void erts_lc_lock_flg(erts_lc_lock_t *lck, Uint16 op_flags) { erts_lc_locked_locks_t *l_lcks; erts_lc_locked_lock_t *l_lck; if (lck->inited != ERTS_LC_INITITALIZED) uninitialized_lock(); if (lck->id < 0) return; l_lcks = make_my_locked_locks(); l_lck = new_locked_lock(lck, op_flags); if (!l_lcks->locked.last) { ASSERT(!l_lcks->locked.first); l_lcks->locked.last = l_lcks->locked.first = l_lck; } else if (l_lcks->locked.last->id < lck->id || (l_lcks->locked.last->id == lck->id && l_lcks->locked.last->extra < lck->extra)) { if (LOCK_IS_TYPE_ORDER_VIOLATION(lck->flags, l_lcks->locked.last->flags)) type_order_violation("locking ", l_lcks, lck); l_lck->prev = l_lcks->locked.last; l_lcks->locked.last->next = l_lck; l_lcks->locked.last = l_lck; } else if (l_lcks->locked.last->id == lck->id && l_lcks->locked.last->extra == lck->extra) lock_twice("Locking", l_lcks, lck, op_flags); else lock_order_violation(l_lcks, lck); }
void erts_lc_unrequire_lock_flg(erts_lc_lock_t *lck, erts_lock_options_t options) { lc_thread_t *thr = make_my_locked_locks(); lc_locked_lock_t *ll = thr->locked.first; if (!find_lock(&ll, lck)) required_not_locked(thr, lck); ll = thr->required.first; if (!find_lock(&ll, lck)) unrequire_of_not_required_lock(thr, lck); if (ll->prev) { ASSERT(thr->required.first != ll); ll->prev->next = ll->next; } else { ASSERT(thr->required.first == ll); thr->required.first = ll->next; } if (ll->next) { ASSERT(thr->required.last != ll); ll->next->prev = ll->prev; } else { ASSERT(thr->required.last == ll); thr->required.last = ll->prev; } lc_free(thr, ll); }
void erts_lc_unrequire_lock_flg(erts_lc_lock_t *lck, Uint16 op_flags) { erts_lc_locked_locks_t *l_lcks = make_my_locked_locks(); erts_lc_locked_lock_t *l_lck = l_lcks->locked.first; if (!find_lock(&l_lck, lck)) required_not_locked(l_lcks, lck); l_lck = l_lcks->required.first; if (!find_lock(&l_lck, lck)) unrequire_of_not_required_lock(l_lcks, lck); if (l_lck->prev) { ASSERT(l_lcks->required.first != l_lck); l_lck->prev->next = l_lck->next; } else { ASSERT(l_lcks->required.first == l_lck); l_lcks->required.first = l_lck->next; } if (l_lck->next) { ASSERT(l_lcks->required.last != l_lck); l_lck->next->prev = l_lck->prev; } else { ASSERT(l_lcks->required.last == l_lck); l_lcks->required.last = l_lck->prev; } lc_free((void *) l_lck); }
void erts_lc_trylock_flg_x(int locked, erts_lc_lock_t *lck, Uint16 op_flags, char *file, unsigned int line) { erts_lc_locked_locks_t *l_lcks; erts_lc_locked_lock_t *l_lck; if (lck->inited != ERTS_LC_INITITALIZED) uninitialized_lock(); if (lck->id < 0) return; l_lcks = make_my_locked_locks(); l_lck = locked ? new_locked_lock(lck, op_flags, file, line) : NULL; if (!l_lcks->locked.last) { ASSERT(!l_lcks->locked.first); if (locked) l_lcks->locked.first = l_lcks->locked.last = l_lck; } else { erts_lc_locked_lock_t *tl_lck; #if 0 /* Ok when trylocking I guess... */ if (LOCK_IS_TYPE_ORDER_VIOLATION(lck->flags, l_lcks->locked.last->flags)) type_order_violation("trylocking ", l_lcks, lck); #endif for (tl_lck = l_lcks->locked.last; tl_lck; tl_lck = tl_lck->prev) { if (tl_lck->id < lck->id || (tl_lck->id == lck->id && tl_lck->extra <= lck->extra)) { if (tl_lck->id == lck->id && tl_lck->extra == lck->extra) lock_twice("Trylocking", l_lcks, lck, op_flags); if (locked) { l_lck->next = tl_lck->next; l_lck->prev = tl_lck; if (tl_lck->next) tl_lck->next->prev = l_lck; else l_lcks->locked.last = l_lck; tl_lck->next = l_lck; } return; } } if (locked) { l_lck->next = l_lcks->locked.first; l_lcks->locked.first->prev = l_lck; l_lcks->locked.first = l_lck; } } }
void erts_lc_trylock_flg_x(int locked, erts_lc_lock_t *lck, erts_lock_options_t options, char *file, unsigned int line) { lc_thread_t *thr; lc_locked_lock_t *ll; if (lck->inited != ERTS_LC_INITITALIZED) uninitialized_lock(); if (lck->id < 0) return; thr = make_my_locked_locks(); ll = locked ? new_locked_lock(thr, lck, options, file, line) : NULL; if (!thr->locked.last) { ASSERT(!thr->locked.first); if (locked) thr->locked.first = thr->locked.last = ll; } else { lc_locked_lock_t *tl_lck; #if 0 /* Ok when trylocking I guess... */ if (LOCK_IS_TYPE_ORDER_VIOLATION(lck->flags, thr->locked.last->flags)) type_order_violation("trylocking ", thr, lck); #endif for (tl_lck = thr->locked.last; tl_lck; tl_lck = tl_lck->prev) { if (tl_lck->id < lck->id || (tl_lck->id == lck->id && tl_lck->extra <= lck->extra)) { if (tl_lck->id == lck->id && tl_lck->extra == lck->extra && lck->check_order) lock_twice("Trylocking", thr, lck, options); if (locked) { ll->next = tl_lck->next; ll->prev = tl_lck; if (tl_lck->next) tl_lck->next->prev = ll; else thr->locked.last = ll; tl_lck->next = ll; } return; } } if (locked) { ll->next = thr->locked.first; thr->locked.first->prev = ll; thr->locked.first = ll; } } }
void erts_lc_lock_flg_x(erts_lc_lock_t *lck, erts_lock_options_t options, char *file, unsigned int line) { lc_thread_t *thr; lc_locked_lock_t *new_ll; if (lck->inited != ERTS_LC_INITITALIZED) uninitialized_lock(); if (lck->id < 0) return; thr = make_my_locked_locks(); new_ll = new_locked_lock(thr, lck, options, file, line); if (!thr->locked.last) { ASSERT(!thr->locked.first); thr->locked.last = thr->locked.first = new_ll; ASSERT(0 < lck->id && lck->id < ERTS_LOCK_ORDER_SIZE); thr->matrix.m[lck->id][0] = 1; } else if (( ! lck->check_order && thr->locked.last->id == lck->id) || (thr->locked.last->id < lck->id || (thr->locked.last->id == lck->id && thr->locked.last->extra < lck->extra))) { lc_locked_lock_t* ll; if (LOCK_IS_TYPE_ORDER_VIOLATION(lck->flags, thr->locked.last->flags)) { type_order_violation("locking ", thr, lck); } ASSERT(0 < lck->id && lck->id < ERTS_LOCK_ORDER_SIZE); ll = thr->locked.last; thr->matrix.m[lck->id][ll->id] |= 1; for (ll = ll->prev; ll; ll = ll->prev) { ASSERT(0 < ll->id && ll->id < ERTS_LOCK_ORDER_SIZE); thr->matrix.m[lck->id][ll->id] |= 2; } new_ll->prev = thr->locked.last; thr->locked.last->next = new_ll; thr->locked.last = new_ll; } else if (thr->locked.last->id == lck->id && thr->locked.last->extra == lck->extra) lock_twice("Locking", thr, lck, options); else lock_order_violation(thr, lck); }
void erts_lc_require_lock_flg(erts_lc_lock_t *lck, Uint16 op_flags, char *file, unsigned int line) { erts_lc_locked_locks_t *l_lcks = make_my_locked_locks(); erts_lc_locked_lock_t *l_lck = l_lcks->locked.first; if (!find_lock(&l_lck, lck)) required_not_locked(l_lcks, lck); l_lck = new_locked_lock(lck, op_flags, file, line); if (!l_lcks->required.last) { ASSERT(!l_lcks->required.first); l_lck->next = l_lck->prev = NULL; l_lcks->required.first = l_lcks->required.last = l_lck; } else { erts_lc_locked_lock_t *l_lck2; ASSERT(l_lcks->required.first); for (l_lck2 = l_lcks->required.last; l_lck2; l_lck2 = l_lck2->prev) { if (l_lck2->id < lck->id || (l_lck2->id == lck->id && l_lck2->extra < lck->extra)) break; else if (l_lck2->id == lck->id && l_lck2->extra == lck->extra) require_twice(l_lcks, lck); } if (!l_lck2) { l_lck->next = l_lcks->required.first; l_lck->prev = NULL; l_lcks->required.first->prev = l_lck; l_lcks->required.first = l_lck; } else { l_lck->next = l_lck2->next; if (l_lck->next) { ASSERT(l_lcks->required.last != l_lck2); l_lck->next->prev = l_lck; } else { ASSERT(l_lcks->required.last == l_lck2); l_lcks->required.last = l_lck; } l_lck->prev = l_lck2; l_lck2->next = l_lck; } } }
void erts_lc_require_lock_flg(erts_lc_lock_t *lck, erts_lock_options_t options, char *file, unsigned int line) { lc_thread_t *thr = make_my_locked_locks(); lc_locked_lock_t *ll = thr->locked.first; if (!find_lock(&ll, lck)) required_not_locked(thr, lck); ll = new_locked_lock(thr, lck, options, file, line); if (!thr->required.last) { ASSERT(!thr->required.first); ll->next = ll->prev = NULL; thr->required.first = thr->required.last = ll; } else { lc_locked_lock_t *l_lck2; ASSERT(thr->required.first); for (l_lck2 = thr->required.last; l_lck2; l_lck2 = l_lck2->prev) { if (l_lck2->id < lck->id || (l_lck2->id == lck->id && l_lck2->extra < lck->extra)) break; else if (l_lck2->id == lck->id && l_lck2->extra == lck->extra) require_twice(thr, lck); } if (!l_lck2) { ll->next = thr->required.first; ll->prev = NULL; thr->required.first->prev = ll; thr->required.first = ll; } else { ll->next = l_lck2->next; if (ll->next) { ASSERT(thr->required.last != l_lck2); ll->next->prev = ll; } else { ASSERT(thr->required.last == l_lck2); thr->required.last = ll; } ll->prev = l_lck2; l_lck2->next = ll; } } }