udphole

Basic UDP wormhole proxy
git clone git://git.finwo.net/app/udphole
Log | Files | Refs | README | LICENSE

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