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

Last change on this file since ba0e1bc was ba0e1bc, checked in by caparson <caparson@…>, 6 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.