pthread.odin 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. package posix
  2. import "core:c"
  3. when ODIN_OS == .Darwin {
  4. foreign import lib "system:System.framework"
  5. } else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
  6. foreign import lib "system:pthread"
  7. } else {
  8. foreign import lib "system:c"
  9. }
  10. // pthread.h - threads
  11. // NOTE: mutexes, rwlock, condition variables, once and barriers are left out in favour of `core:sync`.
  12. foreign lib {
  13. /*
  14. Initializes a thread attributes object.
  15. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_init.html ]]
  16. */
  17. pthread_attr_init :: proc(attr: ^pthread_attr_t) -> Errno ---
  18. /*
  19. Destroys a thread attributes object.
  20. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_init.html ]]
  21. */
  22. pthread_attr_destroy :: proc(attr: ^pthread_attr_t) -> Errno ---
  23. /*
  24. The detachstate attribute controls whether the thread is created in a detached state.
  25. If the thread is created detached, then use of the ID of the newly created thread is an error.
  26. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getdetachstate.html ]]
  27. */
  28. pthread_attr_getdetachstate :: proc(attr: ^pthread_attr_t, detachstate: ^Detach_State) -> Errno ---
  29. /*
  30. The detachstate attribute controls whether the thread is created in a detached state.
  31. If the thread is created detached, then use of the ID of the newly created thread is an error.
  32. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getdetachstate.html ]]
  33. */
  34. pthread_attr_setdetachstate :: proc(attr: ^pthread_attr_t, detachstate: Detach_State) -> Errno ---
  35. /*
  36. The guardsize attribute controls the size of the guard area for the created thread's stack.
  37. The guardsize attribute provides protection against overflow of the stack pointer.
  38. If a thread's stack is created with guard protection, the implementation allocates extra memory
  39. at the overflow end of the stack as a buffer against stack overflow of the stack pointer.
  40. If an application overflows into this buffer an error shall result (possibly in a SIGSEGV signal being delivered to the thread).
  41. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setguardsize.html ]]
  42. */
  43. pthread_attr_getguardsize :: proc(attr: ^pthread_attr_t, guardsize: ^c.size_t) -> Errno ---
  44. /*
  45. The guardsize attribute controls the size of the guard area for the created thread's stack.
  46. The guardsize attribute provides protection against overflow of the stack pointer.
  47. If a thread's stack is created with guard protection, the implementation allocates extra memory
  48. at the overflow end of the stack as a buffer against stack overflow of the stack pointer.
  49. If an application overflows into this buffer an error shall result (possibly in a SIGSEGV signal being delivered to the thread).
  50. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setguardsize.html ]]
  51. */
  52. pthread_attr_setguardsize :: proc(attr: ^pthread_attr_t, guardsize: c.size_t) -> Errno ---
  53. /*
  54. When the attributes objects are used by pthread_create(), the inheritsched attribute determines
  55. how the other scheduling attributes of the created thread shall be set.
  56. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setinheritsched.html ]]
  57. */
  58. pthread_attr_getinheritsched :: proc(attr: ^pthread_attr_t, inheritsched: ^Inherit_Sched) -> Errno ---
  59. /*
  60. When the attributes objects are used by pthread_create(), the inheritsched attribute determines
  61. how the other scheduling attributes of the created thread shall be set.
  62. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setinheritsched.html ]]
  63. */
  64. pthread_attr_setinheritsched :: proc(attr: ^pthread_attr_t, inheritsched: Inherit_Sched) -> Errno ---
  65. /*
  66. Gets the scheduling param.
  67. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setschedparam.html ]]
  68. */
  69. pthread_attr_getschedparam :: proc(attr: ^pthread_attr_t, param: ^sched_param) -> Errno ---
  70. /*
  71. Sets the scheduling param.
  72. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setschedparam.html ]]
  73. */
  74. pthread_attr_setschedparam :: proc(attr: ^pthread_attr_t, param: ^sched_param) -> Errno ---
  75. /*
  76. Gets the scheduling poicy.
  77. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getschedpolicy.html ]]
  78. */
  79. pthread_attr_getschedpolicy :: proc(attr: ^pthread_attr_t, policy: ^Sched_Policy) -> Errno ---
  80. /*
  81. Sets the scheduling poicy.
  82. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getschedpolicy.html ]]
  83. */
  84. pthread_attr_setschedpolicy :: proc(attr: ^pthread_attr_t, policy: Sched_Policy) -> Errno ---
  85. /*
  86. Gets the contention scope.
  87. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getscope.html ]]
  88. */
  89. pthread_attr_getscope :: proc(attr: ^pthread_attr_t, contentionscope: ^Thread_Scope) -> Errno ---
  90. /*
  91. Sets the contention scope.
  92. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getscope.html ]]
  93. */
  94. pthread_attr_setscope :: proc(attr: ^pthread_attr_t, contentionscope: ^Thread_Scope) -> Errno ---
  95. /*
  96. Get the area of storage to be used for the created thread's stack.
  97. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getstack.html ]]
  98. */
  99. pthread_attr_getstack :: proc(attr: ^pthread_attr_t, stackaddr: ^[^]byte, stacksize: ^c.size_t) -> Errno ---
  100. /*
  101. Specify the area of storage to be used for the created thread's stack.
  102. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getstack.html ]]
  103. */
  104. pthread_attr_setstack :: proc(attr: ^pthread_attr_t, stackaddr: [^]byte, stacksize: c.size_t) -> Errno ---
  105. /*
  106. Gets the stack size.
  107. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getstacksize.html ]]
  108. */
  109. pthread_attr_getstacksize :: proc(attr: ^pthread_attr_t, stacksize: ^c.size_t) -> Errno ---
  110. /*
  111. Sets the stack size.
  112. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getstacksize.html ]]
  113. */
  114. pthread_attr_setstacksize :: proc(attr: ^pthread_attr_t, stacksize: c.size_t) -> Errno ---
  115. /*
  116. Register fork handlers to be called before and after fork().
  117. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html ]]
  118. */
  119. pthread_atfork :: proc(prepare: proc "c" (), parent: proc "c" (), child: proc "c" ()) -> Errno ---
  120. /*
  121. Cancel the execution of a thread.
  122. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cancel.html ]]
  123. */
  124. pthread_cancel :: proc(thread: pthread_t) -> Errno ---
  125. /*
  126. Creates a new thread with the given attributes.
  127. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_create.html ]]
  128. */
  129. pthread_create :: proc(
  130. thread: ^pthread_t,
  131. attr: ^pthread_attr_t,
  132. start_routine: proc "c" (arg: rawptr) -> rawptr,
  133. arg: rawptr,
  134. ) -> Errno ---
  135. /*
  136. Indicate that storage for the thread can be reclaimed when the thread terminates.
  137. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_detach.html ]]
  138. */
  139. pthread_detach :: proc(thread: pthread_t) -> Errno ---
  140. /*
  141. Compare thread IDs.
  142. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_equal.html ]]
  143. */
  144. pthread_equal :: proc(t1: pthread_t, t2: pthread_t) -> b32 ---
  145. /*
  146. Terminates the calling thread and make the given value available to any successfull join calls.
  147. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_exit.html ]]
  148. */
  149. pthread_exit :: proc(value_ptr: rawptr) -> ! ---
  150. /*
  151. Gets the current concurrency hint.
  152. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getconcurrency.html ]]
  153. */
  154. pthread_getconcurrency :: proc() -> c.int ---
  155. /*
  156. Sets the current desired concurrency hint.
  157. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getconcurrency.html ]]
  158. */
  159. pthread_setconcurrency :: proc(new_level: c.int) -> Errno ---
  160. /*
  161. Access a thread CPU-time clock.
  162. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getcpuclockid.html ]]
  163. */
  164. pthread_getcpuclockid :: proc(thread_id: pthread_t, clock_id: ^clockid_t) -> Errno ---
  165. /*
  166. Gets the scheduling policy and parameters.
  167. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getschedparam.html ]]
  168. */
  169. pthread_getschedparam :: proc(thread: pthread_t, policy: ^Sched_Policy, param: ^sched_param) -> Errno ---
  170. /*
  171. Sets the scheduling policy and parameters.
  172. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getschedparam.html ]]
  173. */
  174. pthread_setschedparam :: proc(thread: pthread_t, policy: Sched_Policy, param: ^sched_param) -> Errno ---
  175. /*
  176. Creates a thread-specific data key visible to all threads in the process.
  177. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_key_create.html ]]
  178. */
  179. pthread_key_create :: proc(key: ^pthread_key_t, destructor: proc "c" (value: rawptr) = nil) -> Errno ---
  180. /*
  181. Deletes a thread-specific data key visible to all threads in the process.
  182. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_key_delete.html ]]
  183. */
  184. pthread_key_delete :: proc(key: pthread_key_t) -> Errno ---
  185. /*
  186. Returns the value currently bound to the specified key on behalf of the calling thread.
  187. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getspecific.html ]]
  188. */
  189. pthread_getspecific :: proc(key: pthread_key_t) -> rawptr ---
  190. /*
  191. Sets the value currently bound to the specified key on behalf of the calling thread.
  192. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getspecific.html ]]
  193. */
  194. pthread_setspecific :: proc(key: pthread_key_t, value: rawptr) -> Errno ---
  195. /*
  196. Suspends execution of the calling thread until the target thread terminates.
  197. Example:
  198. ar: [10_000]i32
  199. sb1 := ar[:5_000]
  200. sb2 := ar[5_000:]
  201. th1, th2: posix.pthread_t
  202. posix.pthread_create(&th1, nil, incer, &sb1)
  203. posix.pthread_create(&th2, nil, incer, &sb2)
  204. posix.pthread_join(th1)
  205. posix.pthread_join(th2)
  206. incer :: proc "c" (arg: rawptr) -> rawptr {
  207. sb := (^[]i32)(arg)
  208. for &val in sb {
  209. val += 1
  210. }
  211. return nil
  212. }
  213. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html ]]
  214. */
  215. pthread_join :: proc(thread: pthread_t, value_ptr: ^rawptr = nil) -> Errno ---
  216. /*
  217. Get the calling thread ID.
  218. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html ]]
  219. */
  220. pthread_self :: proc() -> pthread_t ---
  221. /*
  222. Atomically set the calling thread's cancelability and return the previous value.
  223. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_setcancelstate.html ]]
  224. */
  225. pthread_setcancelstate :: proc(state: Cancel_State, oldstate: ^Cancel_State) -> Errno ---
  226. /*
  227. Atomically set the calling thread's cancel type and return the previous value.
  228. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_setcancelstate.html ]]
  229. */
  230. pthread_setcanceltype :: proc(type: Cancel_Type, oldtype: ^Cancel_Type) -> Errno ---
  231. /*
  232. Creates a cancellation point in the calling thread.
  233. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_testcancel.html ]]
  234. */
  235. pthread_testcancel :: proc() ---
  236. /*
  237. Sets the scheduling priority for the thread given.
  238. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_setschedprio.html ]]
  239. */
  240. pthread_setschedprio :: proc(thread: pthread_t, prio: c.int) -> Errno ---
  241. }
  242. Detach_State :: enum c.int {
  243. // Causes all threads to be in the joinable state.
  244. CREATE_JOINABLE = PTHREAD_CREATE_JOINABLE,
  245. // Causes all threads to be in the detached state.
  246. CREATE_DETACHED = PTHREAD_CREATE_DETACHED,
  247. }
  248. Inherit_Sched :: enum c.int {
  249. // Threads inherit from the creating thread.
  250. INHERIT_SCHED = PTHREAD_INHERIT_SCHED,
  251. // Threads scheduling shall be set to the corresponding values from the attributes object.
  252. EXPLICIT_SCHED = PTHREAD_EXPLICIT_SCHED,
  253. }
  254. Thread_Scope :: enum c.int {
  255. // System scheduling contention scope.
  256. SYSTEM = PTHREAD_SCOPE_SYSTEM,
  257. // Process scheduling contention scope.
  258. PROCESS = PTHREAD_SCOPE_PROCESS,
  259. }
  260. Cancel_State :: enum c.int {
  261. ENABLE = PTHREAD_CANCEL_ENABLE,
  262. DISABLE = PTHREAD_CANCEL_DISABLE,
  263. }
  264. Cancel_Type :: enum c.int {
  265. DEFERRED = PTHREAD_CANCEL_DEFERRED,
  266. ASYNCHRONOUS = PTHREAD_CANCEL_ASYNCHRONOUS,
  267. }
  268. when ODIN_OS == .Darwin {
  269. PTHREAD_CANCEL_ASYNCHRONOUS :: 0x00
  270. PTHREAD_CANCEL_DEFERRED :: 0x02
  271. PTHREAD_CANCEL_DISABLE :: 0x00
  272. PTHREAD_CANCEL_ENABLE :: 0x01
  273. PTHREAD_CANCELED :: rawptr(uintptr(1))
  274. PTHREAD_CREATE_DETACHED :: 2
  275. PTHREAD_CREATE_JOINABLE :: 1
  276. PTHREAD_EXPLICIT_SCHED :: 2
  277. PTHREAD_INHERIT_SCHED :: 1
  278. PTHREAD_PRIO_INHERIT :: 1
  279. PTHREAD_PRIO_NONE :: 0
  280. PTHREAD_PRIO_PROTECT :: 2
  281. PTHREAD_PROCESS_SHARED :: 1
  282. PTHREAD_PROCESS_PRIVATE :: 2
  283. PTHREAD_SCOPE_PROCESS :: 2
  284. PTHREAD_SCOPE_SYSTEM :: 1
  285. pthread_t :: distinct u64
  286. pthread_attr_t :: struct {
  287. __sig: c.long,
  288. __opaque: [56]c.char,
  289. }
  290. pthread_key_t :: distinct c.ulong
  291. sched_param :: struct {
  292. sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
  293. _: [4]c.char,
  294. }
  295. } else when ODIN_OS == .FreeBSD {
  296. PTHREAD_CANCEL_ASYNCHRONOUS :: 0x02
  297. PTHREAD_CANCEL_DEFERRED :: 0x00
  298. PTHREAD_CANCEL_DISABLE :: 0x01
  299. PTHREAD_CANCEL_ENABLE :: 0x00
  300. PTHREAD_CANCELED :: rawptr(uintptr(1))
  301. PTHREAD_CREATE_DETACHED :: 1
  302. PTHREAD_CREATE_JOINABLE :: 0
  303. PTHREAD_EXPLICIT_SCHED :: 0
  304. PTHREAD_INHERIT_SCHED :: 4
  305. PTHREAD_PRIO_INHERIT :: 1
  306. PTHREAD_PRIO_NONE :: 0
  307. PTHREAD_PRIO_PROTECT :: 2
  308. PTHREAD_PROCESS_SHARED :: 0
  309. PTHREAD_PROCESS_PRIVATE :: 1
  310. PTHREAD_SCOPE_PROCESS :: 0
  311. PTHREAD_SCOPE_SYSTEM :: 2
  312. pthread_t :: distinct u64
  313. pthread_attr_t :: distinct rawptr
  314. pthread_key_t :: distinct c.int
  315. sched_param :: struct {
  316. sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
  317. }
  318. } else when ODIN_OS == .NetBSD {
  319. PTHREAD_CANCEL_ASYNCHRONOUS :: 1
  320. PTHREAD_CANCEL_DEFERRED :: 0
  321. PTHREAD_CANCEL_DISABLE :: 1
  322. PTHREAD_CANCEL_ENABLE :: 0
  323. PTHREAD_CANCELED :: rawptr(uintptr(1))
  324. PTHREAD_CREATE_DETACHED :: 1
  325. PTHREAD_CREATE_JOINABLE :: 0
  326. PTHREAD_EXPLICIT_SCHED :: 1
  327. PTHREAD_INHERIT_SCHED :: 0
  328. PTHREAD_PRIO_INHERIT :: 1
  329. PTHREAD_PRIO_NONE :: 0
  330. PTHREAD_PRIO_PROTECT :: 2
  331. PTHREAD_PROCESS_SHARED :: 1
  332. PTHREAD_PROCESS_PRIVATE :: 0
  333. PTHREAD_SCOPE_PROCESS :: 0
  334. PTHREAD_SCOPE_SYSTEM :: 1
  335. pthread_t :: distinct rawptr
  336. pthread_attr_t :: struct {
  337. pta_magic: c.uint,
  338. pta_flags: c.int,
  339. pta_private: rawptr,
  340. }
  341. pthread_key_t :: distinct c.int
  342. sched_param :: struct {
  343. sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
  344. }
  345. } else when ODIN_OS == .OpenBSD {
  346. PTHREAD_CANCEL_ASYNCHRONOUS :: 2
  347. PTHREAD_CANCEL_DEFERRED :: 0
  348. PTHREAD_CANCEL_DISABLE :: 1
  349. PTHREAD_CANCEL_ENABLE :: 0
  350. PTHREAD_CANCELED :: rawptr(uintptr(1))
  351. PTHREAD_CREATE_DETACHED :: 0x1
  352. PTHREAD_CREATE_JOINABLE :: 0
  353. PTHREAD_EXPLICIT_SCHED :: 0
  354. PTHREAD_INHERIT_SCHED :: 0x4
  355. PTHREAD_PRIO_INHERIT :: 1
  356. PTHREAD_PRIO_NONE :: 0
  357. PTHREAD_PRIO_PROTECT :: 2
  358. PTHREAD_PROCESS_SHARED :: 0
  359. PTHREAD_PROCESS_PRIVATE :: 1
  360. PTHREAD_SCOPE_PROCESS :: 0
  361. PTHREAD_SCOPE_SYSTEM :: 0x2
  362. pthread_t :: distinct rawptr
  363. pthread_attr_t :: distinct rawptr
  364. pthread_key_t :: distinct c.int
  365. sched_param :: struct {
  366. sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
  367. }
  368. } else {
  369. #panic("posix is unimplemented for the current target")
  370. }