#include "pthread_impl.h" #include static inline __mtx_t* __mtx_init(__mtx_t *m, int type) { if (m) { *m = (__mtx_t) { ._mt_rfs = 2, ._mt_typ = type, }; } return m; } static inline void __mtx_delete(__mtx_t * m) { free(m); } void __mtx_unref(__mtx_t *m) { if (m) { if (a_fetch_add(&m->_mt_rfs, -1) == 1) { __mtx_delete(m); } } } static inline __mtx_t* __mtx_getref_def(mtx_t *mut, __mtx_t* def) { /* Critical section protected by lock . */ __lock(&mut->_mx_lock); __mtx_t * ret = mut->_mx_mtx; if (ret) { __mtx_addref(ret); } else if (def) { ret = def; mut->_mx_mtx = def; } __unlock(&mut->_mx_lock); return ret; } __mtx_t* __mtx_getref(mtx_t *mut) { __mtx_t * ret = __mtx_getref_def(mut, 0); if (!ret) { __mtx_t * new = __mtx_init(malloc(sizeof *ret), mut->_mx_type); ret = __mtx_getref_def(mut, new); /* somebody sneaked in between the first and second call */ if (ret != new) __mtx_delete(new); } return ret; }