You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
3.4 KiB

  1. #include <stdlib.h>
  2. #include <lwp/lwp.h>
  3. #include <lwp/stackdep.h>
  4. #define STACKSIZE 1000 /* stacksize for a thread */
  5. #define NSTACKS 2 /* # stacks to be put in cache initially */
  6. struct lock {
  7. int lock_locked;
  8. cv_t lock_condvar;
  9. mon_t lock_monitor;
  10. };
  11. /*
  12. * Initialization.
  13. */
  14. static void PyThread__init_thread(void)
  15. {
  16. lwp_setstkcache(STACKSIZE, NSTACKS);
  17. }
  18. /*
  19. * Thread support.
  20. */
  21. long PyThread_start_new_thread(void (*func)(void *), void *arg)
  22. {
  23. thread_t tid;
  24. int success;
  25. dprintf(("PyThread_start_new_thread called\n"));
  26. if (!initialized)
  27. PyThread_init_thread();
  28. success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
  29. return success < 0 ? -1 : 0;
  30. }
  31. long PyThread_get_thread_ident(void)
  32. {
  33. thread_t tid;
  34. if (!initialized)
  35. PyThread_init_thread();
  36. if (lwp_self(&tid) < 0)
  37. return -1;
  38. return tid.thread_id;
  39. }
  40. static void do_PyThread_exit_thread(int no_cleanup)
  41. {
  42. dprintf(("PyThread_exit_thread called\n"));
  43. if (!initialized)
  44. if (no_cleanup)
  45. _exit(0);
  46. else
  47. exit(0);
  48. lwp_destroy(SELF);
  49. }
  50. void PyThread_exit_thread(void)
  51. {
  52. do_PyThread_exit_thread(0);
  53. }
  54. void PyThread__exit_thread(void)
  55. {
  56. do_PyThread_exit_thread(1);
  57. }
  58. #ifndef NO_EXIT_PROG
  59. static void do_PyThread_exit_prog(int status, int no_cleanup)
  60. {
  61. dprintf(("PyThread_exit_prog(%d) called\n", status));
  62. if (!initialized)
  63. if (no_cleanup)
  64. _exit(status);
  65. else
  66. exit(status);
  67. pod_exit(status);
  68. }
  69. void PyThread_exit_prog(int status)
  70. {
  71. do_PyThread_exit_prog(status, 0);
  72. }
  73. void PyThread__exit_prog(int status)
  74. {
  75. do_PyThread_exit_prog(status, 1);
  76. }
  77. #endif /* NO_EXIT_PROG */
  78. /*
  79. * Lock support.
  80. */
  81. PyThread_type_lock PyThread_allocate_lock(void)
  82. {
  83. struct lock *lock;
  84. extern char *malloc(size_t);
  85. dprintf(("PyThread_allocate_lock called\n"));
  86. if (!initialized)
  87. PyThread_init_thread();
  88. lock = (struct lock *) malloc(sizeof(struct lock));
  89. lock->lock_locked = 0;
  90. (void) mon_create(&lock->lock_monitor);
  91. (void) cv_create(&lock->lock_condvar, lock->lock_monitor);
  92. dprintf(("PyThread_allocate_lock() -> %p\n", lock));
  93. return (PyThread_type_lock) lock;
  94. }
  95. void PyThread_free_lock(PyThread_type_lock lock)
  96. {
  97. dprintf(("PyThread_free_lock(%p) called\n", lock));
  98. mon_destroy(((struct lock *) lock)->lock_monitor);
  99. free((char *) lock);
  100. }
  101. int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
  102. {
  103. int success;
  104. dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
  105. success = 0;
  106. (void) mon_enter(((struct lock *) lock)->lock_monitor);
  107. if (waitflag)
  108. while (((struct lock *) lock)->lock_locked)
  109. cv_wait(((struct lock *) lock)->lock_condvar);
  110. if (!((struct lock *) lock)->lock_locked) {
  111. success = 1;
  112. ((struct lock *) lock)->lock_locked = 1;
  113. }
  114. cv_broadcast(((struct lock *) lock)->lock_condvar);
  115. mon_exit(((struct lock *) lock)->lock_monitor);
  116. dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
  117. return success;
  118. }
  119. void PyThread_release_lock(PyThread_type_lock lock)
  120. {
  121. dprintf(("PyThread_release_lock(%p) called\n", lock));
  122. (void) mon_enter(((struct lock *) lock)->lock_monitor);
  123. ((struct lock *) lock)->lock_locked = 0;
  124. cv_broadcast(((struct lock *) lock)->lock_condvar);
  125. mon_exit(((struct lock *) lock)->lock_monitor);
  126. }