lkml.org 
[lkml]   [1999]   [Nov]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [Patch] shm bug introduced with pagecache in 2.3.11
Alexander Viro wrote:
>
> IIRC, there was an implementation and analysis in Vahalia. Streamlining it
> shouldn't be too hard (I have something like that in AFFS patches, but
> there I didn't need {up,down}_write and did need upgrade/downgrade. IOW,
> writrs always started as readers).

I never figured out how to upgrade a reader to a writer:
what if 2 threads acquire the lock 'read', and and both decide to
promote to "write"?
Could you send me the patch?

I have attached below a pseudo-code version of a rw-mutex, what do you
think?
acquire_{shared,exclusive} should be possible with 2 asm instructions
inline
release_exclusive with 3 asm instructions inline

--
Manfred
>>>>>>>>>>>>>>

struct rw_mutex
{
rwlock_t rwl;
wait_queue_head_t wait;
int wake_me_up;
};

/* TODO: add asm, add TASK_EXCLUSIVE for acquire_exclusive,
* check if a waiting writer should stop new readers.
* optimize release_shared
*/

void rw_mutex_init(struct rw_mutex* rwm)
{
init_wait_queue_head(&rwm->wait);
rwm->wake_me_up = 0;
rwm->rwl = RW_LOCK_UNLOCKED;
}

/* 2 asm instructions inline */
void acquire_exclusive(struct rw_mutex* rwm)
{
if(!write_lock_trylock(&rwm->rwl)) {
DECLARE_WAIT_QUEUE(wait,current);
add_wait_queue(wait,&rwm->wait);
for(;;) {
current->state = TASK_UNINTERRUPTIBLE;
rwm->wake_me_up = 1;
if(write_lock_trylock(&rwm->rwl)) {
break;
}
schedule();
}
current->state = TASK_RUNNING;
remove_wait_queue(wait,&rwm->wait);
}
}

/* 2 asm instruction inline */
void acquire_shared(struct rw_mutex* rwm)
{
if(!read_lock_trylock(&rwm->rwl)) {
DECLARE_WAIT_QUEUE(wait,current);
add_wait_queue(wait,&rwm->wait);
for(;;) {
current->state = TASK_UNINTERRUPTIBLE;
rwm->wake_me_up = 1;
if(read_lock_trylock(&rwm->rwl)) {
break;
}
schedule();
}
current->state = TASK_RUNNING;
remove_wait_queue(wait,&rwm->wait);
}
}

/* 3 asm instructions */
void release_exclusive(struct rw_mutex* rwm)
{
read_unlock(&rwm->rwl);
if(rwm->wake_me_up) {
rwm->wake_me_up = 0;
wake_up(&rwm->wait);
}
}
void release_shared(struct rw_mutex* rwm)
{
read_unlock(&rwm->rwl);
if(rwm->wake_me_up) {
/* FIXME: is this a race? */
if(rwm->rwl != 0)
return;
rwm->wake_me_up = 0;
wake_up(&rwm->wait);
}
}
>>>>>>>>>>>>>>>>>


-
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:55    [W:0.060 / U:0.584 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site