home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyth_os2.zip / python-1.0.2 / Python / thread.c < prev    next >
C/C++ Source or Header  |  1994-05-04  |  17KB  |  689 lines

  1. /***********************************************************
  2. Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
  3. Amsterdam, The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI not be used in advertising or publicity pertaining to
  13. distribution of the software without specific, written prior permission.
  14.  
  15. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  18. FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  21. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. #ifdef HAVE_CONFIG_H
  26. #include "config.h"
  27. #endif
  28.  
  29. #ifdef WITH_SGI_DL
  30. #define USE_DL
  31. #endif
  32.  
  33. #ifdef HAVE_THREAD_H
  34. #define SOLARIS
  35. #endif
  36.  
  37. #include "thread.h"
  38.  
  39. #ifdef DEBUG
  40. static int thread_debug = 0;
  41. #define dprintf(args)    ((thread_debug & 1) && printf args)
  42. #define d2printf(args)    ((thread_debug & 8) && printf args)
  43. #else
  44. #define dprintf(args)
  45. #define d2printf(args)
  46. #endif
  47.  
  48. #ifdef __sgi
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51. #include <signal.h>
  52. #include <sys/types.h>
  53. #include <sys/wait.h>
  54. #include <sys/prctl.h>
  55. #include <ulocks.h>
  56. #include <errno.h>
  57.  
  58. #define HDR_SIZE    2680    /* sizeof(ushdr_t) */
  59. #define MAXPROC        100    /* max # of threads that can be started */
  60.  
  61. static usptr_t *shared_arena;
  62. static ulock_t count_lock;    /* protection for some variables */
  63. static ulock_t wait_lock;    /* lock used to wait for other threads */
  64. static int waiting_for_threads;    /* protected by count_lock */
  65. static int nthreads;        /* protected by count_lock */
  66. static int exit_status;
  67. #ifndef NO_EXIT_PROG
  68. static int do_exit;        /* indicates that the program is to exit */
  69. #endif
  70. static int exiting;        /* we're already exiting (for maybe_exit) */
  71. static pid_t my_pid;        /* PID of main thread */
  72. static pid_t pidlist[MAXPROC];    /* PIDs of other threads */
  73. static int maxpidindex;        /* # of PIDs in pidlist */
  74. #endif /* __sgi */
  75. #ifdef SOLARIS
  76. #include <stdlib.h>
  77. #include <stdio.h>
  78. #include <unistd.h>
  79. #include </usr/include/thread.h>
  80. #undef sun
  81. #endif
  82. #ifdef sun
  83. #include <stdlib.h>
  84. #include <lwp/lwp.h>
  85. #include <lwp/stackdep.h>
  86.  
  87. #define STACKSIZE    1000    /* stacksize for a thread */
  88. #define NSTACKS        2    /* # stacks to be put in cache initialy */
  89.  
  90. struct lock {
  91.     int lock_locked;
  92.     cv_t lock_condvar;
  93.     mon_t lock_monitor;
  94. };
  95. #endif /* sun */
  96. #ifdef C_THREADS
  97. #include <cthreads.h>
  98. #endif /* C_THREADS */
  99. #ifdef _POSIX_THREADS
  100. #include <pthread.h>
  101. #endif /* _POSIX_THREADS */
  102.  
  103. #ifdef __STDC__
  104. #define _P(args)        args
  105. #define _P0()            (void)
  106. #define _P1(v,t)        (t)
  107. #define _P2(v1,t1,v2,t2)    (t1,t2)
  108. #else
  109. #define _P(args)        ()
  110. #define _P0()            ()
  111. #define _P1(v,t)        (v) t;
  112. #define _P2(v1,t1,v2,t2)    (v1,v2) t1; t2;
  113. #endif /* __STDC__ */
  114.  
  115. static int initialized;
  116.  
  117. #ifdef __sgi
  118. #ifndef NO_EXIT_PROG
  119. /*
  120.  * This routine is called as a signal handler when another thread
  121.  * exits.  When that happens, we must see whether we have to exit as
  122.  * well (because of an exit_prog()) or whether we should continue on.
  123.  */
  124. static void exit_sig _P0()
  125. {
  126.     d2printf(("exit_sig called\n"));
  127.     if (exiting && getpid() == my_pid) {
  128.         d2printf(("already exiting\n"));
  129.         return;
  130.     }
  131.     if (do_exit) {
  132.         d2printf(("exiting in exit_sig\n"));
  133. #ifdef DEBUG
  134.         if ((thread_debug & 8) == 0)
  135.             thread_debug &= ~1; /* don't produce debug messages */
  136. #endif
  137.         exit_thread();
  138.     }
  139. }
  140.  
  141. /*
  142.  * This routine is called when a process calls exit().  If that wasn't
  143.  * done from the library, we do as if an exit_prog() was intended.
  144.  */
  145. static void maybe_exit _P0()
  146. {
  147.     dprintf(("maybe_exit called\n"));
  148.     if (exiting) {
  149.         dprintf(("already exiting\n"));
  150.         return;
  151.     }
  152.     exit_prog(0);
  153. }
  154. #endif /* NO_EXIT_PROG */
  155. #endif /* __sgi */
  156.  
  157. /*
  158.  * Initialization.
  159.  */
  160. void init_thread _P0()
  161. {
  162. #ifdef __sgi
  163. #ifndef NO_EXIT_PROG
  164.     struct sigaction s;
  165. #endif /* NO_EXIT_PROG */
  166. #ifdef USE_DL
  167.     long addr, size;
  168. #endif /* USE_DL */
  169. #endif /* __sgi */
  170.  
  171. #ifdef DEBUG
  172.     char *p = getenv("THREADDEBUG");
  173.  
  174.     if (p) {
  175.         if (*p)
  176.             thread_debug = atoi(p);
  177.         else
  178.             thread_debug = 1;
  179.     }
  180. #endif /* DEBUG */
  181.     if (initialized)
  182.         return;
  183.     initialized = 1;
  184.     dprintf(("init_thread called\n"));
  185.  
  186. #ifdef __sgi
  187. #ifdef USE_DL
  188.     if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
  189.         perror("usconfig - CONF_INITSIZE (check)");
  190.     if (usconfig(CONF_INITSIZE, size) < 0)
  191.         perror("usconfig - CONF_INITSIZE (reset)");
  192.     addr = (long) dl_getrange(size + HDR_SIZE);
  193.     dprintf(("trying to use addr %lx-%lx for shared arena\n", addr, addr+size));
  194.     errno = 0;
  195.     if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
  196.         perror("usconfig - CONF_ATTACHADDR (set)");
  197. #endif /* USE_DL */
  198.     if (usconfig(CONF_INITUSERS, 16) < 0)
  199.         perror("usconfig - CONF_INITUSERS");
  200.     my_pid = getpid();    /* so that we know which is the main thread */
  201. #ifndef NO_EXIT_PROG
  202.     atexit(maybe_exit);
  203.     s.sa_handler = exit_sig;
  204.     sigemptyset(&s.sa_mask);
  205.     /*sigaddset(&s.sa_mask, SIGUSR1);*/
  206.     s.sa_flags = 0;
  207.     sigaction(SIGUSR1, &s, 0);
  208.     if (prctl(PR_SETEXITSIG, SIGUSR1) < 0)
  209.         perror("prctl - PR_SETEXITSIG");
  210. #endif /* NO_EXIT_PROG */
  211.     if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0)
  212.         perror("usconfig - CONF_ARENATYPE");
  213.     usconfig(CONF_LOCKTYPE, US_DEBUG); /* XXX */
  214. #ifdef DEBUG
  215.     if (thread_debug & 4)
  216.         usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
  217.     else if (thread_debug & 2)
  218.         usconfig(CONF_LOCKTYPE, US_DEBUG);
  219. #endif /* DEBUG */
  220.     if ((shared_arena = usinit(tmpnam(0))) == 0)
  221.         perror("usinit");
  222. #ifdef USE_DL
  223.     if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
  224.         perror("usconfig - CONF_ATTACHADDR (reset)");
  225. #endif /* USE_DL */
  226.     if ((count_lock = usnewlock(shared_arena)) == NULL)
  227.         perror("usnewlock (count_lock)");
  228.     (void) usinitlock(count_lock);
  229.     if ((wait_lock = usnewlock(shared_arena)) == NULL)
  230.         perror("usnewlock (wait_lock)");
  231.     dprintf(("arena start: %lx, arena size: %ld\n", (long) shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
  232. #endif /* __sgi */
  233. #ifdef SOLARIS
  234.     /* nothing */
  235. #endif
  236. #ifdef sun
  237.     lwp_setstkcache(STACKSIZE, NSTACKS);
  238. #endif /* sun */
  239. #ifdef C_THREADS
  240.     cthread_init();
  241. #endif /* C_THREADS */
  242. }
  243.  
  244. /*
  245.  * Thread support.
  246.  */
  247. #ifdef SOLARIS
  248. struct func_arg {
  249.     void (*func) _P((void *));
  250.     void *arg;
  251. };
  252.  
  253. static void *new_func _P1(funcarg, void *funcarg)
  254. {
  255.     void (*func) _P((void *));
  256.     void *arg;
  257.  
  258.     func = ((struct func_arg *) funcarg)->func;
  259.     arg = ((struct func_arg *) funcarg)->arg;
  260.     free(funcarg);
  261.     (*func)(arg);
  262.     return 0;
  263. }
  264. #endif /* SOLARIS */
  265.  
  266. #ifdef __sgi
  267. static void clean_threads _P0()
  268. {
  269.     int i;
  270.     pid_t pid;
  271.  
  272.     /* clean up any exited threads */
  273.     i = 0;
  274.     while (i < maxpidindex) {
  275.         if ((pid = pidlist[i]) > 0) {
  276.             pid = waitpid(pid, 0, WNOHANG);
  277.             if (pid < 0)
  278.                 return;
  279.             if (pid != 0) {
  280.                 /* a thread has exited */
  281.                 pidlist[i] = pidlist[--maxpidindex];
  282.                 continue; /* don't increment i */
  283.             }
  284.         }
  285.         i++;
  286.     }
  287. }
  288. #endif /* __sgi */
  289.  
  290. int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
  291. {
  292. #ifdef SOLARIS
  293.     struct func_arg *funcarg;
  294. #endif
  295. #ifdef sun
  296.     thread_t tid;
  297. #endif /* sun */
  298. #if defined(__sgi) && defined(USE_DL)
  299.     long addr, size;
  300.     static int local_initialized = 0;
  301. #endif /* __sgi and USE_DL */
  302. #ifdef _POSIX_THREADS
  303.     pthread_t th;
  304. #endif
  305.     int success = 0;    /* init not needed when SOLARIS and */
  306.                 /* C_THREADS implemented properly */
  307.  
  308.     dprintf(("start_new_thread called\n"));
  309.     if (!initialized)
  310.         init_thread();
  311. #ifdef __sgi
  312.     switch (ussetlock(count_lock)) {
  313.     case 0: return 0;
  314.     case -1: perror("ussetlock (count_lock)");
  315.     }
  316.     if (maxpidindex >= MAXPROC)
  317.         success = -1;
  318.     else {
  319. #ifdef USE_DL
  320.         if (!local_initialized) {
  321.             if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
  322.                 perror("usconfig - CONF_INITSIZE (check)");
  323.             if (usconfig(CONF_INITSIZE, size) < 0)
  324.                 perror("usconfig - CONF_INITSIZE (reset)");
  325.             addr = (long) dl_getrange(size + HDR_SIZE);
  326.             dprintf(("trying to use addr %lx-%lx for sproc\n", addr, addr+size));
  327.             errno = 0;
  328.             if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
  329.                 perror("usconfig - CONF_ATTACHADDR (set)");
  330.         }
  331. #endif /* USE_DL */
  332.         clean_threads();
  333.         if ((success = sproc(func, PR_SALL, arg)) < 0)
  334.             perror("sproc");
  335. #ifdef USE_DL
  336.         if (!local_initialized) {
  337.             if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
  338.                 perror("usconfig - CONF_ATTACHADDR (reset)");
  339.             local_initialized = 1;
  340.         }
  341. #endif /* USE_DL */
  342.         if (success >= 0) {
  343.             nthreads++;
  344.             pidlist[maxpidindex++] = success;
  345.             dprintf(("pidlist[%d] = %d\n", maxpidindex-1, success));
  346.         }
  347.     }
  348.     if (usunsetlock(count_lock) < 0)
  349.         perror("usunsetlock (count_lock)");
  350. #endif /* __sgi */
  351. #ifdef SOLARIS
  352.     funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
  353.     funcarg->func = func;
  354.     funcarg->arg = arg;
  355.     if (thr_create(0, 0, new_func, funcarg, THR_NEW_LWP, 0)) {
  356.         perror("thr_create");
  357.         free((void *) funcarg);
  358.         success = -1;
  359.     }
  360. #endif /* SOLARIS */
  361. #ifdef sun
  362.     success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
  363. #endif /* sun */
  364. #ifdef C_THREADS
  365.     (void) cthread_fork(func, arg);
  366. #endif /* C_THREADS */
  367. #ifdef _POSIX_THREADS
  368.     pthread_create(&th, NULL, func, arg);
  369. #endif
  370.     return success < 0 ? 0 : 1;
  371. }
  372.  
  373. static void do_exit_thread _P1(no_cleanup, int no_cleanup)
  374. {
  375.     dprintf(("exit_thread called\n"));
  376.     if (!initialized)
  377.         if (no_cleanup)
  378.             _exit(0);
  379.         else
  380.             exit(0);
  381. #ifdef __sgi
  382.     if (ussetlock(count_lock) < 0)
  383.         perror("ussetlock (count_lock)");
  384.     nthreads--;
  385.     if (getpid() == my_pid) {
  386.         /* main thread; wait for other threads to exit */
  387.         exiting = 1;
  388. #ifndef NO_EXIT_PROG
  389.         if (do_exit) {
  390.             int i;
  391.  
  392.             /* notify other threads */
  393.             clean_threads();
  394.             if (nthreads >= 0) {
  395.                 dprintf(("kill other threads\n"));
  396.                 for (i = 0; i < maxpidindex; i++)
  397.                     if (pidlist[i] > 0)
  398.                         (void) kill(pidlist[i],
  399.                                 SIGKILL);
  400.                 _exit(exit_status);
  401.             }
  402.         }
  403. #endif /* NO_EXIT_PROG */
  404.         waiting_for_threads = 1;
  405.         if (ussetlock(wait_lock) < 0)
  406.             perror("ussetlock (wait_lock)");
  407.         for (;;) {
  408.             if (nthreads < 0) {
  409.                 dprintf(("really exit (%d)\n", exit_status));
  410.                 if (no_cleanup)
  411.                     _exit(exit_status);
  412.                 else
  413.                     exit(exit_status);
  414.             }
  415.             if (usunsetlock(count_lock) < 0)
  416.                 perror("usunsetlock (count_lock)");
  417.             dprintf(("waiting for other threads (%d)\n", nthreads));
  418.             if (ussetlock(wait_lock) < 0)
  419.                 perror("ussetlock (wait_lock)");
  420.             if (ussetlock(count_lock) < 0)
  421.                 perror("ussetlock (count_lock)");
  422.         }
  423.     }
  424.     /* not the main thread */
  425.     if (waiting_for_threads) {
  426.         dprintf(("main thread is waiting\n"));
  427.         if (usunsetlock(wait_lock) < 0)
  428.             perror("usunsetlock (wait_lock)");
  429.     }
  430. #ifndef NO_EXIT_PROG
  431.     else if (do_exit)
  432.         (void) kill(my_pid, SIGUSR1);
  433. #endif /* NO_EXIT_PROG */
  434.     if (usunsetlock(count_lock) < 0)
  435.         perror("usunsetlock (count_lock)");
  436.     _exit(0);
  437. #endif /* __sgi */
  438. #ifdef SOLARIS
  439.     thr_exit(0);
  440. #endif /* SOLARIS */
  441. #ifdef sun
  442.     lwp_destroy(SELF);
  443. #endif /* sun */
  444. #ifdef C_THREADS
  445.     cthread_exit(0);
  446. #endif /* C_THREADS */
  447. }
  448.  
  449. void exit_thread _P0()
  450. {
  451.     do_exit_thread(0);
  452. }
  453.  
  454. void _exit_thread _P0()
  455. {
  456.     do_exit_thread(1);
  457. }
  458.  
  459. #ifndef NO_EXIT_PROG
  460. static void do_exit_prog _P2(status, int status, no_cleanup, int no_cleanup)
  461. {
  462.     dprintf(("exit_prog(%d) called\n", status));
  463.     if (!initialized)
  464.         if (no_cleanup)
  465.             _exit(status);
  466.         else
  467.             exit(status);
  468. #ifdef __sgi
  469.     do_exit = 1;
  470.     exit_status = status;
  471.     do_exit_thread(no_cleanup);
  472. #endif /* __sgi */
  473. #ifdef SOLARIS
  474.     if (no_cleanup)
  475.         _exit(status);
  476.     else
  477.         exit(status);
  478. #endif /* SOLARIS */
  479. #ifdef sun
  480.     pod_exit(status);
  481. #endif /* sun */
  482. }
  483.  
  484. void exit_prog _P1(status, int status)
  485. {
  486.     do_exit_prog(status, 0);
  487. }
  488.  
  489. void _exit_prog _P1(status, int status)
  490. {
  491.     do_exit_prog(status, 1);
  492. }
  493. #endif /* NO_EXIT_PROG */
  494.  
  495. /*
  496.  * Lock support.
  497.  */
  498. type_lock allocate_lock _P0()
  499. {
  500. #ifdef __sgi
  501.     ulock_t lock;
  502. #endif
  503. #ifdef SOLARIS
  504.     mutex_t *lock;
  505. #endif
  506. #ifdef sun
  507.     struct lock *lock;
  508.     extern char *malloc();
  509. #endif
  510.  
  511.     dprintf(("allocate_lock called\n"));
  512.     if (!initialized)
  513.         init_thread();
  514.  
  515. #ifdef __sgi
  516.     if ((lock = usnewlock(shared_arena)) == NULL)
  517.         perror("usnewlock");
  518.     (void) usinitlock(lock);
  519. #endif /* __sgi */
  520. #ifdef SOLARIS
  521.     lock = (mutex_t *) malloc(sizeof(mutex_t));
  522.     if (mutex_init(lock, USYNC_THREAD, 0)) {
  523.         perror("mutex_init");
  524.         free((void *) lock);
  525.         lock = 0;
  526.     }
  527. #endif /* SOLARIS */
  528. #ifdef sun
  529.     lock = (struct lock *) malloc(sizeof(struct lock));
  530.     lock->lock_locked = 0;
  531.     (void) mon_create(&lock->lock_monitor);
  532.     (void) cv_create(&lock->lock_condvar, lock->lock_monitor);
  533. #endif /* sun */
  534.     dprintf(("allocate_lock() -> %lx\n", (long)lock));
  535.     return (type_lock) lock;
  536. }
  537.  
  538. void free_lock _P1(lock, type_lock lock)
  539. {
  540.     dprintf(("free_lock(%lx) called\n", (long)lock));
  541. #ifdef __sgi
  542.     usfreelock((ulock_t) lock, shared_arena);
  543. #endif /* __sgi */
  544. #ifdef SOLARIS
  545.     mutex_destroy((mutex_t *) lock);
  546.     free((void *) lock);
  547. #endif
  548. #ifdef sun
  549.     mon_destroy(((struct lock *) lock)->lock_monitor);
  550.     free((char *) lock);
  551. #endif /* sun */
  552. }
  553.  
  554. int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
  555. {
  556.     int success;
  557.  
  558.     dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag));
  559. #ifdef __sgi
  560.     errno = 0;        /* clear it just in case */
  561.     if (waitflag)
  562.         success = ussetlock((ulock_t) lock);
  563.     else
  564.         success = uscsetlock((ulock_t) lock, 1); /* Try it once */
  565.     if (success < 0)
  566.         perror(waitflag ? "ussetlock" : "uscsetlock");
  567. #endif /* __sgi */
  568. #ifdef SOLARIS
  569.     if (waitflag)
  570.         success = mutex_lock((mutex_t *) lock);
  571.     else
  572.         success = mutex_trylock((mutex_t *) lock);
  573.     if (success < 0)
  574.         perror(waitflag ? "mutex_lock" : "mutex_trylock");
  575.     else
  576.         success = !success; /* solaris does it the other way round */
  577. #endif /* SOLARIS */
  578. #ifdef sun
  579.     success = 0;
  580.  
  581.     (void) mon_enter(((struct lock *) lock)->lock_monitor);
  582.     if (waitflag)
  583.         while (((struct lock *) lock)->lock_locked)
  584.             cv_wait(((struct lock *) lock)->lock_condvar);
  585.     if (!((struct lock *) lock)->lock_locked) {
  586.         success = 1;
  587.         ((struct lock *) lock)->lock_locked = 1;
  588.     }
  589.     cv_broadcast(((struct lock *) lock)->lock_condvar);
  590.     mon_exit(((struct lock *) lock)->lock_monitor);
  591. #endif /* sun */
  592.     dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success));
  593.     return success;
  594. }
  595.  
  596. void release_lock _P1(lock, type_lock lock)
  597. {
  598.     dprintf(("release_lock(%lx) called\n", (long)lock));
  599. #ifdef __sgi
  600.     if (usunsetlock((ulock_t) lock) < 0)
  601.         perror("usunsetlock");
  602. #endif /* __sgi */
  603. #ifdef SOLARIS
  604.     if (mutex_unlock((mutex_t *) lock))
  605.         perror("mutex_unlock");
  606. #endif /* SOLARIS */
  607. #ifdef sun
  608.     (void) mon_enter(((struct lock *) lock)->lock_monitor);
  609.     ((struct lock *) lock)->lock_locked = 0;
  610.     cv_broadcast(((struct lock *) lock)->lock_condvar);
  611.     mon_exit(((struct lock *) lock)->lock_monitor);
  612. #endif /* sun */
  613. }
  614.  
  615. /*
  616.  * Semaphore support.
  617.  */
  618. type_sema allocate_sema _P1(value, int value)
  619. {
  620. #ifdef __sgi
  621.     usema_t *sema;
  622. #endif /* __sgi */
  623. #ifdef SOLARIS
  624.     sema_t *sema;
  625. #endif
  626. #ifdef sun
  627.     type_sema sema = 0;
  628. #endif
  629.  
  630.     dprintf(("allocate_sema called\n"));
  631.     if (!initialized)
  632.         init_thread();
  633.  
  634. #ifdef __sgi
  635.     if ((sema = usnewsema(shared_arena, value)) == NULL)
  636.         perror("usnewsema");
  637. #endif /* __sgi */
  638. #ifdef SOLARIS
  639.     sema = (sema_t *) malloc(sizeof(sema_t));
  640.     if (sema_init(sema, value, USYNC_THREAD, 0)) {
  641.         perror("sema_init");
  642.         free((void *) sema);
  643.         sema = 0;
  644.     }
  645. #endif /* SOLARIS */
  646.     dprintf(("allocate_sema() -> %lx\n", (long) sema));
  647.     return (type_sema) sema;
  648. }
  649.  
  650. void free_sema _P1(sema, type_sema sema)
  651. {
  652.     dprintf(("free_sema(%lx) called\n", (long) sema));
  653. #ifdef __sgi
  654.     usfreesema((usema_t *) sema, shared_arena);
  655. #endif /* __sgi */
  656. #ifdef SOLARIS
  657.     if (sema_destroy((sema_t *) sema))
  658.         perror("sema_destroy");
  659.     free((void *) sema);
  660. #endif /* SOLARIS */
  661. }
  662.  
  663. void down_sema _P1(sema, type_sema sema)
  664. {
  665.     dprintf(("down_sema(%lx) called\n", (long) sema));
  666. #ifdef __sgi
  667.     if (uspsema((usema_t *) sema) < 0)
  668.         perror("uspsema");
  669. #endif
  670. #ifdef SOLARIS
  671.     if (sema_wait((sema_t *) sema))
  672.         perror("sema_wait");
  673. #endif
  674.     dprintf(("down_sema(%lx) return\n", (long) sema));
  675. }
  676.  
  677. void up_sema _P1(sema, type_sema sema)
  678. {
  679.     dprintf(("up_sema(%lx)\n", (long) sema));
  680. #ifdef __sgi
  681.     if (usvsema((usema_t *) sema) < 0)
  682.         perror("usvsema");
  683. #endif /* __sgi */
  684. #ifdef SOLARIS
  685.     if (sema_post((sema_t *) sema))
  686.         perror("sema_post");
  687. #endif
  688. }
  689.