Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2004-10-01 15:18:10 +0400
committerCorinna Vinschen <corinna@vinschen.de>2004-10-01 15:18:10 +0400
commitc6ef5fb7ece1079ccd298b89b63c051cbb7b80e0 (patch)
tree5c90ad48b996a4c2b18dac77d152735b441fecff
parent00ee07cb12cc19aedd03e1a73ccad03151cb712b (diff)
* sysv_sem.cc: Update to FreeBSD version 1.69.
1.68: Reduce the overhead of semop() by using the kernel stack instead of malloc'd memory to store the operations array if it is small enough to fit. 1.69: Adjust the number of processes waiting on a semaphore properly if we're woken up in the middle of sleeping.
-rw-r--r--winsup/cygserver/ChangeLog9
-rw-r--r--winsup/cygserver/sysv_sem.cc41
2 files changed, 36 insertions, 14 deletions
diff --git a/winsup/cygserver/ChangeLog b/winsup/cygserver/ChangeLog
index 99b69a24e..5597350aa 100644
--- a/winsup/cygserver/ChangeLog
+++ b/winsup/cygserver/ChangeLog
@@ -1,3 +1,12 @@
+2004-10-01 Corinna Vinschen <corinna@vinschen.de>
+
+ * sysv_sem.cc: Update to FreeBSD version 1.69.
+ 1.68: Reduce the overhead of semop() by using the kernel stack
+ instead of malloc'd memory to store the operations array if it
+ is small enough to fit.
+ 1.69: Adjust the number of processes waiting on a semaphore properly
+ if we're woken up in the middle of sleeping.
+
2004-09-23 Corinna Vinschen <corinna@vinschen.de>
* sysv_shm.cc (kern_shmat): Avoid compiler warning.
diff --git a/winsup/cygserver/sysv_sem.cc b/winsup/cygserver/sysv_sem.cc
index bcb312d58..a4acf37f1 100644
--- a/winsup/cygserver/sysv_sem.cc
+++ b/winsup/cygserver/sysv_sem.cc
@@ -17,7 +17,7 @@
#ifndef __FBSDID
#define __FBSDID(s) const char version[] = (s)
#endif
-__FBSDID("$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/kern/sysv_sem.c,v 1.67 2003/11/15 11:56:53 tjr Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/kern/sysv_sem.c,v 1.70 2004/05/30 20:34:58 phk Exp $");
#define _KERNEL 1
#define __BSD_VISIBLE 1
@@ -953,6 +953,8 @@ struct semop_args {
int
semop(struct thread *td, struct semop_args *uap)
{
+#define SMALL_SOPS 8
+ struct sembuf small_sops[SMALL_SOPS];
int semid = uap->semid;
size_t nsops = uap->nsops;
struct sembuf *sops;
@@ -976,16 +978,20 @@ semop(struct thread *td, struct semop_args *uap)
return (EINVAL);
/* Allocate memory for sem_ops */
- if (nsops > (unsigned long) seminfo.semopm) {
+ if (nsops <= SMALL_SOPS)
+ sops = small_sops;
+ else if (nsops <= (unsigned long) seminfo.semopm)
+ sops = (struct sembuf *) sys_malloc(nsops * sizeof(*sops), M_SEM, M_WAITOK);
+ else {
DPRINTF(("too many sops (max=%d, nsops=%d)\n", seminfo.semopm,
nsops));
return (E2BIG);
}
- sops = (struct sembuf *) sys_malloc(nsops * sizeof(sops[0]), M_SEM, M_WAITOK);
if ((error = copyin(uap->sops, sops, nsops * sizeof(sops[0]))) != 0) {
DPRINTF(("error = %d from copyin(%08x, %08x, %d)\n", error,
uap->sops, sops, nsops * sizeof(sops[0])));
- sys_free(sops, M_SEM);
+ if (sops != small_sops)
+ sys_free(sops, M_SEM);
return (error);
}
@@ -1110,15 +1116,7 @@ semop(struct thread *td, struct semop_args *uap)
error = msleep(semaptr, sema_mtxp, (PZERO - 4) | PCATCH,
"semwait", 0);
DPRINTF(("semop: good morning (error=%d)!\n", error));
-
- if (error != 0) {
-#ifdef __CYGWIN__
- if (error != EIDRM)
-#endif /* __CYGWIN__ */
- error = EINTR;
- goto done2;
- }
- DPRINTF(("semop: good morning!\n"));
+ /* return code is checked below, after sem[nz]cnt-- */
/*
* Make sure that the semaphore still exists
@@ -1137,6 +1135,20 @@ semop(struct thread *td, struct semop_args *uap)
semptr->semzcnt--;
else
semptr->semncnt--;
+
+ /*
+ * Is it really morning, or was our sleep interrupted?
+ * (Delayed check of msleep() return code because we
+ * need to decrement sem[nz]cnt either way.)
+ */
+ if (error != 0) {
+#ifdef __CYGWIN__
+ if (error != EIDRM)
+#endif /* __CYGWIN__ */
+ error = EINTR;
+ goto done2;
+ }
+ DPRINTF(("semop: good morning!\n"));
}
done:
@@ -1216,7 +1228,8 @@ done:
td->td_retval[0] = 0;
done2:
mtx_unlock(sema_mtxp);
- sys_free(sops, M_SEM);
+ if (sops != small_sops)
+ sys_free(sops, M_SEM);
return (error);
}