Messages in this thread | | | Date | Sun, 26 May 2013 08:09:11 +0200 | From | Manfred Spraul <> | Subject | Re: [PATCH] ipc,sem: move restart loop to do_smart_update |
| |
Hi Rik,
On 05/20/2013 12:32 AM, Rik van Riel wrote: > @@ -751,17 +744,19 @@ static int update_queue(struct sem_array *sma, int semnum, struct list_head *pt) > static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsops, > int otime, struct list_head *pt) > { > - int i; > + int i, restart; > > + again: > + restart = 0; > if (sma->complex_count || sops == NULL) { > - if (update_queue(sma, -1, pt)) > + if (update_queue(sma, -1, pt, &restart)) > otime = 1; > } I didn't notice it immediately, this is insufficient: Complex operations may affect all semaphores in the array. Thus it is not sufficient to scan the per-semaphore queues of the semaphores that were touched by *sops, all must be scanned.
Perhaps something like: > + if (update_queue(sma, -1, pt, &restart)) > + sops = NULL; > otime = 1; > } (untested!)
Test case: 1: semop(<key>, {{1, -1, 0}, {2, 1, 0}}, 2 <unfinished ...> 2: semop(<key>, {{2, -1, 0}}, 1 <unfinished ...> 3: semop(<key>, {{1, 1, 0}}, 1) = 0
[3] is able to run, calls do_smart_update(). The global queue is scanned and [1] is released Without the "sops = NULL", [2] sleeps forever.
-- Manfred
| |