diff options
Diffstat (limited to 'erts/emulator/beam/erl_threads.h')
-rw-r--r-- | erts/emulator/beam/erl_threads.h | 467 |
1 files changed, 190 insertions, 277 deletions
diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h index 5347979372..8b5c17d739 100644 --- a/erts/emulator/beam/erl_threads.h +++ b/erts/emulator/beam/erl_threads.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * Copyright Ericsson AB 2001-2017. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -259,13 +259,16 @@ #include "sys.h" +#include "erl_lock_flags.h" +#include "erl_term.h" + #ifdef USE_THREADS #define ETHR_TRY_INLINE_FUNCS #include "ethread.h" + #include "erl_lock_check.h" #include "erl_lock_count.h" -#include "erl_term.h" #if defined(__GLIBC__) && (__GLIBC__ << 16) + __GLIBC_MINOR__ < (2 << 16) + 4 /* @@ -307,9 +310,11 @@ typedef struct { erts_lc_lock_t lc; #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_lock_t lcnt; + erts_lcnt_ref_t lcnt; +#endif +#ifdef DEBUG + erts_lock_flags_t flags; #endif - } erts_mtx_t; typedef ethr_cond erts_cnd_t; @@ -320,7 +325,10 @@ typedef struct { erts_lc_lock_t lc; #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_lock_t lcnt; + erts_lcnt_ref_t lcnt; +#endif +#ifdef DEBUG + erts_lock_flags_t flags; #endif } erts_rwmtx_t; @@ -365,7 +373,10 @@ typedef struct { erts_lc_lock_t lc; #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_lock_t lcnt; + erts_lcnt_ref_t lcnt; +#endif +#ifdef DEBUG + erts_lock_flags_t flags; #endif } erts_spinlock_t; @@ -376,7 +387,10 @@ typedef struct { erts_lc_lock_t lc; #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_lock_t lcnt; + erts_lcnt_ref_t lcnt; +#endif +#ifdef DEBUG + erts_lock_flags_t flags; #endif } erts_rwlock_t; @@ -479,16 +493,14 @@ ERTS_GLB_INLINE void erts_thr_install_exit_handler(void (*exit_handler)(void)); ERTS_GLB_INLINE erts_tid_t erts_thr_self(void); ERTS_GLB_INLINE int erts_thr_getname(erts_tid_t tid, char *buf, size_t len); ERTS_GLB_INLINE int erts_equal_tids(erts_tid_t x, erts_tid_t y); -ERTS_GLB_INLINE void erts_mtx_init_x(erts_mtx_t *mtx, char *name, Eterm extra, - int enable_lcnt); -ERTS_GLB_INLINE void erts_mtx_init_x_opt(erts_mtx_t *mtx, char *name, Eterm extra, - Uint16 opt, int enable_lcnt); -ERTS_GLB_INLINE void erts_mtx_init_locked_x(erts_mtx_t *mtx, - char *name, - Eterm extra, - int enable_lcnt); -ERTS_GLB_INLINE void erts_mtx_init(erts_mtx_t *mtx, char *name); -ERTS_GLB_INLINE void erts_mtx_init_locked(erts_mtx_t *mtx, char *name); +ERTS_GLB_INLINE void erts_mtx_init(erts_mtx_t *mtx, + char *name, + Eterm extra, + erts_lock_flags_t flags); +ERTS_GLB_INLINE void erts_mtx_init_locked(erts_mtx_t *mtx, + char *name, + Eterm extra, + erts_lock_flags_t flags); ERTS_GLB_INLINE void erts_mtx_destroy(erts_mtx_t *mtx); #ifdef ERTS_ENABLE_LOCK_POSITION ERTS_GLB_INLINE int erts_mtx_trylock_x(erts_mtx_t *mtx, char *file, @@ -507,18 +519,15 @@ ERTS_GLB_INLINE void erts_cnd_wait(erts_cnd_t *cnd, erts_mtx_t *mtx); ERTS_GLB_INLINE void erts_cnd_signal(erts_cnd_t *cnd); ERTS_GLB_INLINE void erts_cnd_broadcast(erts_cnd_t *cnd); ERTS_GLB_INLINE void erts_rwmtx_set_reader_group(int no); -ERTS_GLB_INLINE void erts_rwmtx_init_opt_x(erts_rwmtx_t *rwmtx, - erts_rwmtx_opt_t *opt, - char *name, - Eterm extra); -ERTS_GLB_INLINE void erts_rwmtx_init_x(erts_rwmtx_t *rwmtx, - char *name, - Eterm extra); ERTS_GLB_INLINE void erts_rwmtx_init_opt(erts_rwmtx_t *rwmtx, - erts_rwmtx_opt_t *opt, - char *name); + erts_rwmtx_opt_t *opt, + char *name, + Eterm extra, + erts_lock_flags_t flags); ERTS_GLB_INLINE void erts_rwmtx_init(erts_rwmtx_t *rwmtx, - char *name); + char *name, + Eterm extra, + erts_lock_flags_t flags); ERTS_GLB_INLINE void erts_rwmtx_destroy(erts_rwmtx_t *rwmtx); #ifdef ERTS_ENABLE_LOCK_POSITION ERTS_GLB_INLINE int erts_rwmtx_tryrlock_x(erts_rwmtx_t *rwmtx, char *file, unsigned int line); @@ -608,16 +617,10 @@ ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_cmpxchg(erts_no_atomic64_t *xchgp ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_read_bset(erts_no_atomic64_t *var, erts_aint64_t mask, erts_aint64_t set); - -ERTS_GLB_INLINE void erts_spinlock_init_x_opt(erts_spinlock_t *lock, - char *name, - Eterm extra, - Uint16 opt); -ERTS_GLB_INLINE void erts_spinlock_init_x(erts_spinlock_t *lock, - char *name, - Eterm extra); ERTS_GLB_INLINE void erts_spinlock_init(erts_spinlock_t *lock, - char *name); + char *name, + Eterm extra, + erts_lock_flags_t flags); ERTS_GLB_INLINE void erts_spinlock_destroy(erts_spinlock_t *lock); ERTS_GLB_INLINE void erts_spin_unlock(erts_spinlock_t *lock); #ifdef ERTS_ENABLE_LOCK_POSITION @@ -626,11 +629,10 @@ ERTS_GLB_INLINE void erts_spin_lock_x(erts_spinlock_t *lock, char *file, unsigne ERTS_GLB_INLINE void erts_spin_lock(erts_spinlock_t *lock); #endif ERTS_GLB_INLINE int erts_lc_spinlock_is_locked(erts_spinlock_t *lock); -ERTS_GLB_INLINE void erts_rwlock_init_x(erts_rwlock_t *lock, - char *name, - Eterm extra); ERTS_GLB_INLINE void erts_rwlock_init(erts_rwlock_t *lock, - char *name); + char *name, + Eterm extra, + erts_lock_flags_t flags); ERTS_GLB_INLINE void erts_rwlock_destroy(erts_rwlock_t *lock); ERTS_GLB_INLINE void erts_read_unlock(erts_rwlock_t *lock); #ifdef ERTS_ENABLE_LOCK_POSITION @@ -649,6 +651,7 @@ ERTS_GLB_INLINE void erts_tsd_set(erts_tsd_key_t key, void *value); ERTS_GLB_INLINE void * erts_tsd_get(erts_tsd_key_t key); ERTS_GLB_INLINE erts_tse_t *erts_tse_fetch(void); ERTS_GLB_INLINE void erts_tse_return(erts_tse_t *ep); +ERTS_GLB_INLINE void erts_tse_prepare_timed(erts_tse_t *ep); ERTS_GLB_INLINE void erts_tse_set(erts_tse_t *ep); ERTS_GLB_INLINE void erts_tse_reset(erts_tse_t *ep); ERTS_GLB_INLINE int erts_tse_wait(erts_tse_t *ep); @@ -2055,6 +2058,8 @@ erts_atomic64_read_dirty(erts_atomic64_t *var) #endif /* !USE_THREADS */ +#include "erl_msacc.h" + #if ERTS_GLB_INLINE_INCL_FUNC_DEF ERTS_GLB_INLINE void @@ -2161,107 +2166,41 @@ erts_equal_tids(erts_tid_t x, erts_tid_t y) } ERTS_GLB_INLINE void -erts_mtx_init_x(erts_mtx_t *mtx, char *name, Eterm extra, int enable_lcnt) +erts_mtx_init(erts_mtx_t *mtx, char *name, Eterm extra, erts_lock_flags_t flags) { #ifdef USE_THREADS int res = ethr_mutex_init(&mtx->mtx); - if (res) - erts_thr_fatal_error(res, "initialize mutex"); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock_x(&mtx->lc, name, ERTS_LC_FLG_LT_MUTEX, extra); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - if (enable_lcnt) - erts_lcnt_init_lock_x(&mtx->lcnt, name, ERTS_LCNT_LT_MUTEX, extra); - else - erts_lcnt_init_lock_x(&mtx->lcnt, NULL, ERTS_LCNT_LT_MUTEX, extra); -#endif -#endif -} + if (res) { + erts_thr_fatal_error(res, "initialize mutex"); + } -ERTS_GLB_INLINE void -erts_mtx_init_x_opt(erts_mtx_t *mtx, char *name, Eterm extra, Uint16 opt, - int enable_lcnt) -{ -#ifdef USE_THREADS - int res = ethr_mutex_init(&mtx->mtx); - if (res) - erts_thr_fatal_error(res, "initialize mutex"); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock_x(&mtx->lc, name, ERTS_LC_FLG_LT_MUTEX, extra); + flags |= ERTS_LOCK_TYPE_MUTEX; +#ifdef DEBUG + mtx->flags = flags; #endif -#ifdef ERTS_ENABLE_LOCK_COUNT - if (enable_lcnt) - erts_lcnt_init_lock_x(&mtx->lcnt, name, ERTS_LCNT_LT_MUTEX | opt, extra); - else - erts_lcnt_init_lock_x(&mtx->lcnt, NULL, ERTS_LCNT_LT_MUTEX | opt, extra); -#endif -#endif -} - -ERTS_GLB_INLINE void -erts_mtx_init_locked_x(erts_mtx_t *mtx, char *name, Eterm extra, int enable_lcnt) -{ -#ifdef USE_THREADS - int res = ethr_mutex_init(&mtx->mtx); - if (res) - erts_thr_fatal_error(res, "initialize mutex"); #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock_x(&mtx->lc, name, ERTS_LC_FLG_LT_MUTEX, extra); + erts_lc_init_lock_x(&mtx->lc, name, flags, extra); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - if (enable_lcnt) - erts_lcnt_init_lock_x(&mtx->lcnt, name, ERTS_LCNT_LT_MUTEX, extra); - else - erts_lcnt_init_lock_x(&mtx->lcnt, NULL, ERTS_LCNT_LT_MUTEX, extra); -#endif - ethr_mutex_lock(&mtx->mtx); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_trylock(1, &mtx->lc); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_trylock(&mtx->lcnt, 1); -#endif + erts_lcnt_init_ref_x(&mtx->lcnt, name, extra, flags); #endif +#endif /* USE_THREADS */ } ERTS_GLB_INLINE void -erts_mtx_init(erts_mtx_t *mtx, char *name) +erts_mtx_init_locked(erts_mtx_t *mtx, char *name, Eterm extra, erts_lock_flags_t flags) { #ifdef USE_THREADS - int res = ethr_mutex_init(&mtx->mtx); - if (res) - erts_thr_fatal_error(res, "initialize mutex"); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock(&mtx->lc, name, ERTS_LC_FLG_LT_MUTEX); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init_lock(&mtx->lcnt, name, ERTS_LCNT_LT_MUTEX); -#endif -#endif -} + erts_mtx_init(mtx, name, extra, flags); -ERTS_GLB_INLINE void -erts_mtx_init_locked(erts_mtx_t *mtx, char *name) -{ -#ifdef USE_THREADS - int res = ethr_mutex_init(&mtx->mtx); - if (res) - erts_thr_fatal_error(res, "initialize mutex"); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock(&mtx->lc, name, ERTS_LC_FLG_LT_MUTEX); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init_lock(&mtx->lcnt, name, ERTS_LCNT_LT_MUTEX); -#endif ethr_mutex_lock(&mtx->mtx); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_trylock(1, &mtx->lc); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_trylock(&mtx->lcnt, 1); -#endif + #ifdef ERTS_ENABLE_LOCK_CHECK + erts_lc_trylock(1, &mtx->lc); + #endif + #ifdef ERTS_ENABLE_LOCK_COUNT + erts_lcnt_trylock(&mtx->lcnt, 1); + #endif #endif } @@ -2270,11 +2209,14 @@ erts_mtx_destroy(erts_mtx_t *mtx) { #ifdef USE_THREADS int res; + + ASSERT(!(mtx->flags & ERTS_LOCK_FLAGS_PROPERTY_STATIC)); + #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_destroy_lock(&mtx->lc); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_destroy_lock(&mtx->lcnt); + erts_lcnt_uninstall(&mtx->lcnt); #endif res = ethr_mutex_destroy(&mtx->mtx); if (res != 0) { @@ -2371,7 +2313,8 @@ erts_lc_mtx_is_locked(erts_mtx_t *mtx) #if defined(USE_THREADS) && defined(ERTS_ENABLE_LOCK_CHECK) int res; erts_lc_lock_t lc = mtx->lc; - lc.flags = 0; + lc.flags = ERTS_LOCK_FLAGS_TYPE_MUTEX; + lc.taken_options = 0; erts_lc_have_locks(&res, &lc, 1); return res; #else @@ -2413,6 +2356,7 @@ erts_cnd_wait(erts_cnd_t *cnd, erts_mtx_t *mtx) { #ifdef USE_THREADS int res; + ERTS_MSACC_PUSH_AND_SET_STATE(ERTS_MSACC_STATE_SLEEP); #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_unlock(&mtx->lc); #endif @@ -2431,6 +2375,7 @@ erts_cnd_wait(erts_cnd_t *cnd, erts_mtx_t *mtx) #endif if (res != 0 && res != EINTR) erts_thr_fatal_error(res, "wait on condition variable"); + ERTS_MSACC_POP_STATE(); #endif } @@ -2469,7 +2414,7 @@ erts_rwmtx_set_reader_group(int no) #ifdef USE_THREADS int res; #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_check_no_locked_of_type(ERTS_LC_FLG_LT_RWMUTEX); + erts_lc_check_no_locked_of_type(ERTS_LOCK_TYPE_RWMUTEX); #endif res = ethr_rwmutex_set_reader_group(no); if (res != 0) @@ -2478,57 +2423,32 @@ erts_rwmtx_set_reader_group(int no) } ERTS_GLB_INLINE void -erts_rwmtx_init_opt_x(erts_rwmtx_t *rwmtx, - erts_rwmtx_opt_t *opt, - char *name, - Eterm extra) -{ +erts_rwmtx_init_opt(erts_rwmtx_t *rwmtx, erts_rwmtx_opt_t *opt, + char *name, Eterm extra, erts_lock_flags_t flags) { #ifdef USE_THREADS int res = ethr_rwmutex_init_opt(&rwmtx->rwmtx, opt); - if (res != 0) - erts_thr_fatal_error(res, "initialize rwmutex"); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock_x(&rwmtx->lc, name, ERTS_LC_FLG_LT_RWMUTEX, extra); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - if (name && name[0] == '\0') - erts_lcnt_init_lock_x(&rwmtx->lcnt, NULL, ERTS_LCNT_LT_RWMUTEX, extra); - else - erts_lcnt_init_lock_x(&rwmtx->lcnt, name, ERTS_LCNT_LT_RWMUTEX, extra); -#endif -#endif -} + if (res != 0) { + erts_thr_fatal_error(res, "initialize rwmutex"); + } -ERTS_GLB_INLINE void -erts_rwmtx_init_x(erts_rwmtx_t *rwmtx, - char *name, - Eterm extra) -{ - erts_rwmtx_init_opt_x(rwmtx, NULL, name, extra); -} + flags |= ERTS_LOCK_TYPE_RWMUTEX; +#ifdef DEBUG + rwmtx->flags = flags; +#endif -ERTS_GLB_INLINE void -erts_rwmtx_init_opt(erts_rwmtx_t *rwmtx, - erts_rwmtx_opt_t *opt, - char *name) -{ -#ifdef USE_THREADS - int res = ethr_rwmutex_init_opt(&rwmtx->rwmtx, opt); - if (res != 0) - erts_thr_fatal_error(res, "initialize rwmutex"); #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock(&rwmtx->lc, name, ERTS_LC_FLG_LT_RWMUTEX); + erts_lc_init_lock_x(&rwmtx->lc, name, flags, extra); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init_lock(&rwmtx->lcnt, name, ERTS_LCNT_LT_RWMUTEX); -#endif + erts_lcnt_init_ref_x(&rwmtx->lcnt, name, extra, flags); #endif +#endif /* USE_THREADS */ } ERTS_GLB_INLINE void -erts_rwmtx_init(erts_rwmtx_t *rwmtx, char *name) -{ - erts_rwmtx_init_opt(rwmtx, NULL, name); +erts_rwmtx_init(erts_rwmtx_t *rwmtx, char *name, Eterm extra, + erts_lock_flags_t flags) { + erts_rwmtx_init_opt(rwmtx, NULL, name, extra, flags); } ERTS_GLB_INLINE void @@ -2536,11 +2456,14 @@ erts_rwmtx_destroy(erts_rwmtx_t *rwmtx) { #ifdef USE_THREADS int res; + + ASSERT(!(rwmtx->flags & ERTS_LOCK_FLAGS_PROPERTY_STATIC)); + #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_destroy_lock(&rwmtx->lc); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_destroy_lock(&rwmtx->lcnt); + erts_lcnt_uninstall(&rwmtx->lcnt); #endif res = ethr_rwmutex_destroy(&rwmtx->rwmtx); if (res != 0) { @@ -2568,7 +2491,7 @@ erts_rwmtx_tryrlock(erts_rwmtx_t *rwmtx) int res; #ifdef ERTS_ENABLE_LOCK_CHECK - if (erts_lc_trylock_force_busy_flg(&rwmtx->lc, ERTS_LC_FLG_LO_READ)) + if (erts_lc_trylock_force_busy_flg(&rwmtx->lc, ERTS_LOCK_OPTIONS_READ)) return EBUSY; /* Make sure caller can handle the situation without causing a lock order violation */ #endif @@ -2577,13 +2500,13 @@ erts_rwmtx_tryrlock(erts_rwmtx_t *rwmtx) #ifdef ERTS_ENABLE_LOCK_CHECK #ifdef ERTS_ENABLE_LOCK_POSITION - erts_lc_trylock_flg_x(res == 0, &rwmtx->lc, ERTS_LC_FLG_LO_READ,file,line); + erts_lc_trylock_flg_x(res == 0, &rwmtx->lc, ERTS_LOCK_OPTIONS_READ,file,line); #else - erts_lc_trylock_flg(res == 0, &rwmtx->lc, ERTS_LC_FLG_LO_READ); + erts_lc_trylock_flg(res == 0, &rwmtx->lc, ERTS_LOCK_OPTIONS_READ); #endif #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_trylock_opt(&rwmtx->lcnt, res, ERTS_LCNT_LO_READ); + erts_lcnt_trylock_opt(&rwmtx->lcnt, res, ERTS_LOCK_OPTIONS_READ); #endif return res; @@ -2602,13 +2525,13 @@ erts_rwmtx_rlock(erts_rwmtx_t *rwmtx) #ifdef USE_THREADS #ifdef ERTS_ENABLE_LOCK_CHECK #ifdef ERTS_ENABLE_LOCK_POSITION - erts_lc_lock_flg_x(&rwmtx->lc, ERTS_LC_FLG_LO_READ,file,line); + erts_lc_lock_flg_x(&rwmtx->lc, ERTS_LOCK_OPTIONS_READ,file,line); #else - erts_lc_lock_flg(&rwmtx->lc, ERTS_LC_FLG_LO_READ); + erts_lc_lock_flg(&rwmtx->lc, ERTS_LOCK_OPTIONS_READ); #endif #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_lock_opt(&rwmtx->lcnt, ERTS_LCNT_LO_READ); + erts_lcnt_lock_opt(&rwmtx->lcnt, ERTS_LOCK_OPTIONS_READ); #endif ethr_rwmutex_rlock(&rwmtx->rwmtx); #ifdef ERTS_ENABLE_LOCK_COUNT @@ -2622,10 +2545,10 @@ erts_rwmtx_runlock(erts_rwmtx_t *rwmtx) { #ifdef USE_THREADS #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_unlock_flg(&rwmtx->lc, ERTS_LC_FLG_LO_READ); + erts_lc_unlock_flg(&rwmtx->lc, ERTS_LOCK_OPTIONS_READ); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_unlock_opt(&rwmtx->lcnt, ERTS_LCNT_LO_READ); + erts_lcnt_unlock_opt(&rwmtx->lcnt, ERTS_LOCK_OPTIONS_READ); #endif ethr_rwmutex_runlock(&rwmtx->rwmtx); #endif @@ -2643,7 +2566,7 @@ erts_rwmtx_tryrwlock(erts_rwmtx_t *rwmtx) int res; #ifdef ERTS_ENABLE_LOCK_CHECK - if (erts_lc_trylock_force_busy_flg(&rwmtx->lc, ERTS_LC_FLG_LO_READ_WRITE)) + if (erts_lc_trylock_force_busy_flg(&rwmtx->lc, ERTS_LOCK_OPTIONS_RDWR)) return EBUSY; /* Make sure caller can handle the situation without causing a lock order violation */ #endif @@ -2652,13 +2575,13 @@ erts_rwmtx_tryrwlock(erts_rwmtx_t *rwmtx) #ifdef ERTS_ENABLE_LOCK_CHECK #ifdef ERTS_ENABLE_LOCK_POSITION - erts_lc_trylock_flg_x(res == 0, &rwmtx->lc, ERTS_LC_FLG_LO_READ_WRITE,file,line); + erts_lc_trylock_flg_x(res == 0, &rwmtx->lc, ERTS_LOCK_OPTIONS_RDWR,file,line); #else - erts_lc_trylock_flg(res == 0, &rwmtx->lc, ERTS_LC_FLG_LO_READ_WRITE); + erts_lc_trylock_flg(res == 0, &rwmtx->lc, ERTS_LOCK_OPTIONS_RDWR); #endif #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_trylock_opt(&rwmtx->lcnt, res, ERTS_LCNT_LO_READ_WRITE); + erts_lcnt_trylock_opt(&rwmtx->lcnt, res, ERTS_LOCK_OPTIONS_RDWR); #endif return res; @@ -2677,13 +2600,13 @@ erts_rwmtx_rwlock(erts_rwmtx_t *rwmtx) #ifdef USE_THREADS #ifdef ERTS_ENABLE_LOCK_CHECK #ifdef ERTS_ENABLE_LOCK_POSITION - erts_lc_lock_flg_x(&rwmtx->lc, ERTS_LC_FLG_LO_READ_WRITE,file,line); + erts_lc_lock_flg_x(&rwmtx->lc, ERTS_LOCK_OPTIONS_RDWR,file,line); #else - erts_lc_lock_flg(&rwmtx->lc, ERTS_LC_FLG_LO_READ_WRITE); + erts_lc_lock_flg(&rwmtx->lc, ERTS_LOCK_OPTIONS_RDWR); #endif #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_lock_opt(&rwmtx->lcnt, ERTS_LCNT_LO_READ_WRITE); + erts_lcnt_lock_opt(&rwmtx->lcnt, ERTS_LOCK_OPTIONS_RDWR); #endif ethr_rwmutex_rwlock(&rwmtx->rwmtx); #ifdef ERTS_ENABLE_LOCK_COUNT @@ -2697,10 +2620,10 @@ erts_rwmtx_rwunlock(erts_rwmtx_t *rwmtx) { #ifdef USE_THREADS #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_unlock_flg(&rwmtx->lc, ERTS_LC_FLG_LO_READ_WRITE); + erts_lc_unlock_flg(&rwmtx->lc, ERTS_LOCK_OPTIONS_RDWR); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_unlock_opt(&rwmtx->lcnt, ERTS_LCNT_LO_READ_WRITE); + erts_lcnt_unlock_opt(&rwmtx->lcnt, ERTS_LOCK_OPTIONS_RDWR); #endif ethr_rwmutex_rwunlock(&rwmtx->rwmtx); #endif @@ -2738,7 +2661,8 @@ erts_lc_rwmtx_is_rlocked(erts_rwmtx_t *mtx) #if defined(USE_THREADS) && defined(ERTS_ENABLE_LOCK_CHECK) int res; erts_lc_lock_t lc = mtx->lc; - lc.flags = ERTS_LC_FLG_LO_READ; + lc.flags = ERTS_LOCK_TYPE_RWMUTEX; + lc.taken_options = ERTS_LOCK_OPTIONS_READ; erts_lc_have_locks(&res, &lc, 1); return res; #else @@ -2752,7 +2676,8 @@ erts_lc_rwmtx_is_rwlocked(erts_rwmtx_t *mtx) #if defined(USE_THREADS) && defined(ERTS_ENABLE_LOCK_CHECK) int res; erts_lc_lock_t lc = mtx->lc; - lc.flags = ERTS_LC_FLG_LO_READ|ERTS_LC_FLG_LO_WRITE; + lc.flags = ERTS_LOCK_TYPE_RWMUTEX; + lc.taken_options = ERTS_LOCK_OPTIONS_RDWR; erts_lc_have_locks(&res, &lc, 1); return res; #else @@ -3085,59 +3010,26 @@ erts_no_atomic64_read_bset(erts_no_atomic64_t *var, /* spinlock */ ERTS_GLB_INLINE void -erts_spinlock_init_x(erts_spinlock_t *lock, char *name, Eterm extra) +erts_spinlock_init(erts_spinlock_t *lock, char *name, Eterm extra, erts_lock_flags_t flags) { #ifdef USE_THREADS int res = ethr_spinlock_init(&lock->slck); - if (res) - erts_thr_fatal_error(res, "init spinlock"); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock_x(&lock->lc, name, ERTS_LC_FLG_LT_SPINLOCK, extra); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init_lock_x(&lock->lcnt, name, ERTS_LCNT_LT_SPINLOCK, extra); -#endif -#else - (void)lock; -#endif -} + if (res) { + erts_thr_fatal_error(res, "init spinlock"); + } -ERTS_GLB_INLINE void -erts_spinlock_init_x_opt(erts_spinlock_t *lock, char *name, Eterm extra, - Uint16 opt) -{ -#ifdef USE_THREADS - int res = ethr_spinlock_init(&lock->slck); - if (res) - erts_thr_fatal_error(res, "init spinlock"); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock_x(&lock->lc, name, ERTS_LC_FLG_LT_SPINLOCK, extra); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init_lock_x(&lock->lcnt, name, ERTS_LCNT_LT_SPINLOCK|opt, extra); + flags |= ERTS_LOCK_TYPE_SPINLOCK; +#ifdef DEBUG + lock->flags = flags; #endif -#else - (void)lock; -#endif -} - -ERTS_GLB_INLINE void -erts_spinlock_init(erts_spinlock_t *lock, char *name) -{ -#ifdef USE_THREADS - int res = ethr_spinlock_init(&lock->slck); - if (res) - erts_thr_fatal_error(res, "init spinlock"); #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock(&lock->lc, name, ERTS_LC_FLG_LT_SPINLOCK); + erts_lc_init_lock_x(&lock->lc, name, flags, extra); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init_lock(&lock->lcnt, name, ERTS_LCNT_LT_SPINLOCK); -#endif -#else - (void)lock; + erts_lcnt_init_ref_x(&lock->lcnt, name, extra, flags); #endif +#endif /* USE_THREADS */ } ERTS_GLB_INLINE void @@ -3145,11 +3037,14 @@ erts_spinlock_destroy(erts_spinlock_t *lock) { #ifdef USE_THREADS int res; + + ASSERT(!(lock->flags & ERTS_LOCK_FLAGS_PROPERTY_STATIC)); + #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_destroy_lock(&lock->lc); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_destroy_lock(&lock->lcnt); + erts_lcnt_uninstall(&lock->lcnt); #endif res = ethr_spinlock_destroy(&lock->slck); if (res != 0) { @@ -3217,7 +3112,8 @@ erts_lc_spinlock_is_locked(erts_spinlock_t *lock) #if defined(USE_THREADS) && defined(ERTS_ENABLE_LOCK_CHECK) int res; erts_lc_lock_t lc = lock->lc; - lc.flags = 0; + lc.flags = ERTS_LOCK_TYPE_SPINLOCK; + lc.taken_options = 0; erts_lc_have_locks(&res, &lc, 1); return res; #else @@ -3228,39 +3124,26 @@ erts_lc_spinlock_is_locked(erts_spinlock_t *lock) /* rwspinlock */ ERTS_GLB_INLINE void -erts_rwlock_init_x(erts_rwlock_t *lock, char *name, Eterm extra) +erts_rwlock_init(erts_rwlock_t *lock, char *name, Eterm extra, erts_lock_flags_t flags) { #ifdef USE_THREADS int res = ethr_rwlock_init(&lock->rwlck); - if (res) - erts_thr_fatal_error(res, "init rwlock"); -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock_x(&lock->lc, name, ERTS_LC_FLG_LT_RWSPINLOCK, extra); -#endif -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init_lock_x(&lock->lcnt, name, ERTS_LCNT_LT_RWSPINLOCK, extra); -#endif -#else - (void)lock; + if (res) { + erts_thr_fatal_error(res, "init rwlock"); + } + + flags |= ERTS_LOCK_TYPE_RWSPINLOCK; +#ifdef DEBUG + lock->flags = flags; #endif -} -ERTS_GLB_INLINE void -erts_rwlock_init(erts_rwlock_t *lock, char *name) -{ -#ifdef USE_THREADS - int res = ethr_rwlock_init(&lock->rwlck); - if (res) - erts_thr_fatal_error(res, "init rwlock"); #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_init_lock(&lock->lc, name, ERTS_LC_FLG_LT_RWSPINLOCK); + erts_lc_init_lock_x(&lock->lc, name, flags, extra); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init_lock(&lock->lcnt, name, ERTS_LCNT_LT_RWSPINLOCK); -#endif -#else - (void)lock; + erts_lcnt_init_ref_x(&lock->lcnt, name, extra, flags); #endif +#endif /* USE_THREADS */ } ERTS_GLB_INLINE void @@ -3268,11 +3151,14 @@ erts_rwlock_destroy(erts_rwlock_t *lock) { #ifdef USE_THREADS int res; + + ASSERT(!(lock->flags & ERTS_LOCK_FLAGS_PROPERTY_STATIC)); + #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_destroy_lock(&lock->lc); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_destroy_lock(&lock->lcnt); + erts_lcnt_uninstall(&lock->lcnt); #endif res = ethr_rwlock_destroy(&lock->rwlck); if (res != 0) { @@ -3296,10 +3182,10 @@ erts_read_unlock(erts_rwlock_t *lock) { #ifdef USE_THREADS #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_unlock_flg(&lock->lc, ERTS_LC_FLG_LO_READ); + erts_lc_unlock_flg(&lock->lc, ERTS_LOCK_OPTIONS_READ); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_unlock_opt(&lock->lcnt, ERTS_LCNT_LO_READ); + erts_lcnt_unlock_opt(&lock->lcnt, ERTS_LOCK_OPTIONS_READ); #endif ethr_read_unlock(&lock->rwlck); #else @@ -3317,13 +3203,13 @@ erts_read_lock(erts_rwlock_t *lock) #ifdef USE_THREADS #ifdef ERTS_ENABLE_LOCK_CHECK #ifdef ERTS_ENABLE_LOCK_POSITION - erts_lc_lock_flg_x(&lock->lc, ERTS_LC_FLG_LO_READ,file,line); + erts_lc_lock_flg_x(&lock->lc, ERTS_LOCK_OPTIONS_READ,file,line); #else - erts_lc_lock_flg(&lock->lc, ERTS_LC_FLG_LO_READ); + erts_lc_lock_flg(&lock->lc, ERTS_LOCK_OPTIONS_READ); #endif #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_lock_opt(&lock->lcnt, ERTS_LCNT_LO_READ); + erts_lcnt_lock_opt(&lock->lcnt, ERTS_LOCK_OPTIONS_READ); #endif ethr_read_lock(&lock->rwlck); #ifdef ERTS_ENABLE_LOCK_COUNT @@ -3339,10 +3225,10 @@ erts_write_unlock(erts_rwlock_t *lock) { #ifdef USE_THREADS #ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_unlock_flg(&lock->lc, ERTS_LC_FLG_LO_READ_WRITE); + erts_lc_unlock_flg(&lock->lc, ERTS_LOCK_OPTIONS_RDWR); #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_unlock_opt(&lock->lcnt, ERTS_LCNT_LO_READ_WRITE); + erts_lcnt_unlock_opt(&lock->lcnt, ERTS_LOCK_OPTIONS_RDWR); #endif ethr_write_unlock(&lock->rwlck); #else @@ -3360,13 +3246,13 @@ erts_write_lock(erts_rwlock_t *lock) #ifdef USE_THREADS #ifdef ERTS_ENABLE_LOCK_CHECK #ifdef ERTS_ENABLE_LOCK_POSITION - erts_lc_lock_flg_x(&lock->lc, ERTS_LC_FLG_LO_READ_WRITE,file,line); + erts_lc_lock_flg_x(&lock->lc, ERTS_LOCK_OPTIONS_RDWR,file,line); #else - erts_lc_lock_flg(&lock->lc, ERTS_LC_FLG_LO_READ_WRITE); + erts_lc_lock_flg(&lock->lc, ERTS_LOCK_OPTIONS_RDWR); #endif #endif #ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_lock_opt(&lock->lcnt, ERTS_LCNT_LO_READ_WRITE); + erts_lcnt_lock_opt(&lock->lcnt, ERTS_LOCK_OPTIONS_RDWR); #endif ethr_write_lock(&lock->rwlck); #ifdef ERTS_ENABLE_LOCK_COUNT @@ -3383,7 +3269,8 @@ erts_lc_rwlock_is_rlocked(erts_rwlock_t *lock) #if defined(USE_THREADS) && defined(ERTS_ENABLE_LOCK_CHECK) int res; erts_lc_lock_t lc = lock->lc; - lc.flags = ERTS_LC_FLG_LO_READ; + lc.flags = ERTS_LOCK_TYPE_RWSPINLOCK; + lc.taken_options = ERTS_LOCK_OPTIONS_READ; erts_lc_have_locks(&res, &lc, 1); return res; #else @@ -3397,7 +3284,8 @@ erts_lc_rwlock_is_rwlocked(erts_rwlock_t *lock) #if defined(USE_THREADS) && defined(ERTS_ENABLE_LOCK_CHECK) int res; erts_lc_lock_t lc = lock->lc; - lc.flags = ERTS_LC_FLG_LO_READ|ERTS_LC_FLG_LO_WRITE; + lc.flags = ERTS_LOCK_TYPE_RWSPINLOCK; + lc.taken_options = ERTS_LOCK_OPTIONS_RDWR; erts_lc_have_locks(&res, &lc, 1); return res; #else @@ -3461,6 +3349,15 @@ ERTS_GLB_INLINE void erts_tse_return(erts_tse_t *ep) #endif } +ERTS_GLB_INLINE void erts_tse_prepare_timed(erts_tse_t *ep) +{ +#ifdef USE_THREADS + int res = ethr_event_prepare_timed(&((ethr_ts_event *) ep)->event); + if (res != 0) + erts_thr_fatal_error(res, "prepare timed"); +#endif +} + ERTS_GLB_INLINE void erts_tse_set(erts_tse_t *ep) { #ifdef USE_THREADS @@ -3478,7 +3375,11 @@ ERTS_GLB_INLINE void erts_tse_reset(erts_tse_t *ep) ERTS_GLB_INLINE int erts_tse_wait(erts_tse_t *ep) { #ifdef USE_THREADS - return ethr_event_wait(&((ethr_ts_event *) ep)->event); + int res; + ERTS_MSACC_PUSH_AND_SET_STATE(ERTS_MSACC_STATE_SLEEP); + res = ethr_event_wait(&((ethr_ts_event *) ep)->event); + ERTS_MSACC_POP_STATE(); + return res; #else return ENOTSUP; #endif @@ -3487,7 +3388,11 @@ ERTS_GLB_INLINE int erts_tse_wait(erts_tse_t *ep) ERTS_GLB_INLINE int erts_tse_swait(erts_tse_t *ep, int spincount) { #ifdef USE_THREADS - return ethr_event_swait(&((ethr_ts_event *) ep)->event, spincount); + int res; + ERTS_MSACC_PUSH_AND_SET_STATE(ERTS_MSACC_STATE_SLEEP); + res = ethr_event_swait(&((ethr_ts_event *) ep)->event, spincount); + ERTS_MSACC_POP_STATE(); + return res; #else return ENOTSUP; #endif @@ -3496,8 +3401,12 @@ ERTS_GLB_INLINE int erts_tse_swait(erts_tse_t *ep, int spincount) ERTS_GLB_INLINE int erts_tse_twait(erts_tse_t *ep, Sint64 tmo) { #ifdef USE_THREADS - return ethr_event_twait(&((ethr_ts_event *) ep)->event, - (ethr_sint64_t) tmo); + int res; + ERTS_MSACC_PUSH_AND_SET_STATE(ERTS_MSACC_STATE_SLEEP); + res = ethr_event_twait(&((ethr_ts_event *) ep)->event, + (ethr_sint64_t) tmo); + ERTS_MSACC_POP_STATE(); + return res; #else return ENOTSUP; #endif @@ -3506,9 +3415,13 @@ ERTS_GLB_INLINE int erts_tse_twait(erts_tse_t *ep, Sint64 tmo) ERTS_GLB_INLINE int erts_tse_stwait(erts_tse_t *ep, int spincount, Sint64 tmo) { #ifdef USE_THREADS - return ethr_event_stwait(&((ethr_ts_event *) ep)->event, - spincount, - (ethr_sint64_t) tmo); + int res; + ERTS_MSACC_PUSH_AND_SET_STATE(ERTS_MSACC_STATE_SLEEP); + res = ethr_event_stwait(&((ethr_ts_event *) ep)->event, + spincount, + (ethr_sint64_t) tmo); + ERTS_MSACC_POP_STATE(); + return res; #else return ENOTSUP; #endif |