ipc/sem.c: change perform_atomic_semop parameters
Right now, perform_atomic_semop gets the content of sem_queue as individual fields. Changes that, instead pass a pointer to sem_queue. This is a preparation for the next patch: it uses sem_queue to store the reason why a task must sleep. Signed-off-by: Manfred Spraul <manfred@colorfullife.com> Cc: Davidlohr Bueso <davidlohr.bueso@hp.com> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
2f2ed41dca
commit
d198cd6d6d
38
ipc/sem.c
38
ipc/sem.c
@ -585,21 +585,23 @@ SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg)
|
|||||||
/**
|
/**
|
||||||
* perform_atomic_semop - Perform (if possible) a semaphore operation
|
* perform_atomic_semop - Perform (if possible) a semaphore operation
|
||||||
* @sma: semaphore array
|
* @sma: semaphore array
|
||||||
* @sops: array with operations that should be checked
|
* @q: struct sem_queue that describes the operation
|
||||||
* @nsops: number of operations
|
|
||||||
* @un: undo array
|
|
||||||
* @pid: pid that did the change
|
|
||||||
*
|
*
|
||||||
* Returns 0 if the operation was possible.
|
* Returns 0 if the operation was possible.
|
||||||
* Returns 1 if the operation is impossible, the caller must sleep.
|
* Returns 1 if the operation is impossible, the caller must sleep.
|
||||||
* Negative values are error codes.
|
* Negative values are error codes.
|
||||||
*/
|
*/
|
||||||
static int perform_atomic_semop(struct sem_array *sma, struct sembuf *sops,
|
static int perform_atomic_semop(struct sem_array *sma, struct sem_queue *q)
|
||||||
int nsops, struct sem_undo *un, int pid)
|
|
||||||
{
|
{
|
||||||
int result, sem_op;
|
int result, sem_op, nsops, pid;
|
||||||
struct sembuf *sop;
|
struct sembuf *sop;
|
||||||
struct sem *curr;
|
struct sem *curr;
|
||||||
|
struct sembuf *sops;
|
||||||
|
struct sem_undo *un;
|
||||||
|
|
||||||
|
sops = q->sops;
|
||||||
|
nsops = q->nsops;
|
||||||
|
un = q->undo;
|
||||||
|
|
||||||
for (sop = sops; sop < sops + nsops; sop++) {
|
for (sop = sops; sop < sops + nsops; sop++) {
|
||||||
curr = sma->sem_base + sop->sem_num;
|
curr = sma->sem_base + sop->sem_num;
|
||||||
@ -627,6 +629,7 @@ static int perform_atomic_semop(struct sem_array *sma, struct sembuf *sops,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sop--;
|
sop--;
|
||||||
|
pid = q->pid;
|
||||||
while (sop >= sops) {
|
while (sop >= sops) {
|
||||||
sma->sem_base[sop->sem_num].sempid = pid;
|
sma->sem_base[sop->sem_num].sempid = pid;
|
||||||
sop--;
|
sop--;
|
||||||
@ -779,8 +782,7 @@ static int wake_const_ops(struct sem_array *sma, int semnum,
|
|||||||
q = container_of(walk, struct sem_queue, list);
|
q = container_of(walk, struct sem_queue, list);
|
||||||
walk = walk->next;
|
walk = walk->next;
|
||||||
|
|
||||||
error = perform_atomic_semop(sma, q->sops, q->nsops,
|
error = perform_atomic_semop(sma, q);
|
||||||
q->undo, q->pid);
|
|
||||||
|
|
||||||
if (error <= 0) {
|
if (error <= 0) {
|
||||||
/* operation completed, remove from queue & wakeup */
|
/* operation completed, remove from queue & wakeup */
|
||||||
@ -892,8 +894,7 @@ again:
|
|||||||
if (semnum != -1 && sma->sem_base[semnum].semval == 0)
|
if (semnum != -1 && sma->sem_base[semnum].semval == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
error = perform_atomic_semop(sma, q->sops, q->nsops,
|
error = perform_atomic_semop(sma, q);
|
||||||
q->undo, q->pid);
|
|
||||||
|
|
||||||
/* Does q->sleeper still need to sleep? */
|
/* Does q->sleeper still need to sleep? */
|
||||||
if (error > 0)
|
if (error > 0)
|
||||||
@ -1871,8 +1872,13 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
|
|||||||
if (un && un->semid == -1)
|
if (un && un->semid == -1)
|
||||||
goto out_unlock_free;
|
goto out_unlock_free;
|
||||||
|
|
||||||
error = perform_atomic_semop(sma, sops, nsops, un,
|
queue.sops = sops;
|
||||||
task_tgid_vnr(current));
|
queue.nsops = nsops;
|
||||||
|
queue.undo = un;
|
||||||
|
queue.pid = task_tgid_vnr(current);
|
||||||
|
queue.alter = alter;
|
||||||
|
|
||||||
|
error = perform_atomic_semop(sma, &queue);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
/* If the operation was successful, then do
|
/* If the operation was successful, then do
|
||||||
* the required updates.
|
* the required updates.
|
||||||
@ -1889,12 +1895,6 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
|
|||||||
* task into the pending queue and go to sleep.
|
* task into the pending queue and go to sleep.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
queue.sops = sops;
|
|
||||||
queue.nsops = nsops;
|
|
||||||
queue.undo = un;
|
|
||||||
queue.pid = task_tgid_vnr(current);
|
|
||||||
queue.alter = alter;
|
|
||||||
|
|
||||||
if (nsops == 1) {
|
if (nsops == 1) {
|
||||||
struct sem *curr;
|
struct sem *curr;
|
||||||
curr = &sma->sem_base[sops->sem_num];
|
curr = &sma->sem_base[sops->sem_num];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user