- 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.
@ -57,7 +57,7 @@
*/
#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
@ -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,
(long long)msgsz, msgflg));
restart:
msqid = IPCID_TO_IX(msqidr);
mutex_enter(&msgmutex);
if (msg_realloc_state) {
/* In case of reallocation, we will wait for completion */
while (msg_realloc_state)
cv_wait(&msg_realloc_cv, &msgmutex);
}
/* In case of reallocation, we will wait for completion */
while (__predict_false(msg_realloc_state))
cv_wait(&msg_realloc_cv, &msgmutex);
if (msqid < 0 || msqid >= msginfo.msgmni) {
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_waiters--;
/* Notify reallocator, in case of such state */
if (msg_realloc_state)
cv_broadcast(&msg_realloc_cv);
if (we_own_it)
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 "
"call\n"));
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,
user_msgp, (long long)msgsz, msgtyp, msgflg));
restart:
msqid = IPCID_TO_IX(msqidr);
mutex_enter(&msgmutex);
if (msg_realloc_state) {
/* In case of reallocation, we will wait for completion */
while (msg_realloc_state)
cv_wait(&msg_realloc_cv, &msgmutex);
}
/* In case of reallocation, we will wait for completion */
while (__predict_false(msg_realloc_state))
cv_wait(&msg_realloc_cv, &msgmutex);
if (msqid < 0 || msqid >= msginfo.msgmni) {
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_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);
mutex_exit(&msgmutex);
goto restart;
}
if (error || msg_realloc_state) {
if (error != 0) {
MSG_PRINTF(("msgsnd: interrupted system call\n"));
error = EINTR;
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.
@ -46,7 +46,7 @@
*/
#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
@ -760,7 +760,7 @@ sys_semop(struct lwp *l, void *v, register_t *retval)
int do_wakeup, do_undos;
SEM_PRINTF(("call to semop(%d, %p, %zd)\n", semid, SCARG(uap,sops), nsops));
restart:
if (nsops <= SMALL_SOPS) {
sops = small_sops;
} else if (nsops <= seminfo.semopm) {
@ -774,11 +774,9 @@ sys_semop(struct lwp *l, void *v, register_t *retval)
}
mutex_enter(&semlock);
if (sem_realloc_state) {
/* In case of reallocation, we will wait for completion */
while (sem_realloc_state)
cv_wait(&sem_realloc_cv, &semlock);
}
/* In case of reallocation, we will wait for completion */
while (__predict_false(sem_realloc_state))
cv_wait(&sem_realloc_cv, &semlock);
semid = IPCID_TO_IX(semid); /* Convert back to zero origin */
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_waiters--;
/* Notify reallocator, in case of such state */
if (sem_realloc_state)
cv_broadcast(&sem_realloc_cv);
/* Notify reallocator, if it is waiting */
cv_broadcast(&sem_realloc_cv);
/*
* Make sure that the semaphore still exists
@ -922,8 +919,14 @@ sys_semop(struct lwp *l, void *v, register_t *retval)
else
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? */
if (error || sem_realloc_state) {
if (error != 0) {
error = EINTR;
goto out;
}