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_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); }