SHARE
TWEET

concurrent.s

a guest Dec 31st, 2011 110 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Copyright (c) 2012 Teresa Bradbury
  2.  
  3. ; Execution starts here
  4. ; In this example there are 3 threads
  5. ; Thread 2 prints twice then kills itself (by returning)
  6. ; Thread 1 loops until the main thread kills it
  7. 0x0100:
  8. call threadinit
  9. load #thread1 R1
  10. load #thread1stack R2
  11. call threadcreate
  12. store R1 thread1id
  13. load #thread2 R1
  14. load #thread2stack R2
  15. call threadcreate
  16. store R1 thread2id
  17. mainloop:
  18. load #mainstr R1
  19. call printstring
  20. call threadyield
  21. ;jump mainloop  ; uncomment this for inf-loop
  22. load #mainstr R1
  23. call printstring
  24. call threadyield
  25. load #mainstr R1
  26. call printstring
  27. call threadyield
  28. load #mainstr R1
  29. call printstring
  30. call threadyield
  31. load thread1id R1
  32. call threaddestroy
  33. load #mainstr R1
  34. call printstring
  35. call threadyield
  36. load #mainstr R1
  37. call printstring
  38. call threadselfdestruct
  39.  
  40. thread1id : block 1
  41. thread2id : block 1
  42. mainstr : block #"Main Thread\n"
  43.  
  44. thread1 :
  45. load #thread1str R1
  46. call printstring
  47. call threadyield
  48. jump thread1
  49. ;return
  50.  
  51. thread2 :
  52. load #thread2str R1
  53. call printstring
  54. call threadyield
  55. ;jump thread2
  56. load #thread2str R1
  57. call printstring
  58. call threadyield
  59. return
  60.  
  61. thread1stack : block 8
  62. thread2stack : block 8
  63. thread1str : block #"Thread 1\n"
  64. thread2str : block #"Thread 2\n"
  65.  
  66. ; R1 : string pointer (changed)
  67. printstring :
  68. load R1 R2
  69. jumpz R2 printstring_end
  70. store R2 0xfff0
  71. add R1 ONE R1
  72. jump printstring
  73. printstring_end :
  74. return
  75.  
  76. ; -------------------------------------
  77. ; --------- Concurrency Data ----------
  78. ; -------------------------------------
  79.  
  80. maxthreads : block #3
  81. ; For each thread, the first word is one if the thread exists
  82. ;  and zero otherwise. The second word is the stack pointer.
  83. threaddata : block 6
  84. currentthreadid : block 1
  85.  
  86. ; -------------------------------------
  87. ; ------- Concurrency Functions -------
  88. ; -------------------------------------
  89.  
  90. ; must be called at start of the program
  91. ; it initializes the data structures
  92. ; No parameters
  93. threadinit :
  94. load maxthreads R0
  95. threadinit_threaddatainit :
  96. ; R0 is the thread that is being initialised. It counts down.
  97. add R0 MONE R0
  98. ; thread id
  99. move R0 R1
  100. ; structure offset
  101. move ZERO R2
  102. ; no flags
  103. move ZERO R3
  104. call threaddatastore
  105. jumpnz R0 threadinit_threaddatainit
  106. ; set thread zero to active
  107. move ZERO R1
  108. move ZERO R2
  109. move ONE R3
  110. call threaddatastore
  111. store ZERO currentthreadid
  112. return
  113.  
  114. ; R1 : in thread id
  115. ; R2 : in structure offset
  116. ; R1 : out data
  117. ; preserves R0
  118. threaddataload :
  119. ; structure has size 2
  120. load #2 R3
  121. mult R1 R3 R3
  122. add R3 R2 R3
  123. load R3 #threaddata R1
  124. return
  125.  
  126. ; R1 : in thread id
  127. ; R2 : in structure offset
  128. ; R3 : in data
  129. ; preserves R0
  130. threaddatastore :
  131. ; structure has size 2
  132. load #2 R4
  133. mult R1 R4 R4
  134. add R4 R2 R4
  135. store R3 #threaddata R4
  136. return
  137.  
  138. ; R1 : in function pointer
  139. ; R2 : in stack pointer
  140. ; R1 : out thread id (-1 for error)
  141. ;  Stack needs to be big enough for thread's workings,
  142. ;  plus at least 3
  143. threadcreate :
  144. push R1
  145. push R2
  146. ; find a free thread id (in R0)
  147. move ZERO R0
  148. threadcreate_findid :
  149. load maxthreads R1
  150. sub R1 R0 R2
  151. ; if R2 == 0 then R0 == maxthreads
  152. ;   so return -1 as no available threads
  153. jumpnz R2 threadcreate_no_error
  154. move MONE R1
  155. return
  156. threadcreate_no_error :
  157. move R0 R1
  158. move ZERO R2
  159. call threaddataload
  160. jumpz R1 threadcreate_foundid
  161. add ONE R0 R0
  162. jump threadcreate_findid
  163.  
  164. threadcreate_foundid :
  165. ; created thread is inactive (not current) and
  166. ;  the stack contains a pointer to selfdestruct then
  167. ;  the provided stack pointer so first it will
  168. ;  return to the given function and if it returns
  169. ;  again it will be destroyed
  170. pop R2 ; stack pointer
  171. pop R1 ; function pointer
  172. store R1 #1 R2
  173. load #threadselfdestruct R1
  174. store R1 #0 R2
  175. ; Store the stack pointer
  176. move R0 R1
  177. add R2 ONE R3
  178. move ONE R2
  179. call threaddatastore
  180. ; Mark the thread as existant
  181. move R0 R1
  182. move ZERO R2
  183. move ONE R3
  184. call threaddatastore
  185.  
  186. ; Return the created thread id
  187. move R0 R1
  188. return
  189.  
  190. ; Pass thread id in R1
  191. threaddestroy :
  192. ; If thread id is not current, we just mark nonexistant
  193. ; If thread id *is* current, we mark nonexistant and then call
  194. ;  threadyield to switch to another thread
  195. move R1 R0 ; because R0 survives the function calls
  196. ; Turn off the thread
  197. move R0 R1
  198. move ZERO R2
  199. move ZERO R3
  200. call threaddatastore
  201. ; Is this the current thread?
  202. load currentthreadid R1
  203. sub R0 R1 R2
  204. jumpnz R2 threaddestroy_notcurrentthread
  205. call threadyield
  206. threaddestroy_notcurrentthread :
  207. return
  208.  
  209. ; No parameters - destroys current thread
  210. ; this is called on returning from a thread function
  211. threadselfdestruct :
  212. load currentthreadid R1
  213. jump threaddestroy
  214.  
  215. ; No parameters
  216. threadyield :
  217. ; store the stackpointer
  218. load currentthreadid R1
  219. move ONE R2
  220. move SP R3
  221. call threaddatastore
  222. ; round robin scheduling
  223. ;  we will eventually choose the thread id in R0
  224. load currentthreadid R0
  225. threadyield_findnext :
  226. load maxthreads R1
  227. add R0 ONE R0
  228. sub R1 R0 R2
  229. ; if R2 == 0 then R0 == maxthreads
  230. ;   so R0 := 0
  231. jumpnz R2 threadyield_mod
  232. move ZERO R0
  233. threadyield_mod :
  234. move R0 R1
  235. move ZERO R2
  236. call threaddataload
  237. jumpnz R1 threadyield_foundnext
  238. ; if none of the threads exist, halt
  239. load currentthreadid R4
  240. sub R4 R0 R4
  241. jumpnz R4 threadyield_findnext
  242. halt
  243. threadyield_foundnext :
  244. store R0 currentthreadid
  245. ; load the new stack pointer
  246. load currentthreadid R1
  247. move ONE R2
  248. call threaddataload
  249. move R1 SP
  250. return
RAW Paste Data
Pastebin PRO Summer Special!
Get 40% OFF on Pastebin PRO accounts!
Top