thread.monkey2 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. Namespace std.thread
  2. #If __THREADS__
  3. #Import "<std>"
  4. #Import "native/bbthread.cpp"
  5. #Import "native/bbthread.h"
  6. Using std..
  7. Extern Private
  8. Struct bbThread="bbThread"
  9. Global current_id:Int
  10. Field running:Bool
  11. Method start:Int( entry:Void() )
  12. Method detach()
  13. Method join()
  14. End
  15. Struct bbMutex="bbMutex"
  16. Method try_lock:Bool()
  17. Method lock()
  18. Method unlock()
  19. End
  20. Struct bbCondvar="bbCondvar" 'condition_variable_any"
  21. Method wait( mutex:bbMutex )
  22. Method notify_one()
  23. Method notify_all()
  24. End
  25. Public
  26. Class Thread
  27. Method New( entry:Void() )
  28. FlushZombies()
  29. _entry=entry
  30. _id=_thread.start( Lambda()
  31. _mutex.lock()
  32. _threads[bbThread.current_id]=Self
  33. _mutex.unlock()
  34. _entry()
  35. End )
  36. End
  37. Property Id:Int()
  38. Return _id
  39. End
  40. Property Running:Bool()
  41. Return _thread.running
  42. End
  43. Method Detach()
  44. If Not _id Return
  45. _mutex.lock()
  46. _zombies.Add( Self )
  47. _threads.Remove( _id )
  48. _mutex.unlock()
  49. _thread.detach()
  50. _id=0
  51. End
  52. Method Join()
  53. If Not _id Return
  54. _thread.join()
  55. _mutex.lock()
  56. _threads.Remove( _id )
  57. _mutex.unlock()
  58. _id=0
  59. End
  60. Function Current:Thread()
  61. _mutex.lock()
  62. Local thread:=_threads[bbThread.current_id]
  63. _mutex.unlock()
  64. Return thread
  65. End
  66. Function CurrentId:Int()
  67. Return bbThread.current_id
  68. End
  69. Function Main:Thread()
  70. _mutex.lock()
  71. If Not _threads.Contains( 1 ) _threads[1]=New Thread( 1 )
  72. Local thread:=_threads[1]
  73. _mutex.unlock()
  74. Return thread
  75. End
  76. Private
  77. Global _mutex:bbMutex
  78. Global _zombies:=New Stack<Thread>
  79. Global _threads:=New IntMap<Thread>
  80. Field _thread:bbThread
  81. Field _entry:Void()
  82. Field _id:Int
  83. Method New( id:Int )
  84. _id=id
  85. End
  86. Function FlushZombies()
  87. If _zombies.Empty Return
  88. _mutex.lock()
  89. Local put:=0
  90. For Local thread:=Eachin _zombies
  91. If Not thread.Running Continue
  92. _zombies[put]=thread
  93. put+=1
  94. Next
  95. _zombies.Resize( put )
  96. _mutex.unlock()
  97. End
  98. End
  99. Class Mutex
  100. Method TryLock:Bool()
  101. Return _mutex.try_lock()
  102. End
  103. Method Lock()
  104. _mutex.lock()
  105. End
  106. Method Unlock()
  107. _mutex.unlock()
  108. End
  109. Private
  110. Field _mutex:bbMutex
  111. End
  112. Class Condvar
  113. Method Wait( mutex:Mutex )
  114. _condvar.wait( mutex._mutex )
  115. End
  116. Method Notify()
  117. _condvar.notify_one()
  118. End
  119. Method NotifyAll()
  120. _condvar.notify_all()
  121. End
  122. Private
  123. Field _condvar:bbCondvar
  124. End
  125. Class Semaphore
  126. Method New( count:Int=0 )
  127. _count=count
  128. End
  129. Method Wait()
  130. _mutex.lock()
  131. While( _count<=0 )
  132. _condvar.wait( _mutex )
  133. Wend
  134. _count-=1
  135. _mutex.unlock()
  136. End
  137. Method Signal()
  138. _mutex.lock()
  139. _count+=1
  140. _condvar.notify_one()
  141. _mutex.unlock()
  142. End
  143. Private
  144. Field _count:Int
  145. Field _mutex:bbMutex
  146. Field _condvar:bbCondvar
  147. End
  148. #endif