diff --git a/ipc/sem.c b/ipc/sem.c index 7eb6f049dd7c5d547ad9b62fa33646857d978352..82518d6a96a34583ae76f6ec85795f32aa70cb2e 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -474,6 +474,17 @@ static void update_queue(struct sem_array *sma, int semnum) 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);