lkml.org 
[lkml]   [1999]   [Sep]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subjectrecursive locks in kernel?

Hi,

Do we have recursive locks (like the one described in the book "Unix
Internals" by Uresh Vahalia (Section 7.10.2) in linux 2.2.9 kernel (or any
later kernel)?

Recursive locks are useful when we have a lower level function which is called by many
higher level functions with some of them locking some data before calling this function
and some of them not. Now the problem arises if this lower level function
also wants to lock the same data because it does not know whether the data is
already locked by some higher level function or not. If it just locks it
blindly then this could lead to a deadlock.

For example:

The function f3 might get called via two diffrent call sequences like shown below:
In the second sequence, the caller f1 locks X and in the first it doesn't. Since f3 does not
know whether X is locked or not, it tries to lock it (in second sequence) resulting in deadlock.

calls calls
f1 -----> f2 -----> f3, f3 locks X successfully.


calls calls
f1A(locks X) -----> f2 -----> f3, f3 tries to lock X resulting in deadlock.

One solution to above probelm is to pass an argument to f3 via f2 which will hint
f3 on whether to lock or not. But this is awkward and also what if there are
more than one locks to consider. Here recursive locks will be a better solution.


One implementation of recursive locks:
--------------------------------------

typedef struct recursive_lock {
int data_to_lock; /* 1 means locked, 0 means free */
pid_t owner_pid; /* owner process of the lock */
int lock_count; /* no. of recursive instances of the lock held by the owner */
}recursive_lock_t;


get_recursive_lock(recursive_lock_t *r)
{
if(atomic_test_and_set(&r->data_to_lock) == 0) { /* if lock is free */
r->data_to_lock = 1; /* lock it */
r->owner_pid = current->pid; /* make ourself as the owner */
r->lock_count = 1; /* first instance of this lock */
return;
}
/* data is locked ; check if we are already the owner */
if(r->owner_pid == current->pid) { /* if held by the same process */
r->lock_count ++; /* return with success */
return;
}
/* lock is owned by some other process. So busy wait */
while(atomic_test_and_set(&r->data_to_lock) != 0) { /* if already locked */
while(r->data_to_lock != 0) /* busy wait till unlocked */
;
}
r->owner_pid = current->pid; /* make ourself as the owner */
r->lock_count = 1; /* first instance of this lock */
}


release_recursive_lock(recursive_lock_t *r)
{
r->lock_count --;
if(r->lock_count == 0) { /* last lock */
r->owner_pid = -1; /* no one owns this lock */
r->data_to_lock = 0; /* free the lock */
}
}

expecting comments from you ,
- Sushil.






-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:54    [W:0.061 / U:0.664 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site