pthread_linux.odin 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package unix;
  2. import "core:c"
  3. // TODO(tetra): For robustness, I'd like to mark this with align 16.
  4. // I cannot currently do this.
  5. // And at the time of writing there is a bug with putting it
  6. // as the only field in a struct.
  7. pthread_t :: distinct u64;
  8. // pthread_t :: struct #align 16 { x: u64 };
  9. // NOTE(tetra): Got all the size constants from pthreadtypes-arch.h on my
  10. // Linux machine.
  11. PTHREAD_COND_T_SIZE :: 48;
  12. PTHREAD_MUTEXATTR_T_SIZE :: 4;
  13. PTHREAD_CONDATTR_T_SIZE :: 4;
  14. PTHREAD_RWLOCKATTR_T_SIZE :: 8;
  15. PTHREAD_BARRIERATTR_T_SIZE :: 4;
  16. // WARNING: The sizes of these things are different yet again
  17. // on non-X86!
  18. when size_of(int) == 8 {
  19. PTHREAD_ATTR_T_SIZE :: 56;
  20. PTHREAD_MUTEX_T_SIZE :: 40;
  21. PTHREAD_RWLOCK_T_SIZE :: 56;
  22. PTHREAD_BARRIER_T_SIZE :: 32;
  23. } else when size_of(int) == 4 {
  24. PTHREAD_ATTR_T_SIZE :: 32;
  25. PTHREAD_MUTEX_T_SIZE :: 32;
  26. PTHREAD_RWLOCK_T_SIZE :: 44;
  27. PTHREAD_BARRIER_T_SIZE :: 20;
  28. }
  29. pthread_cond_t :: opaque struct #align 16 {
  30. _: [PTHREAD_COND_T_SIZE] c.char,
  31. };
  32. pthread_mutex_t :: opaque struct #align 16 {
  33. _: [PTHREAD_MUTEX_T_SIZE] c.char,
  34. };
  35. pthread_rwlock_t :: opaque struct #align 16 {
  36. _: [PTHREAD_RWLOCK_T_SIZE] c.char,
  37. };
  38. pthread_barrier_t :: opaque struct #align 16 {
  39. _: [PTHREAD_BARRIER_T_SIZE] c.char,
  40. };
  41. pthread_attr_t :: opaque struct #align 16 {
  42. _: [PTHREAD_ATTR_T_SIZE] c.char,
  43. };
  44. pthread_condattr_t :: opaque struct #align 16 {
  45. _: [PTHREAD_CONDATTR_T_SIZE] c.char,
  46. };
  47. pthread_mutexattr_t :: opaque struct #align 16 {
  48. _: [PTHREAD_MUTEXATTR_T_SIZE] c.char,
  49. };
  50. pthread_rwlockattr_t :: opaque struct #align 16 {
  51. _: [PTHREAD_RWLOCKATTR_T_SIZE] c.char,
  52. };
  53. pthread_barrierattr_t :: opaque struct #align 16 {
  54. _: [PTHREAD_BARRIERATTR_T_SIZE] c.char,
  55. };
  56. PTHREAD_MUTEX_NORMAL :: 0;
  57. PTHREAD_MUTEX_RECURSIVE :: 1;
  58. PTHREAD_MUTEX_ERRORCHECK :: 2;
  59. // TODO(tetra, 2019-11-01): Maybe make `enum c.int`s for these?
  60. PTHREAD_CREATE_JOINABLE :: 0;
  61. PTHREAD_CREATE_DETACHED :: 1;
  62. PTHREAD_INHERIT_SCHED :: 0;
  63. PTHREAD_EXPLICIT_SCHED :: 1;
  64. PTHREAD_PROCESS_PRIVATE :: 0;
  65. PTHREAD_PROCESS_SHARED :: 1;
  66. SCHED_OTHER :: 0;
  67. SCHED_FIFO :: 1;
  68. SCHED_RR :: 2; // Round robin.
  69. sched_param :: struct {
  70. sched_priority: c.int,
  71. }
  72. sem_t :: struct #align 16 {
  73. _: [SEM_T_SIZE] c.char,
  74. }
  75. when size_of(int) == 8 {
  76. SEM_T_SIZE :: 32;
  77. } else when size_of(int) == 4 {
  78. SEM_T_SIZE :: 16;
  79. }
  80. foreign import "system:pthread"
  81. @(default_calling_convention="c")
  82. foreign pthread {
  83. // create named semaphore.
  84. // used in process-shared semaphores.
  85. sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---;
  86. sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---;
  87. sem_destroy :: proc(sem: ^sem_t) -> c.int ---;
  88. sem_post :: proc(sem: ^sem_t) -> c.int ---;
  89. sem_wait :: proc(sem: ^sem_t) -> c.int ---;
  90. sem_trywait :: proc(sem: ^sem_t) -> c.int ---;
  91. // sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int ---;
  92. // NOTE: unclear whether pthread_yield is well-supported on Linux systems,
  93. // see https://linux.die.net/man/3/pthread_yield
  94. pthread_yield :: proc() -> c.int ---;
  95. }