version 1.29.8.1, 2011/04/21 01:42:10 |
version 1.30, 2011/04/11 22:31:43 |
|
|
__KERNEL_RCSID(0, "$NetBSD$"); |
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
|
#include <sys/systm.h> |
#include <sys/kernel.h> |
#include <sys/kernel.h> |
|
|
#include <sys/atomic.h> |
|
#include <sys/proc.h> |
#include <sys/proc.h> |
#include <sys/ksem.h> |
#include <sys/ksem.h> |
#include <sys/syscall.h> |
#include <sys/syscall.h> |
Line 105 typedef struct ksem { |
|
Line 104 typedef struct ksem { |
|
|
|
static kmutex_t ksem_lock __cacheline_aligned; |
static kmutex_t ksem_lock __cacheline_aligned; |
static LIST_HEAD(,ksem) ksem_head __cacheline_aligned; |
static LIST_HEAD(,ksem) ksem_head __cacheline_aligned; |
static u_int nsems_total __cacheline_aligned; |
|
static u_int nsems __cacheline_aligned; |
static u_int nsems __cacheline_aligned; |
|
|
static int ksem_sysinit(void); |
static int ksem_sysinit(void); |
Line 143 ksem_sysinit(void) |
|
Line 141 ksem_sysinit(void) |
|
{ |
{ |
int error; |
int error; |
|
|
|
nsems = 0; |
mutex_init(&ksem_lock, MUTEX_DEFAULT, IPL_NONE); |
mutex_init(&ksem_lock, MUTEX_DEFAULT, IPL_NONE); |
LIST_INIT(&ksem_head); |
LIST_INIT(&ksem_head); |
nsems_total = 0; |
|
nsems = 0; |
|
|
|
error = syscall_establish(NULL, ksem_syscalls); |
error = syscall_establish(NULL, ksem_syscalls); |
if (error) { |
if (error) { |
Line 165 ksem_sysfini(bool interface) |
|
Line 162 ksem_sysfini(bool interface) |
|
if (error != 0) { |
if (error != 0) { |
return error; |
return error; |
} |
} |
/* |
if (nsems != 0) { |
* Make sure that no semaphores are in use. Note: semops |
|
* must be unused at this point. |
|
*/ |
|
if (nsems_total) { |
|
error = syscall_establish(NULL, ksem_syscalls); |
error = syscall_establish(NULL, ksem_syscalls); |
KASSERT(error == 0); |
KASSERT(error == 0); |
return EBUSY; |
return EBUSY; |
Line 303 ksem_create(lwp_t *l, const char *name, |
|
Line 296 ksem_create(lwp_t *l, const char *name, |
|
ks->ks_uid = kauth_cred_geteuid(uc); |
ks->ks_uid = kauth_cred_geteuid(uc); |
ks->ks_gid = kauth_cred_getegid(uc); |
ks->ks_gid = kauth_cred_getegid(uc); |
|
|
atomic_inc_uint(&nsems_total); |
|
*ksret = ks; |
*ksret = ks; |
return 0; |
return 0; |
} |
} |
|
|
ksem_free(ksem_t *ks) |
ksem_free(ksem_t *ks) |
{ |
{ |
|
|
KASSERT(!cv_has_waiters(&ks->ks_cv)); |
|
|
|
if (ks->ks_name) { |
if (ks->ks_name) { |
KASSERT(ks->ks_namelen > 0); |
KASSERT(ks->ks_namelen > 0); |
kmem_free(ks->ks_name, ks->ks_namelen); |
kmem_free(ks->ks_name, ks->ks_namelen); |
Line 321 ksem_free(ksem_t *ks) |
|
Line 311 ksem_free(ksem_t *ks) |
|
mutex_destroy(&ks->ks_lock); |
mutex_destroy(&ks->ks_lock); |
cv_destroy(&ks->ks_cv); |
cv_destroy(&ks->ks_cv); |
kmem_free(ks, sizeof(ksem_t)); |
kmem_free(ks, sizeof(ksem_t)); |
|
|
atomic_dec_uint(&nsems_total); |
|
} |
} |
|
|
int |
int |
Line 460 do_ksem_open(struct lwp *l, const char * |
|
Line 448 do_ksem_open(struct lwp *l, const char * |
|
if ((oflag & O_CREAT) == 0) { |
if ((oflag & O_CREAT) == 0) { |
mutex_exit(&ksem_lock); |
mutex_exit(&ksem_lock); |
KASSERT(ksnew == NULL); |
KASSERT(ksnew == NULL); |
error = ENOENT; |
return ENOENT; |
goto err; |
|
} |
} |
|
|
/* Check for the limit locked. */ |
/* Check for the limit locked. */ |
Line 472 do_ksem_open(struct lwp *l, const char * |
|
Line 459 do_ksem_open(struct lwp *l, const char * |
|
} |
} |
|
|
/* |
/* |
* Finally, insert semaphore into the list. |
* Finally, insert semaphore into the hash. |
* Note: it already has the initial reference. |
* Note: it already has the initial reference. |
*/ |
*/ |
ks = ksnew; |
ks = ksnew; |
Line 502 sys__ksem_close(struct lwp *l, const str |
|
Line 489 sys__ksem_close(struct lwp *l, const str |
|
/* { |
/* { |
intptr_t id; |
intptr_t id; |
} */ |
} */ |
int fd = (int)SCARG(uap, id); |
struct sys_close_args cuap; |
|
SCARG(&cuap, fd) = SCARG(uap, id); |
if (fd_getfile(fd) == NULL) { |
return sys_close(l, (const void *)&cuap, retval); |
return EBADF; |
|
} |
|
return fd_close(fd); |
|
} |
} |
|
|
static int |
static int |
Line 565 sys__ksem_unlink(struct lwp *l, const st |
|
Line 549 sys__ksem_unlink(struct lwp *l, const st |
|
return error; |
return error; |
} |
} |
|
|
/* Remove from the global list. */ |
/* Remove and destroy if no referenes. */ |
LIST_REMOVE(ks, ks_entry); |
LIST_REMOVE(ks, ks_entry); |
nsems--; |
nsems--; |
mutex_exit(&ksem_lock); |
|
|
|
refcnt = ks->ks_ref; |
refcnt = ks->ks_ref; |
if (refcnt) { |
if (refcnt) { |
Line 576 sys__ksem_unlink(struct lwp *l, const st |
|
Line 559 sys__ksem_unlink(struct lwp *l, const st |
|
ks->ks_flags |= KS_UNLINKED; |
ks->ks_flags |= KS_UNLINKED; |
} |
} |
mutex_exit(&ks->ks_lock); |
mutex_exit(&ks->ks_lock); |
|
mutex_exit(&ksem_lock); |
|
|
if (refcnt == 0) { |
if (refcnt == 0) { |
ksem_free(ks); |
ksem_free(ks); |
Line 691 sys__ksem_destroy(struct lwp *l, const s |
|
Line 675 sys__ksem_destroy(struct lwp *l, const s |
|
intptr_t id; |
intptr_t id; |
} */ |
} */ |
int fd = (int)SCARG(uap, id), error; |
int fd = (int)SCARG(uap, id), error; |
|
struct sys_close_args cuap; |
ksem_t *ks; |
ksem_t *ks; |
|
|
error = ksem_get(fd, &ks); |
error = ksem_get(fd, &ks); |
Line 711 sys__ksem_destroy(struct lwp *l, const s |
|
Line 696 sys__ksem_destroy(struct lwp *l, const s |
|
} |
} |
out: |
out: |
mutex_exit(&ks->ks_lock); |
mutex_exit(&ks->ks_lock); |
|
fd_putfile(fd); |
if (error) { |
if (error) { |
fd_putfile(fd); |
|
return error; |
return error; |
} |
} |
return fd_close(fd); |
SCARG(&cuap, fd) = fd; |
|
return sys_close(l, (const void *)&cuap, retval); |
} |
} |