home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnuc / library / rcs / ix_sleep.c,v < prev    next >
Encoding:
Text File  |  1992-07-04  |  3.1 KB  |  163 lines

  1. head    1.2;
  2. access;
  3. symbols
  4.     version39-41:1.2;
  5. locks;
  6. comment    @ *  @;
  7.  
  8.  
  9. 1.2
  10. date    92.07.04.19.17.31;    author mwild;    state Exp;
  11. branches;
  12. next    1.1;
  13.  
  14. 1.1
  15. date    92.05.14.19.55.40;    author mwild;    state Exp;
  16. branches;
  17. next    ;
  18.  
  19.  
  20. desc
  21. @**IX like process synchronisation based on events
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @store a textual wait-message ala BSD4.4 for use in ps/dump.
  28. Make sure to check for SIGINT after returning from Wait
  29. @
  30. text
  31. @#define KERNEL
  32. #include "ixemul.h"
  33.  
  34. /* #undef DEBUG */
  35. #ifdef DEBUG
  36. #define DP(a) kprintf a
  37. #else
  38. #define DP(a)
  39. #endif
  40.  
  41. extern struct ixemul_base *ixemulbase;
  42.  
  43. /* this is the `message' we queue on the sleep queues. */
  44. struct sleep_msg {
  45.   struct MinNode     sm_node;
  46.   short            sm_signal;
  47.   struct Task*        sm_sigtask;
  48.   u_int            sm_waitchan;
  49. };
  50.  
  51.  
  52. static inline u_short
  53. ix_hash (u_int waitchan)
  54. {
  55.   unsigned short res;
  56.  
  57.   res = (waitchan >> 16) ^ (waitchan & 0xffff);
  58.   res %= IX_NUM_SLEEP_QUEUES;
  59.   return res; 
  60. }
  61.  
  62. int
  63. ix_sleep (u_int waitchan, char *wmesg)
  64. {
  65.   /* we run in the context of the calling task, we generate a sleep msg and
  66.    * add it to the right sleep queue. wakeup() will do the rest.
  67.    */
  68.   struct sleep_msg sm;
  69.   struct MinList *the_list;
  70.   u_int wait_sigs;
  71.   int res = -1;
  72.  
  73. #ifdef DEBUG
  74.   if (u.p_stat == SSLEEP)
  75.     {
  76.       DP(("PANIC!! sleep recursion!\n"));
  77.       while (1) ;
  78.     }
  79. #endif
  80.  
  81.   if (CURSIG (& u))
  82.     {
  83.       errno = EINTR;
  84.       return -1;
  85.     }
  86.  
  87.   sm.sm_sigtask = FindTask (0);
  88.   sm.sm_waitchan = waitchan;
  89.  
  90.   u.p_stat = SSLEEP;    /* so that machdep.c can interrupt us */
  91.   u.p_wchan = (caddr_t) waitchan;
  92.   u.p_wmesg = wmesg;
  93.   the_list = & ixemulbase->ix_sleep_queues [ix_hash (waitchan)];
  94.   
  95.   sm.sm_signal = u.u_sleep_sig;
  96.  
  97.   wait_sigs =  (1<< sm.sm_signal) | SIGBREAKF_CTRL_C;
  98.  
  99.   Disable ();
  100.   AddTail ((struct List *) the_list, (struct Node *) &sm);
  101.  
  102. DP(("ix_sleep: $%lx ", waitchan));
  103.   /* this will break the Disable () and reestablish it afterwards */
  104.   res = Wait (wait_sigs);
  105.   /* this conversion is inhibited in the Launch handler as long as we're
  106.      in SSLEEP state. Since the SetSignal() below will remove all traces
  107.      of a perhaps present SIGBREAKF_CTRL_C, we'll have to do the conversion
  108.      here ourselves */
  109.   if (((u.p_sigignore & sigmask(SIGMSG)) || !(u.p_sigcatch & sigmask(SIGMSG)))
  110.       && (res & SIGBREAKF_CTRL_C))
  111.     _psignal (FindTask (0), SIGINT);
  112.   SetSignal (0, res);
  113.   res = CURSIG (&u) ? -1 : 0;
  114. DP(("ix_sleep: back.\n"));
  115.  
  116.   Remove ((struct Node *) &sm);
  117.   Enable ();
  118.  
  119. ret:
  120.   u.p_wchan = 0;
  121.   u.p_wmesg = 0;
  122.   u.p_stat = SRUN;
  123.   errno = res == 0 ? 0 : EINTR;
  124.   return res;
  125. }
  126.  
  127. /*
  128.  * ix_wakeup() can be called from an interrupt (and is called that way;-))
  129.  */
  130.  
  131. void
  132. ix_wakeup (u_int waitchan)
  133. {
  134.   struct MinList *the_list = & ixemulbase->ix_sleep_queues[ix_hash (waitchan)];
  135.   struct sleep_msg *sm, *nsm;
  136.   
  137.   Disable ();
  138.  
  139.   for (sm  = (struct sleep_msg *)the_list->mlh_Head;
  140.        nsm = (struct sleep_msg *)sm->sm_node.mln_Succ;
  141.        sm  = nsm)
  142.     if (sm->sm_waitchan == waitchan)
  143.       Signal (sm->sm_sigtask, 1 << sm->sm_signal);
  144.  
  145.   Enable ();
  146. }
  147.  
  148. @
  149.  
  150.  
  151. 1.1
  152. log
  153. @Initial revision
  154. @
  155. text
  156. @d33 1
  157. a33 1
  158. ix_sleep (u_int waitchan)
  159. d62 1
  160. d75 7
  161. d91 1
  162. @
  163.