protothreads.h (1984B)
1 #ifndef UDPHOLE_PROTOTHREADS_H 2 #define UDPHOLE_PROTOTHREADS_H 3 4 #include <stddef.h> 5 6 #define PT_CONCAT2(s1, s2) s1##s2 7 #define PT_CONCAT(s1, s2) PT_CONCAT2(s1, s2) 8 9 #define PT_RESUME(pt) \ 10 do { \ 11 if ((pt)->lc != NULL) \ 12 goto *(pt)->lc; \ 13 } while (0) 14 15 #define PT_SET(pt) \ 16 do { \ 17 PT_CONCAT(PT_LABEL, __LINE__): \ 18 (pt)->lc = &&PT_CONCAT(PT_LABEL, __LINE__); \ 19 } while (0) 20 21 struct pt { 22 void *lc; 23 }; 24 25 #define PT_WAITING 0 26 #define PT_YIELDED 1 27 #define PT_EXITED 2 28 #define PT_ENDED 3 29 30 #define PT_INIT(pt) ((pt)->lc = NULL) 31 32 #define PT_THREAD(name_args) char name_args 33 34 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; (void)PT_YIELD_FLAG; PT_RESUME((pt)) 35 36 #define PT_END(pt) PT_INIT(pt); PT_YIELD_FLAG = 0; return PT_ENDED; } 37 38 #define PT_WAIT_UNTIL(pt, condition) \ 39 do { \ 40 PT_SET(pt); \ 41 if (!(condition)) \ 42 return PT_WAITING; \ 43 } while (0) 44 45 #define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) 46 47 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) 48 49 #define PT_SPAWN(pt, child, thread) \ 50 do { \ 51 PT_INIT((child)); \ 52 PT_WAIT_THREAD((pt), (thread)); \ 53 } while (0) 54 55 #define PT_RESTART(pt) \ 56 do { \ 57 PT_INIT(pt); \ 58 return PT_WAITING; \ 59 } while (0) 60 61 #define PT_EXIT(pt) \ 62 do { \ 63 PT_INIT(pt); \ 64 return PT_EXITED; \ 65 } while (0) 66 67 #define PT_SCHEDULE(f) ((f) < PT_EXITED) 68 69 #define PT_YIELD(pt) \ 70 do { \ 71 PT_YIELD_FLAG = 0; \ 72 PT_SET(pt); \ 73 if (PT_YIELD_FLAG == 0) \ 74 return PT_YIELDED; \ 75 } while (0) 76 77 #define PT_YIELD_UNTIL(pt, cond) \ 78 do { \ 79 PT_YIELD_FLAG = 0; \ 80 PT_SET(pt); \ 81 if ((PT_YIELD_FLAG == 0) || !(cond)) \ 82 return PT_YIELDED; \ 83 } while (0) 84 85 struct pt_sem { 86 unsigned int count; 87 }; 88 89 #define PT_SEM_INIT(s, c) ((s)->count = (c)) 90 91 #define PT_SEM_WAIT(pt, s) \ 92 do { \ 93 PT_WAIT_UNTIL(pt, (s)->count > 0); \ 94 (s)->count--; \ 95 } while (0) 96 97 #define PT_SEM_SIGNAL(pt, s) ((s)->count++) 98 99 #endif // UDPHOLE_PROTOTHREADS_H