diff options
author | Tim J. Robbins <tjr@FreeBSD.org> | 2003-12-19 13:07:17 +0000 |
---|---|---|
committer | Tim J. Robbins <tjr@FreeBSD.org> | 2003-12-19 13:07:17 +0000 |
commit | f5925b74365a9223710735c5935cc7c5fa06502c (patch) | |
tree | 0724d62cda807213b78ef8bf6cf65ae390044294 /sys/kern/sysv_sem.c | |
parent | 22df7d650a24281e61947913c736b7163416dc39 (diff) | |
download | src-f5925b74365a9223710735c5935cc7c5fa06502c.tar.gz src-f5925b74365a9223710735c5935cc7c5fa06502c.zip |
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.
Notes
Notes:
svn path=/head/; revision=123667
Diffstat (limited to 'sys/kern/sysv_sem.c')
-rw-r--r-- | sys/kern/sysv_sem.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index 42a4faac59a2..e07e632d8af4 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -877,6 +877,8 @@ semop(td, uap) 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; @@ -900,16 +902,20 @@ semop(td, uap) return (EINVAL); /* Allocate memory for sem_ops */ - if (nsops > seminfo.semopm) { + if (nsops <= SMALL_SOPS) + sops = small_sops; + else if (nsops <= seminfo.semopm) + sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK); + else { DPRINTF(("too many sops (max=%d, nsops=%d)\n", seminfo.semopm, nsops)); return (E2BIG); } - sops = 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]))); - free(sops, M_SEM); + if (sops != small_sops) + free(sops, M_SEM); return (error); } @@ -1137,7 +1143,8 @@ done: td->td_retval[0] = 0; done2: mtx_unlock(sema_mtxp); - free(sops, M_SEM); + if (sops != small_sops) + free(sops, M_SEM); return (error); } |