patch-2.4.27 linux-2.4.27/lib/rwsem-spinlock.c
Next file: linux-2.4.27/lib/rwsem.c
Previous file: linux-2.4.27/kernel/sysctl.c
Back to the patch index
Back to the overall index
- Lines: 99
- Date:
2004-08-07 16:26:06.505422835 -0700
- Orig file:
linux-2.4.26/lib/rwsem-spinlock.c
- Orig date:
2002-11-28 15:53:15.000000000 -0800
diff -urN linux-2.4.26/lib/rwsem-spinlock.c linux-2.4.27/lib/rwsem-spinlock.c
@@ -9,6 +9,7 @@
*/
#include <linux/rwsem.h>
#include <linux/sched.h>
+#include <linux/mm.h>
#include <linux/module.h>
struct rwsem_waiter {
@@ -52,6 +53,7 @@
static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem)
{
struct rwsem_waiter *waiter;
+ struct task_struct *tsk;
int woken;
rwsemtrace(sem,"Entering __rwsem_do_wake");
@@ -64,8 +66,11 @@
if (waiter->flags & RWSEM_WAITING_FOR_WRITE) {
sem->activity = -1;
list_del(&waiter->list);
- waiter->flags = 0;
- wake_up_process(waiter->task);
+ tsk = waiter->task;
+ mb();
+ waiter->task = NULL;
+ wake_up_process(tsk);
+ free_task_struct(tsk);
goto out;
}
@@ -73,8 +78,11 @@
woken = 0;
do {
list_del(&waiter->list);
- waiter->flags = 0;
- wake_up_process(waiter->task);
+ tsk = waiter->task;
+ mb();
+ waiter->task = NULL;
+ wake_up_process(tsk);
+ free_task_struct(tsk);
woken++;
if (list_empty(&sem->wait_list))
break;
@@ -94,14 +102,18 @@
static inline struct rw_semaphore *__rwsem_wake_one_writer(struct rw_semaphore *sem)
{
struct rwsem_waiter *waiter;
+ struct task_struct *tsk;
sem->activity = -1;
waiter = list_entry(sem->wait_list.next,struct rwsem_waiter,list);
list_del(&waiter->list);
- waiter->flags = 0;
- wake_up_process(waiter->task);
+ tsk = waiter->task;
+ mb();
+ waiter->task = NULL;
+ wake_up_process(tsk);
+ free_task_struct(tsk);
return sem;
}
@@ -130,6 +142,7 @@
/* set up my own style of waitqueue */
waiter.task = tsk;
waiter.flags = RWSEM_WAITING_FOR_READ;
+ get_task_struct(tsk);
list_add_tail(&waiter.list,&sem->wait_list);
@@ -138,7 +151,7 @@
/* wait to be given the lock */
for (;;) {
- if (!waiter.flags)
+ if (!waiter.task)
break;
schedule();
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
@@ -198,6 +211,7 @@
/* set up my own style of waitqueue */
waiter.task = tsk;
waiter.flags = RWSEM_WAITING_FOR_WRITE;
+ get_task_struct(tsk);
list_add_tail(&waiter.list,&sem->wait_list);
@@ -206,7 +220,7 @@
/* wait to be given the lock */
for (;;) {
- if (!waiter.flags)
+ if (!waiter.task)
break;
schedule();
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)