コード例 #1
0
/*
 * Return values:
 * 0   : try and take the lock again in local memory
 * -ret: return -ret
 */
int
lock_take_contention(cos_lock_t *l, union cos_lock_atomic_struct *result,
                     union cos_lock_atomic_struct *prev_val, u16_t owner)
{
    int     lock_id = l->lock_id;
    spdid_t spdid   = cos_spd_id();
    int ret;

    if (lock_component_pretake(spdid, lock_id, owner)) return -1;

    /* Must access memory (be volatile) as we want
     * to detect changes here */
    if (owner != l->atom.c.owner) return 0;
    /* Mark the lock as contested */
    if (!l->atom.c.contested) {
        result->c.contested = 1;
        result->c.owner     = owner;
        if (!cos_cas((unsigned long*)&l->atom.v, prev_val->v, result->v)) return 0;
        assert(l->atom.c.contested);
    }
    /* Note if a 1 is returned, there is a
     * generation mismatch, and we just want to
     * try and take the lock again anyway */
    ret = lock_component_take(spdid, lock_id, owner);
    return ret < 0 ? ret : 0;
}
コード例 #2
0
static inline int block_ser_if_block_track_lock_component_take(spdid_t spdid,
        ul_t lock_id,
        u32_t thd_id)
{
    int ret = 0;
    struct track_block tb;	// track on stack

    do {
        if (sched_component_take(cos_spd_id()))
            BUG();
    } while (0);

    if (unlikely(!tracking_block_list[spdid].next)) {
        INIT_LIST(&tracking_block_list[spdid], next, prev);
    }
    INIT_LIST(&tb, next, prev);
    tb.lock_id = lock_id;
    ADD_LIST(&tracking_block_list[spdid], &tb, next, prev);

    do {
        if (sched_component_release(cos_spd_id()))
            BUG();
    } while (0);

    ret = lock_component_take(spdid, lock_id, thd_id);

    do {
        if (sched_component_take(cos_spd_id()))
            BUG();
    } while (0);

    REM_LIST(&tb, next, prev);

    do {
        if (sched_component_release(cos_spd_id()))
            BUG();
    } while (0);

    return ret;
}