- Retry the operations (instead of failing) in case of reallocation.

Suggested by <yamt>.
- Use predicts in checks for reallocation state.
This commit is contained in:
rmind 2007-11-25 19:03:24 +00:00
parent 6cccb0c686
commit 8cfca2b5e3
2 changed files with 46 additions and 34 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: sysv_msg.c,v 1.52 2007/11/04 13:09:32 yamt Exp $ */ /* $NetBSD: sysv_msg.c,v 1.53 2007/11/25 19:03:24 rmind Exp $ */
/*- /*-
* Copyright (c) 1999, 2006, 2007 The NetBSD Foundation, Inc. * Copyright (c) 1999, 2006, 2007 The NetBSD Foundation, Inc.
@ -57,7 +57,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sysv_msg.c,v 1.52 2007/11/04 13:09:32 yamt Exp $"); __KERNEL_RCSID(0, "$NetBSD: sysv_msg.c,v 1.53 2007/11/25 19:03:24 rmind Exp $");
#define SYSVMSG #define SYSVMSG
@ -659,15 +659,13 @@ msgsnd1(struct lwp *l, int msqidr, const char *user_msgp, size_t msgsz,
MSG_PRINTF(("call to msgsnd(%d, %p, %lld, %d)\n", msqid, user_msgp, MSG_PRINTF(("call to msgsnd(%d, %p, %lld, %d)\n", msqid, user_msgp,
(long long)msgsz, msgflg)); (long long)msgsz, msgflg));
restart:
msqid = IPCID_TO_IX(msqidr); msqid = IPCID_TO_IX(msqidr);
mutex_enter(&msgmutex); mutex_enter(&msgmutex);
if (msg_realloc_state) { /* In case of reallocation, we will wait for completion */
/* In case of reallocation, we will wait for completion */ while (__predict_false(msg_realloc_state))
while (msg_realloc_state) cv_wait(&msg_realloc_cv, &msgmutex);
cv_wait(&msg_realloc_cv, &msgmutex);
}
if (msqid < 0 || msqid >= msginfo.msgmni) { if (msqid < 0 || msqid >= msginfo.msgmni) {
MSG_PRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid, MSG_PRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
@ -756,13 +754,20 @@ msgsnd1(struct lwp *l, int msqidr, const char *user_msgp, size_t msgsz,
MSG_PRINTF(("good morning, error=%d\n", error)); MSG_PRINTF(("good morning, error=%d\n", error));
msg_waiters--; msg_waiters--;
/* Notify reallocator, in case of such state */
if (msg_realloc_state)
cv_broadcast(&msg_realloc_cv);
if (we_own_it) if (we_own_it)
msqptr->msg_perm.mode &= ~MSG_LOCKED; msqptr->msg_perm.mode &= ~MSG_LOCKED;
if (error || msg_realloc_state) {
/*
* In case of such state, notify reallocator and
* restart the call.
*/
if (msg_realloc_state) {
cv_broadcast(&msg_realloc_cv);
mutex_exit(&msgmutex);
goto restart;
}
if (error != 0) {
MSG_PRINTF(("msgsnd: interrupted system " MSG_PRINTF(("msgsnd: interrupted system "
"call\n")); "call\n"));
error = EINTR; error = EINTR;
@ -959,15 +964,13 @@ msgrcv1(struct lwp *l, int msqidr, char *user_msgp, size_t msgsz, long msgtyp,
MSG_PRINTF(("call to msgrcv(%d, %p, %lld, %ld, %d)\n", msqid, MSG_PRINTF(("call to msgrcv(%d, %p, %lld, %ld, %d)\n", msqid,
user_msgp, (long long)msgsz, msgtyp, msgflg)); user_msgp, (long long)msgsz, msgtyp, msgflg));
restart:
msqid = IPCID_TO_IX(msqidr); msqid = IPCID_TO_IX(msqidr);
mutex_enter(&msgmutex); mutex_enter(&msgmutex);
if (msg_realloc_state) { /* In case of reallocation, we will wait for completion */
/* In case of reallocation, we will wait for completion */ while (__predict_false(msg_realloc_state))
while (msg_realloc_state) cv_wait(&msg_realloc_cv, &msgmutex);
cv_wait(&msg_realloc_cv, &msgmutex);
}
if (msqid < 0 || msqid >= msginfo.msgmni) { if (msqid < 0 || msqid >= msginfo.msgmni) {
MSG_PRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid, MSG_PRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
@ -1090,11 +1093,17 @@ msgrcv1(struct lwp *l, int msqidr, char *user_msgp, size_t msgsz, long msgtyp,
MSG_PRINTF(("msgrcv: good morning (error=%d)\n", error)); MSG_PRINTF(("msgrcv: good morning (error=%d)\n", error));
msg_waiters--; msg_waiters--;
/* Notify reallocator, in case of such state */ /*
if (msg_realloc_state) * In case of such state, notify reallocator and
* restart the call.
*/
if (msg_realloc_state) {
cv_broadcast(&msg_realloc_cv); cv_broadcast(&msg_realloc_cv);
mutex_exit(&msgmutex);
goto restart;
}
if (error || msg_realloc_state) { if (error != 0) {
MSG_PRINTF(("msgsnd: interrupted system call\n")); MSG_PRINTF(("msgsnd: interrupted system call\n"));
error = EINTR; error = EINTR;
goto unlock; goto unlock;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sysv_sem.c,v 1.75 2007/11/04 13:09:33 yamt Exp $ */ /* $NetBSD: sysv_sem.c,v 1.76 2007/11/25 19:03:24 rmind Exp $ */
/*- /*-
* Copyright (c) 1999, 2007 The NetBSD Foundation, Inc. * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
@ -46,7 +46,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v 1.75 2007/11/04 13:09:33 yamt Exp $"); __KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v 1.76 2007/11/25 19:03:24 rmind Exp $");
#define SYSVSEM #define SYSVSEM
@ -760,7 +760,7 @@ sys_semop(struct lwp *l, void *v, register_t *retval)
int do_wakeup, do_undos; int do_wakeup, do_undos;
SEM_PRINTF(("call to semop(%d, %p, %zd)\n", semid, SCARG(uap,sops), nsops)); SEM_PRINTF(("call to semop(%d, %p, %zd)\n", semid, SCARG(uap,sops), nsops));
restart:
if (nsops <= SMALL_SOPS) { if (nsops <= SMALL_SOPS) {
sops = small_sops; sops = small_sops;
} else if (nsops <= seminfo.semopm) { } else if (nsops <= seminfo.semopm) {
@ -774,11 +774,9 @@ sys_semop(struct lwp *l, void *v, register_t *retval)
} }
mutex_enter(&semlock); mutex_enter(&semlock);
if (sem_realloc_state) { /* In case of reallocation, we will wait for completion */
/* In case of reallocation, we will wait for completion */ while (__predict_false(sem_realloc_state))
while (sem_realloc_state) cv_wait(&sem_realloc_cv, &semlock);
cv_wait(&sem_realloc_cv, &semlock);
}
semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ semid = IPCID_TO_IX(semid); /* Convert back to zero origin */
if (semid < 0 || semid >= seminfo.semmni) { if (semid < 0 || semid >= seminfo.semmni) {
@ -899,9 +897,8 @@ sys_semop(struct lwp *l, void *v, register_t *retval)
SEM_PRINTF(("semop: good morning (error=%d)!\n", error)); SEM_PRINTF(("semop: good morning (error=%d)!\n", error));
sem_waiters--; sem_waiters--;
/* Notify reallocator, in case of such state */ /* Notify reallocator, if it is waiting */
if (sem_realloc_state) cv_broadcast(&sem_realloc_cv);
cv_broadcast(&sem_realloc_cv);
/* /*
* Make sure that the semaphore still exists * Make sure that the semaphore still exists
@ -922,8 +919,14 @@ sys_semop(struct lwp *l, void *v, register_t *retval)
else else
semptr->semncnt--; semptr->semncnt--;
/* In case of such state, restart the call */
if (sem_realloc_state) {
mutex_exit(&semlock);
goto restart;
}
/* Is it really morning, or was our sleep interrupted? */ /* Is it really morning, or was our sleep interrupted? */
if (error || sem_realloc_state) { if (error != 0) {
error = EINTR; error = EINTR;
goto out; goto out;
} }