source: libcfa/src/concurrency/cofor.hfa@ c649d2c

Last change on this file since c649d2c was ba0e1bc, checked in by caparson <caparson@…>, 23 months ago

Added supporting library routines for cofor impl

  • Property mode set to 100644
File size: 2.3 KB
Line 
1#include <thread.hfa>
2#include <locks.hfa>
3#include <list.hfa>
4
5//////////////////////////////////////////////////////////////////////////////////////////
6// cofor ( uC++ COFOR )
7typedef void (*__cofor_body_t)( ssize_t );
8
9void __Cofor__( ssize_t low, ssize_t high, __cofor_body_t loop_body );
10
11#define COFOR( lidname, low, high, loopbody ) \
12 { \
13 void __CFA_loopLambda__( ssize_t lidname ) { \
14 loopbody \
15 } \
16 __Cofor__( low, high, __CFA_loopLambda__ ); \
17 }
18
19struct runner_node {
20 void * value;
21 inline dlink(runner_node);
22};
23P9_EMBEDDED( runner_node, dlink(runner_node) )
24
25thread cofor_runner {
26 go_mutex mutex_lock; // MX lock
27 dlist( runner_node ) items;
28 void (*func)(void *);
29 volatile bool done;
30};
31
32void ?{}( cofor_runner & this ) { this.done = false; }
33
34void main( cofor_runner & this ) with(this) {
35 while ( !done || !items`isEmpty ) {
36 lock( mutex_lock );
37 runner_node * node = &try_pop_front( items );
38 unlock( mutex_lock );
39 func( node->value );
40 free( node->value );
41 free( node );
42 }
43}
44
45void start_runners( cofor_runner * thds, unsigned nprocs, void (*func)(void *) ) {
46 for ( i; nprocs ) {
47 thds[i].func = func;
48 }
49}
50
51void end_runners( cofor_runner * thds, unsigned nprocs ) {
52 for ( i; nprocs ) {
53 thds[i].done = true;
54 }
55}
56
57void send_work( cofor_runner * thds, unsigned nprocs, unsigned & curr_proc, void * value ) {
58 runner_node * node = malloc();
59 (*node){};
60 node->value = value;
61 lock( thds[curr_proc].mutex_lock );
62 insert_last( thds[curr_proc].items, *node );
63 unlock( thds[curr_proc].mutex_lock );
64 curr_proc = ( curr_proc + 1 ) % nprocs;
65}
66
67//////////////////////////////////////////////////////////////////////////////////////////
68// corun
69
70//
71typedef void (*__CFA_corun_lambda_t)( void );
72
73// used to run a corun statement in parallel
74thread co_runner {
75 __CFA_corun_lambda_t body;
76};
77
78// wraps a co_runner to provide RAII deallocation
79struct runner_block {
80 co_runner * runner;
81};
82static inline void ?{}( co_runner & this, __CFA_corun_lambda_t body ) { this.body = body; }
83
84void main( co_runner & this ) with( this ) { body(); }
85
86static inline void ?{}( runner_block & this ) {}
87static inline void ?{}( runner_block & this, __CFA_corun_lambda_t body ) {
88 (*(this.runner = malloc())){ body };
89}
90
91static inline void ^?{}( runner_block & this ) {
92 delete( this.runner );
93}
Note: See TracBrowser for help on using the repository browser.