1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Attempt to improve convergence of POSIX semaphore code with style(9).

MFC after:	3 days
This commit is contained in:
Robert Watson 2008-05-16 18:10:07 +00:00
parent 9a55503ec1
commit 8e230e30b7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=179054

View File

@ -72,7 +72,8 @@ static void sem_free(struct ksem *ksnew);
static int sem_perm(struct thread *td, struct ksem *ks); static int sem_perm(struct thread *td, struct ksem *ks);
static void sem_enter(struct proc *p, struct ksem *ks); static void sem_enter(struct proc *p, struct ksem *ks);
static int sem_leave(struct proc *p, struct ksem *ks); static int sem_leave(struct proc *p, struct ksem *ks);
static void sem_exechook(void *arg, struct proc *p, struct image_params *imgp); static void sem_exechook(void *arg, struct proc *p,
struct image_params *imgp);
static void sem_exithook(void *arg, struct proc *p); static void sem_exithook(void *arg, struct proc *p);
static void sem_forkhook(void *arg, struct proc *p1, struct proc *p2, static void sem_forkhook(void *arg, struct proc *p1, struct proc *p2,
int flags); int flags);
@ -89,21 +90,22 @@ static int kern_sem_open(struct thread *td, int dir, const char *name,
static int kern_sem_unlink(struct thread *td, const char *name); static int kern_sem_unlink(struct thread *td, const char *name);
#ifndef SEM_MAX #ifndef SEM_MAX
#define SEM_MAX 30 #define SEM_MAX 30
#endif #endif
#define SEM_MAX_NAMELEN 14 #define SEM_MAX_NAMELEN 14
#define SEM_TO_ID(x) ((intptr_t)(x)) #define SEM_TO_ID(x) ((intptr_t)(x))
#define ID_TO_SEM(x) id_to_sem(x) #define ID_TO_SEM(x) id_to_sem(x)
/* /*
* available semaphores go here, this includes sem_init and any semaphores * Available semaphores go here, this includes sem_init and any semaphores
* created via sem_open that have not yet been unlinked. * created via sem_open that have not yet been unlinked.
*/ */
LIST_HEAD(, ksem) ksem_head = LIST_HEAD_INITIALIZER(&ksem_head); LIST_HEAD(, ksem) ksem_head = LIST_HEAD_INITIALIZER(&ksem_head);
/* /*
* semaphores still in use but have been sem_unlink()'d go here. * Semaphores still in use but have been sem_unlink()'d go here.
*/ */
LIST_HEAD(, ksem) ksem_deadhead = LIST_HEAD_INITIALIZER(&ksem_deadhead); LIST_HEAD(, ksem) ksem_deadhead = LIST_HEAD_INITIALIZER(&ksem_deadhead);
@ -117,13 +119,12 @@ SYSCTL_INT(_p1003_1b, OID_AUTO, nsems, CTLFLAG_RD, &nsems, 0, "");
static eventhandler_tag sem_exit_tag, sem_exec_tag, sem_fork_tag; static eventhandler_tag sem_exit_tag, sem_exec_tag, sem_fork_tag;
#ifdef SEM_DEBUG #ifdef SEM_DEBUG
#define DP(x) printf x #define DP(x) printf x
#else #else
#define DP(x) #define DP(x)
#endif #endif
static __inline static __inline void
void
sem_ref(struct ksem *ks) sem_ref(struct ksem *ks)
{ {
@ -132,8 +133,7 @@ sem_ref(struct ksem *ks)
DP(("sem_ref: ks = %p, ref = %d\n", ks, ks->ks_ref)); DP(("sem_ref: ks = %p, ref = %d\n", ks, ks->ks_ref));
} }
static __inline static __inline void
void
sem_rel(struct ksem *ks) sem_rel(struct ksem *ks)
{ {
@ -143,8 +143,6 @@ sem_rel(struct ksem *ks)
sem_free(ks); sem_free(ks);
} }
static __inline struct ksem *id_to_sem(semid_t id);
static __inline static __inline
struct ksem * struct ksem *
id_to_sem(semid_t id) id_to_sem(semid_t id)
@ -195,7 +193,8 @@ sem_create(struct thread *td, const char *name, struct ksem **ksret,
free(ret, M_SEM); free(ret, M_SEM);
return (ENAMETOOLONG); return (ENAMETOOLONG);
} }
/* name must start with a '/' but not contain one. */
/* Name must start with a '/' but not contain one. */
if (*name != '/' || len < 2 || index(name + 1, '/') != NULL) { if (*name != '/' || len < 2 || index(name + 1, '/') != NULL) {
free(ret, M_SEM); free(ret, M_SEM);
return (EINVAL); return (EINVAL);
@ -244,10 +243,8 @@ int ksem_init(struct thread *td, struct ksem_init_args *uap);
int int
ksem_init(struct thread *td, struct ksem_init_args *uap) ksem_init(struct thread *td, struct ksem_init_args *uap)
{ {
int error;
error = kern_sem_init(td, UIO_USERSPACE, uap->value, uap->idp); return (kern_sem_init(td, UIO_USERSPACE, uap->value, uap->idp));
return (error);
} }
static int static int
@ -317,6 +314,7 @@ kern_sem_open(struct thread *td, int dir, const char *name, int oflag,
ksnew = NULL; ksnew = NULL;
mtx_lock(&sem_lock); mtx_lock(&sem_lock);
ks = sem_lookup_byname(name); ks = sem_lookup_byname(name);
/* /*
* If we found it but O_EXCL is set, error. * If we found it but O_EXCL is set, error.
*/ */
@ -324,6 +322,7 @@ kern_sem_open(struct thread *td, int dir, const char *name, int oflag,
mtx_unlock(&sem_lock); mtx_unlock(&sem_lock);
return (EEXIST); return (EEXIST);
} }
/* /*
* If we didn't find it... * If we didn't find it...
*/ */
@ -335,6 +334,7 @@ kern_sem_open(struct thread *td, int dir, const char *name, int oflag,
mtx_unlock(&sem_lock); mtx_unlock(&sem_lock);
return (ENOENT); return (ENOENT);
} }
/* /*
* We may block during creation, so drop the lock. * We may block during creation, so drop the lock.
*/ */
@ -357,6 +357,7 @@ kern_sem_open(struct thread *td, int dir, const char *name, int oflag,
DP(("about to set! %d to %p\n", id, idp)); DP(("about to set! %d to %p\n", id, idp));
*idp = id; *idp = id;
} }
/* /*
* We need to make sure we haven't lost a race while * We need to make sure we haven't lost a race while
* allocating during creation. * allocating during creation.
@ -454,8 +455,6 @@ sem_free(struct ksem *ks)
free(ks, M_SEM); free(ks, M_SEM);
} }
static __inline struct kuser *sem_getuser(struct proc *p, struct ksem *ks);
static __inline struct kuser * static __inline struct kuser *
sem_getuser(struct proc *p, struct ksem *ks) sem_getuser(struct proc *p, struct ksem *ks)
{ {
@ -495,9 +494,7 @@ sem_leave(struct proc *p, struct ksem *ks)
} }
static void static void
sem_enter(p, ks) sem_enter(struct proc *p, struct ksem *ks)
struct proc *p;
struct ksem *ks;
{ {
struct kuser *ku, *k; struct kuser *ku, *k;
@ -584,7 +581,10 @@ kern_sem_close(struct thread *td, semid_t id)
error = EINVAL; error = EINVAL;
mtx_lock(&sem_lock); mtx_lock(&sem_lock);
ks = ID_TO_SEM(id); ks = ID_TO_SEM(id);
/* this is not a valid operation for unnamed sems */
/*
* This is not a valid operation for unnamed sems.
*/
if (ks != NULL && ks->ks_name != NULL) if (ks != NULL && ks->ks_name != NULL)
error = sem_leave(td->td_proc, ks); error = sem_leave(td->td_proc, ks);
mtx_unlock(&sem_lock); mtx_unlock(&sem_lock);
@ -661,7 +661,9 @@ ksem_timedwait(struct thread *td, struct ksem_timedwait_args *uap)
struct timespec *ts; struct timespec *ts;
int error; int error;
/* We allow a null timespec (wait forever). */ /*
* We allow a null timespec (wait forever).
*/
if (uap->abstime == NULL) if (uap->abstime == NULL)
ts = NULL; ts = NULL;
else { else {
@ -885,6 +887,7 @@ sem_forkhook(void *arg, struct proc *p1, struct proc *p2, int flags)
count = new_count; count = new_count;
goto race_lost; goto race_lost;
} }
/* /*
* Given an array capable of storing an adequate number of semaphore * Given an array capable of storing an adequate number of semaphore
* references, now walk the list of semaphores and acquire a new * references, now walk the list of semaphores and acquire a new
@ -914,6 +917,7 @@ sem_forkhook(void *arg, struct proc *p1, struct proc *p2, int flags)
} }
mtx_unlock(&sem_lock); mtx_unlock(&sem_lock);
KASSERT(i == count, ("sem_forkhook: i != count (%d, %d)", i, count)); KASSERT(i == count, ("sem_forkhook: i != count (%d, %d)", i, count));
/* /*
* Now cause p2 to enter each of the referenced semaphores, then * Now cause p2 to enter each of the referenced semaphores, then
* release our temporary reference. This is pretty inefficient. * release our temporary reference. This is pretty inefficient.
@ -965,12 +969,14 @@ sem_modload(struct module *module, int cmd, void *arg)
mtx_init(&sem_lock, "sem", "semaphore", MTX_DEF); mtx_init(&sem_lock, "sem", "semaphore", MTX_DEF);
p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX); p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX); p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX);
sem_exit_tag = EVENTHANDLER_REGISTER(process_exit, sem_exithook, sem_exit_tag = EVENTHANDLER_REGISTER(process_exit,
NULL, EVENTHANDLER_PRI_ANY); sem_exithook, NULL, EVENTHANDLER_PRI_ANY);
sem_exec_tag = EVENTHANDLER_REGISTER(process_exec, sem_exechook, sem_exec_tag = EVENTHANDLER_REGISTER(process_exec,
NULL, EVENTHANDLER_PRI_ANY); sem_exechook, NULL, EVENTHANDLER_PRI_ANY);
sem_fork_tag = EVENTHANDLER_REGISTER(process_fork, sem_forkhook, NULL, EVENTHANDLER_PRI_ANY); sem_fork_tag = EVENTHANDLER_REGISTER(process_fork,
sem_forkhook, NULL, EVENTHANDLER_PRI_ANY);
break; break;
case MOD_UNLOAD: case MOD_UNLOAD:
if (nsems != 0) { if (nsems != 0) {
error = EOPNOTSUPP; error = EOPNOTSUPP;
@ -981,6 +987,7 @@ sem_modload(struct module *module, int cmd, void *arg)
EVENTHANDLER_DEREGISTER(process_fork, sem_fork_tag); EVENTHANDLER_DEREGISTER(process_fork, sem_fork_tag);
mtx_destroy(&sem_lock); mtx_destroy(&sem_lock);
break; break;
case MOD_SHUTDOWN: case MOD_SHUTDOWN:
break; break;
default: default: