[lkml]   [2003]   [May]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Subjectrecursive spinlocks. Shoot.

    Here's a before-breakfast implementation of a recursive spinlock. That
    is, the same thread can "take" the spinlock repeatedly. This is crude -
    I just want to focus some attention on the issue (while I go out and
    have breakfast :'E).

    The idea is to implement trylock correctly, and then get lock and
    unlock from that via the standard algebra. lock is a loop doing
    a trylock until it succeeds. We emerge from a successful trylock
    with the lock notionally held.

    The "spinlock" is a register of the current pid, plus a recursion
    counter, with atomic access. The pid is either -1 (unset, count is
    zero) or some decent value (count is positive).

    The trylock will succeed and set the pid if it is currently unset. It
    will succeed if the pid matches ours, and increment the count of

    Unlock just decrements the count. When we've unlocked enough times,
    somebody else can take the lock.

    The objection to this scheme that I have is

    1) its notion of identity is limited to the pid, which is crude
    2) it doesn't detect dead holders of the lock, which would be nice
    3) it should probably be done in assembler, using whatever trick
    rwlocks use
    4) it doesn't actually use a real spinlock to "hold" the lock, which
    makes me nervous.

    typedef struct recursive_spinlock {
    spinlock_t lock;
    int pid;
    int count;
    } recursive_spinlock_t;

    int recursive_spin_trylock(recursive_spinlock_t *lock) {

    if (lock->count <= 0) {
    // greenfield site
    lock->pid = current->pid;
    lock->count = 1;
    return 0;
    // somebody has the lock
    if (lock->pid == current->pid) {
    // it was us! return ok`
    return 0;
    // somebody has the lock and it's not us! return fail
    return 1;

    void recursive_spin_lock(recursive_spinlock_t *lock) {
    while (recursive_spin_trylock(lock) != 0);

    void recursive_spin_unlock(recursive_spinlock_t *lock) {
    if (--lock->count <= 0)
    lock->count = 0;

    void recursive_spinlock_init(recursive_spinlock_t *lock) {
    lock->pid = -1;
    lock->count = 0;

    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2005-03-22 13:35    [W:0.022 / U:74.456 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site