forked from rmbianchi/concurrent_framework
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Algo.h
98 lines (85 loc) · 2.8 KB
/
Algo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
* Algo.h
*
* Created on: Mar 8, 2012
* Authors: [email protected] (Riccardo-Maria BIANCHI)
* [email protected] (Benedikt HEGNER)
*/
#ifndef ALGO_H_
#define ALGO_H_
// include c++
# include <iostream>
# include <cstdio>
// include internals
#include "Whiteboard.h"
#include "tbb/queuing_mutex.h"
enum AlgoState {NOT_RUN, SCHEDULED, ACCEPT, REJECT};
/**
* Algorithm virtual base class
*/
class AlgoBase {
public:
virtual ~AlgoBase(){};
virtual bool body(Context* context) = 0;
virtual const std::vector<std::string> get_inputs() const = 0;
virtual const std::vector<std::string> get_outputs() const = 0;
virtual const char* get_name() const = 0;
virtual void produces(const std::string&) = 0;
virtual void reads(const std::string&) = 0;
};
/**
* Toy algorithm class
*/
class ToyAlgo : public AlgoBase {
public:
ToyAlgo(const char* name, int value, unsigned int time) : name_(name), inputs_(), outputs_(), time_(time), data_(value){};
virtual ~ToyAlgo() {};
// actual implementations of the virtual methods
bool body(Context *context) {
unsigned int event(0);
context->read(event, "event");
//printf("Algo '%s' - begin - EVENT: %i\n", name_, event);
sleep(time_);
read(context);
publish(context);
//printf("Algo '%s' - end - EVENT: %i\n", name_, event);
return true;
};
const std::vector<std::string> get_inputs() const {return inputs_;};
const std::vector<std::string> get_outputs() const {return outputs_;};
const char* get_name() const {return name_;};
void produces(const std::string& out) {outputs_.push_back(out);};
void reads(const std::string& in) {inputs_.push_back(in);};
private:
void publish(Context* context) {
for (t_tags::const_iterator i=outputs_.begin(); i!=outputs_.end(); ++i) context->write(data_, name_, *i);
};
void read(Context* context) {
for (t_tags::const_iterator i=inputs_.begin(); i!=inputs_.end(); ++i) context->read(data_, *i);
};
protected:
typedef std::vector<std::string> t_tags;
const char* name_;
t_tags inputs_;
t_tags outputs_;
const unsigned int time_;
DataItem data_;
};
/**
* non re-entrant toy algorithm class; for now doing non-performant locking
* could try to model it in tbb::flow:graph with a rejecting node
* the serial specifier did not what I naively expected
*/
class NonReentrantToyAlgo : public ToyAlgo{
public:
NonReentrantToyAlgo(const char* name, int value, unsigned int time) : ToyAlgo(name, value, time), counter_(0){};
bool body(Context* context) {
++counter_;
ToyAlgo::body(context);
printf("Algo '%s' unsafe counter: %i\n", name_, counter_);
return true;
};
private:
int counter_;
};
#endif /* ALGO_H_ */