Threads.darwin.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*--------- threads support ------------------------- g.f. -----*/
  2. /*--------- lower half of the Oberon Threads module */
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <limits.h>
  7. #include <signal.h>
  8. #include <semaphore.h>
  9. #include <errno.h>
  10. #include "Threads.h"
  11. extern int suid_root;
  12. extern int debug;
  13. extern void SetSigaltstack();
  14. static o_thr_t mainthread = 0;
  15. void
  16. o_thrSleep(int ms) {
  17. struct timespec sltime, rem;
  18. sltime.tv_sec = ms/1000;
  19. sltime.tv_nsec = 1000000*(ms%1000);
  20. while (nanosleep( &sltime, &rem ) < 0 && errno == EINTR)
  21. sltime = rem;
  22. }
  23. o_mtx_t
  24. o_mtxInit(int dummy) {
  25. o_mtx_t mtx;
  26. mtx = (o_mtx_t)malloc( sizeof(pthread_mutex_t) );
  27. pthread_mutex_init( mtx, NULL );
  28. return mtx;
  29. }
  30. void
  31. o_mtxDestroy(o_mtx_t mtx) {
  32. (void)pthread_mutex_destroy( mtx );
  33. free( mtx );
  34. }
  35. void
  36. o_mtxLock(o_mtx_t mtx) {
  37. (void)pthread_mutex_lock( mtx );
  38. }
  39. void
  40. o_mtxUnlock(o_mtx_t mtx) {
  41. (void)pthread_mutex_unlock( mtx );
  42. }
  43. o_con_t
  44. o_conInit(int dymmy) {
  45. o_con_t c;
  46. c = (o_con_t)malloc( sizeof(pthread_cond_t) );
  47. pthread_cond_init( c, NULL );
  48. return c;
  49. }
  50. void
  51. o_conDestroy(o_con_t c) {
  52. pthread_cond_destroy( c );
  53. free( c );
  54. }
  55. void
  56. o_conWait( o_con_t c, o_mtx_t m ) {
  57. pthread_cond_wait( c, m );
  58. }
  59. void
  60. o_conSignal( o_con_t c ) {
  61. pthread_cond_signal( c );
  62. }
  63. static void *
  64. starter(void *p) {
  65. o_thr_t me = pthread_self();
  66. oberon_proc proc = (oberon_proc)p;
  67. sigset_t old, new;
  68. struct sched_param param;
  69. SetSigaltstack();
  70. sigfillset( &new );
  71. sigdelset( &new, SIGILL );
  72. sigdelset( &new, SIGTRAP );
  73. sigdelset( &new, SIGFPE );
  74. sigdelset( &new, SIGBUS );
  75. sigdelset( &new, SIGSEGV );
  76. sigdelset( &new, SIGTERM );
  77. pthread_sigmask( SIG_SETMASK, &new, &old );
  78. pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
  79. pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
  80. param.sched_priority = 0;
  81. pthread_setschedparam( me, SCHED_OTHER, &param );
  82. proc();
  83. pthread_exit( NULL );
  84. return NULL;
  85. }
  86. o_thr_t
  87. o_thrStart( oberon_proc p, int len ) {
  88. o_thr_t id;
  89. pthread_attr_t attr;
  90. if (len < PTHREAD_STACK_MIN) len = PTHREAD_STACK_MIN;
  91. pthread_attr_init( &attr );
  92. pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
  93. pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
  94. pthread_attr_setstacksize( &attr, len );
  95. if (pthread_create( &id, &attr, starter, p ) != 0) return 0;
  96. return id;
  97. }
  98. o_thr_t
  99. o_thrThis(int dummy) {
  100. return pthread_self();
  101. }
  102. void
  103. o_thrYield(int dummy) {
  104. o_thrSleep( 1 );
  105. }
  106. void
  107. o_thrExit(int dummy) {
  108. pthread_exit( 0 );
  109. }
  110. void
  111. o_thrSuspend(o_thr_t thr) {
  112. mach_port_t mthread;
  113. mthread = pthread_mach_thread_np(thr);
  114. thread_suspend(mthread);
  115. }
  116. void
  117. o_thrResume(o_thr_t thr) {
  118. mach_port_t mthread;
  119. mthread = pthread_mach_thread_np(thr);
  120. thread_resume(mthread);
  121. }
  122. void
  123. o_thrSetprio(o_thr_t thr, int prio) {
  124. struct sched_param param;
  125. int policy;
  126. pthread_getschedparam( thr, &policy, &param );
  127. param.sched_priority = prio;
  128. if (pthread_setschedparam( thr, SCHED_OTHER, &param ) != 0)
  129. perror("pthread_setschedparam");
  130. }
  131. int
  132. o_thrGetprio(o_thr_t thr) {
  133. struct sched_param param;
  134. int policy;
  135. pthread_getschedparam( thr, &policy, &param );
  136. return ( param.sched_priority );
  137. }
  138. void
  139. o_thrKill(o_thr_t thr, int sig) {
  140. pthread_kill( thr, sig );
  141. /* if (thr != mainthread) {
  142. pthread_detach( thr );
  143. if (thr == pthread_self())
  144. pthread_exit( 0 );
  145. else {
  146. pthread_cancel( thr );
  147. }
  148. } */
  149. }
  150. int
  151. o_thrInitialize( int *low, int* high ) {
  152. struct sched_param param;
  153. mainthread = pthread_self();
  154. *high = sched_get_priority_max(SCHED_OTHER);
  155. *low = sched_get_priority_min(SCHED_OTHER);
  156. param.sched_priority = *high;
  157. pthread_setschedparam( mainthread, SCHED_OTHER, &param );
  158. return 1;
  159. }