6 #if defined(__GNUC__) && defined(__i386__)
7 /* force_align_arg_pointer is required for proper function arguments aligning
8 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
9 * thread functions will be properly aligned on the stack, even though GCC may
10 * generate code with the assumption that it is. */
11 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
33 typedef int (*althrd_start_t
)(void*);
37 #define WIN32_LEAN_AND_MEAN
40 typedef DWORD althrd_t
;
41 typedef CRITICAL_SECTION almtx_t
;
42 typedef HANDLE alsem_t
;
45 inline void althrd_yield(void)
51 inline int almtx_lock(almtx_t
*mtx
)
53 if(!mtx
) return althrd_error
;
54 EnterCriticalSection(mtx
);
55 return althrd_success
;
58 inline int almtx_unlock(almtx_t
*mtx
)
60 if(!mtx
) return althrd_error
;
61 LeaveCriticalSection(mtx
);
62 return althrd_success
;
71 #include <dispatch/dispatch.h>
72 #else /* !__APPLE__ */
73 #include <semaphore.h>
74 #endif /* __APPLE__ */
76 typedef pthread_t althrd_t
;
77 typedef pthread_mutex_t almtx_t
;
79 typedef dispatch_semaphore_t alsem_t
;
80 #else /* !__APPLE__ */
81 typedef sem_t alsem_t
;
82 #endif /* __APPLE__ */
85 inline void althrd_yield(void)
91 inline int almtx_lock(almtx_t
*mtx
)
93 if(pthread_mutex_lock(mtx
) != 0)
95 return althrd_success
;
98 inline int almtx_unlock(almtx_t
*mtx
)
100 if(pthread_mutex_unlock(mtx
) != 0)
102 return althrd_success
;
108 int althrd_create(althrd_t
*thr
, althrd_start_t func
, void *arg
);
109 int althrd_detach(althrd_t thr
);
110 int althrd_join(althrd_t thr
, int *res
);
111 void althrd_setname(const char *name
);
113 int almtx_init(almtx_t
*mtx
, int type
);
114 void almtx_destroy(almtx_t
*mtx
);
116 int alsem_init(alsem_t
*sem
, unsigned int initial
);
117 void alsem_destroy(alsem_t
*sem
);
118 int alsem_post(alsem_t
*sem
);
119 int alsem_wait(alsem_t
*sem
);
120 int alsem_trywait(alsem_t
*sem
);
127 /* Add specializations for std::lock_guard and std::unique_lock which take an
128 * almtx_t and call the appropriate almtx_* functions.
133 class lock_guard
<almtx_t
> {
137 using mutex_type
= almtx_t
;
139 explicit lock_guard(almtx_t
&mtx
) : mMtx(mtx
) { almtx_lock(&mMtx
); }
140 lock_guard(almtx_t
&mtx
, std::adopt_lock_t
) noexcept
: mMtx(mtx
) { }
141 ~lock_guard() { almtx_unlock(&mMtx
); }
143 lock_guard(const lock_guard
&) = delete;
144 lock_guard
& operator=(const lock_guard
&) = delete;
148 class unique_lock
<almtx_t
> {
149 almtx_t
*mMtx
{nullptr};
153 using mutex_type
= almtx_t
;
155 unique_lock() noexcept
= default;
156 explicit unique_lock(almtx_t
&mtx
) : mMtx(&mtx
) { almtx_lock(mMtx
); mLocked
= true; }
157 unique_lock(unique_lock
&& rhs
) noexcept
: mMtx(rhs
.mMtx
), mLocked(rhs
.mLocked
)
158 { rhs
.mMtx
= nullptr; rhs
.mLocked
= false; }
159 ~unique_lock() { if(mLocked
) almtx_unlock(mMtx
); }
161 unique_lock
& operator=(const unique_lock
&) = delete;
162 unique_lock
& operator=(unique_lock
&& rhs
)
166 mMtx
= rhs
.mMtx
; rhs
.mMtx
= nullptr;
167 mLocked
= rhs
.mLocked
; rhs
.mLocked
= false;
186 #endif /* AL_THREADS_H */