6.1. Portable Semaphore
Start cpp section to pthread/pthread_semaphore.hpp[1
/1
]
1: #line 1055 "./lpsrc/flx_pthread.pak"
2:
3:
4:
5:
6:
7:
8:
9: namespace flx { namespace pthread {
10:
11:
12:
13:
14: class PTHREAD_EXTERN flx_semaphore_t {
15: sem_t sem;
16: public:
17: flx_semaphore_t(int n=0);
18: ~flx_semaphore_t();
19: void post();
20: void operator++() { post(); }
21: void wait();
22: void operator--() { wait(); }
23: int get();
24: int operator*() { return get(); }
25:
26:
27:
28: int trywait();
29: };
30:
31: }}
32:
33:
Start cpp section to pthread/pthread_semaphore.cpp[1
/1
]
1: #line 1089 "./lpsrc/flx_pthread.pak"
2:
3:
4:
5:
6: namespace flx { namespace pthread {
7: flx_semaphore_t::flx_semaphore_t(int n) { sem_init(&sem, 0, n); }
8: flx_semaphore_t::~flx_semaphore_t() { sem_destroy(&sem); }
9: void flx_semaphore_t::wait() { sem_wait(&sem); }
10: int flx_semaphore_t::trywait() { return sem_trywait(&sem); }
11: void flx_semaphore_t::post() { sem_post(&sem); }
12: int flx_semaphore_t::get(){ int x; sem_getvalue(&sem,&x); return x; }
13:
14: }}
15:
Start cpp section to pthread/pthread_monitor.hpp[1
/1
]
1: #line 1105 "./lpsrc/flx_pthread.pak"
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12: namespace flx { namespace pthread {
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31: class PTHREAD_EXTERN monitor_t {
32: flx_mutex_t m;
33: flx_mutex_t rm;
34: flx_mutex_t wm;
35: int dataput;
36: int datagot;
37: flx_condv_t ack;
38: void *data;
39: public:
40: monitor_t();
41: ~monitor_t();
42: void enqueue(void*);
43: void* dequeue();
44: };
45:
46: }}
47:
48:
Start cpp section to pthread/pthread_monitor.cpp[1
/1
]
1: #line 1154 "./lpsrc/flx_pthread.pak"
2:
3:
4:
5:
6:
7: using namespace std;
8:
9: namespace flx { namespace pthread {
10:
11: monitor_t::monitor_t() : dataput(0),datagot(0) {}
12: monitor_t::~monitor_t() { }
13: inline static void handshake_pos(int &a, flx_condv_t &c, flx_mutex_t &m)
14: {
15: ++a;
16: if(a != 0) do { c.wait(&m); } while (a != 0);
17: else c.signal();
18: assert(a == 0);
19:
20: }
21:
22: inline static void handshake_neg(int &a, flx_condv_t &c, flx_mutex_t &m)
23: {
24: --a;
25: if(a != 0) do { c.wait(&m); } while (a != 0);
26: else c.signal();
27: assert(a == 0);
28:
29: }
30:
31: void
32: monitor_t::enqueue(void* elt)
33: {
34: flx_mutex_locker_t wl(wm);
35: flx_mutex_locker_t l(m);
36: data = elt;
37: handshake_pos(dataput, ack, m);
38: handshake_pos(datagot, ack, m);
39: }
40:
41: void*
42: monitor_t::dequeue()
43: {
44: flx_mutex_locker_t rl(rm);
45: flx_mutex_locker_t l(m);
46: handshake_neg(dataput, ack, m);
47: void *d = data;
48: handshake_neg(datagot, ack, m);
49: return d;
50: }
51:
52: }}
53: