summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ipc/sem.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index 7eb6f049dd7c..82518d6a96a3 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -474,6 +474,17 @@ again:
q = (struct sem_queue *)((char *)walk - offset);
walk = walk->next;
+ /* If we are scanning the single sop, per-semaphore list of
+ * one semaphore and that semaphore is 0, then it is not
+ * necessary to scan the "alter" entries: simple increments
+ * that affect only one entry succeed immediately and cannot
+ * be in the per semaphore pending queue, and decrements
+ * cannot be successful if the value is already 0.
+ */
+ if (semnum != -1 && sma->sem_base[semnum].semval == 0 &&
+ q->alter)
+ break;
+
error = try_atomic_semop(sma, q->sops, q->nsops,
q->undo, q->pid);