diff -Nur linux-2.5.72/ipc/sem.c linux-2.5.72.sem/ipc/sem.c --- linux-2.5.72/ipc/sem.c Mon Jun 16 21:19:59 2003 +++ linux-2.5.72.sem/ipc/sem.c Wed Jun 25 20:29:56 2003 @@ -258,8 +258,7 @@ */ static int try_atomic_semop (struct sem_array * sma, struct sembuf * sops, - int nsops, struct sem_undo *un, int pid, - int do_undo) + int nsops, struct sem_undo *un, int pid) { int result, sem_op; struct sembuf *sop; @@ -289,10 +288,6 @@ curr->semval = result; } - if (do_undo) { - result = 0; - goto undo; - } sop--; while (sop >= sops) { sma->sem_base[sop->sem_num].sempid = pid; @@ -334,23 +329,14 @@ for (q = sma->sem_pending; q; q = q->next) { - if (q->status == 1) - continue; /* this one was woken up before */ - error = try_atomic_semop(sma, q->sops, q->nsops, - q->undo, q->pid, q->alter); + q->undo, q->pid); /* Does q->sleeper still need to sleep? */ if (error <= 0) { - /* Found one, wake it up */ - wake_up_process(q->sleeper); - if (error == 0 && q->alter) { - /* if q-> alter let it self try */ - q->status = 1; - return; - } q->status = error; remove_from_queue(sma,q); + wake_up_process(q->sleeper); } } } @@ -1077,7 +1063,7 @@ } else un = NULL; - error = try_atomic_semop (sma, sops, nsops, un, current->pid, 0); + error = try_atomic_semop (sma, sops, nsops, un, current->pid); if (error <= 0) goto update; @@ -1090,7 +1076,6 @@ queue.nsops = nsops; queue.undo = un; queue.pid = current->pid; - queue.alter = decrease; queue.id = semid; if (alter) append_to_queue(sma ,&queue); @@ -1098,53 +1083,45 @@ prepend_to_queue(sma ,&queue); current->sysvsem.sleep_list = &queue; - for (;;) { - queue.status = -EINTR; - queue.sleeper = current; - current->state = TASK_INTERRUPTIBLE; - sem_unlock(sma); - unlock_semundo(); + queue.status = -EINTR; + queue.sleeper = current; + current->state = TASK_INTERRUPTIBLE; + sem_unlock(sma); + unlock_semundo(); - if (timeout) - jiffies_left = schedule_timeout(jiffies_left); - else - schedule(); + if (timeout) + jiffies_left = schedule_timeout(jiffies_left); + else + schedule(); - lock_semundo(); - sma = sem_lock(semid); - if(sma==NULL) { - if(queue.prev != NULL) - BUG(); - current->sysvsem.sleep_list = NULL; - error = -EIDRM; - goto out_semundo_free; - } - /* - * If queue.status == 1 we where woken up and - * have to retry else we simply return. - * If an interrupt occurred we have to clean up the - * queue - * - */ - if (queue.status == 1) - { - error = try_atomic_semop (sma, sops, nsops, un, - current->pid,0); - if (error <= 0) - break; - } else { - error = queue.status; - if (error == -EINTR && timeout && jiffies_left == 0) - error = -EAGAIN; - if (queue.prev) /* got Interrupt */ - break; - /* Everything done by update_queue */ - current->sysvsem.sleep_list = NULL; - goto out_unlock_semundo_free; - } + lock_semundo(); + sma = sem_lock(semid); + if(sma==NULL) { + if(queue.prev != NULL) + BUG(); + current->sysvsem.sleep_list = NULL; + error = -EIDRM; + goto out_semundo_free; } + + /* + * If queue.status != -EINTR we are woken up by another process + */ + error = queue.status; + if (queue.status != -EINTR) { + current->sysvsem.sleep_list = NULL; + goto out_unlock_semundo_free; + } + + /* + * If an interrupt occurred we have to clean up the queue + */ + if (timeout && jiffies_left == 0) + error = -EAGAIN; current->sysvsem.sleep_list = NULL; remove_from_queue(sma,&queue); + goto out_unlock_semundo_free; + update: if (alter) update_queue (sma);