On 2020-07-08, Ted Unangst wrote:
> I think this makes sem_init(pshared) work.
Whoops, need more context to include the header file changes.
Index: include/semaphore.h
===================================================================
RCS file: /home/cvs/src/include/semaphore.h,v
retrieving revision 1.1
diff -u -p -r1.1 semaphore.h
--- include/semaphore.h 15 Oct 2017 23:40:33 -0000 1.1
+++ include/semaphore.h 8 Jul 2020 08:47:06 -0000
@@ -38,10 +38,16 @@
#define _SEMAPHORE_H_
#include <sys/cdefs.h>
+#include <machine/spinlock.h>
/* Opaque type definition. */
-struct __sem;
-typedef struct __sem *sem_t;
+struct __sem {
+ _atomic_lock_t lock;
+ volatile int waitcount;
+ volatile int value;
+ int shared;
+};
+typedef struct __sem sem_t;
struct timespec;
#define SEM_FAILED ((sem_t *)0)
Index: lib/libc/include/thread_private.h
===================================================================
RCS file: /home/cvs/src/lib/libc/include/thread_private.h,v
retrieving revision 1.35
diff -u -p -r1.35 thread_private.h
--- lib/libc/include/thread_private.h 13 Feb 2019 13:22:14 -0000 1.35
+++ lib/libc/include/thread_private.h 8 Jul 2020 08:44:45 -0000
@@ -273,13 +273,6 @@ __END_HIDDEN_DECLS
#define _SPINLOCK_UNLOCKED _ATOMIC_LOCK_UNLOCKED
-struct __sem {
- _atomic_lock_t lock;
- volatile int waitcount;
- volatile int value;
- int shared;
-};
-
TAILQ_HEAD(pthread_queue, pthread);
#ifdef FUTEX
Index: lib/librthread/rthread.h
===================================================================
RCS file: /home/cvs/src/lib/librthread/rthread.h,v
retrieving revision 1.64
diff -u -p -r1.64 rthread.h
--- lib/librthread/rthread.h 13 Feb 2019 13:22:14 -0000 1.64
+++ lib/librthread/rthread.h 8 Jul 2020 09:18:34 -0000
@@ -79,8 +79,8 @@ struct pthread_spinlock {
(((size) + (_thread_pagesize - 1)) & ~(_thread_pagesize - 1))
__BEGIN_HIDDEN_DECLS
-int _sem_wait(sem_t, int, const struct timespec *, int *);
-int _sem_post(sem_t);
+int _sem_wait(sem_t *, int, const struct timespec *, int *);
+int _sem_post(sem_t *);
void _rthread_init(void);
struct stack *_rthread_alloc_stack(pthread_t);
Index: lib/librthread/rthread_sem.c
===================================================================
RCS file: /home/cvs/src/lib/librthread/rthread_sem.c,v
retrieving revision 1.32
diff -u -p -r1.32 rthread_sem.c
--- lib/librthread/rthread_sem.c 6 Apr 2020 00:01:08 -0000 1.32
+++ lib/librthread/rthread_sem.c 8 Jul 2020 09:18:34 -0000
@@ -55,7 +55,7 @@
* Internal implementation of semaphores
*/
int
-_sem_wait(sem_t sem, int can_eintr, const struct timespec *abstime,
+_sem_wait(sem_t *sem, int can_eintr, const struct timespec *abstime,
int *delayed_cancel)
{
unsigned int val;
@@ -86,7 +86,7 @@ _sem_wait(sem_t sem, int can_eintr, cons
/* always increment count */
int
-_sem_post(sem_t sem)
+_sem_post(sem_t *sem)
{
membar_exit_before_atomic();
atomic_inc_int(&sem->value);
@@ -98,70 +98,29 @@ _sem_post(sem_t sem)
* exported semaphores
*/
int
-sem_init(sem_t *semp, int pshared, unsigned int value)
+sem_init(sem_t *sem, int pshared, unsigned int value)
{
- sem_t sem;
if (value > SEM_VALUE_MAX) {
errno = EINVAL;
return (-1);
}
- if (pshared) {
- errno = EPERM;
- return (-1);
-#ifdef notyet
- char name[SEM_RANDOM_NAME_LEN];
- sem_t *sempshared;
- int i;
-
- for (;;) {
- for (i = 0; i < SEM_RANDOM_NAME_LEN - 1; i++)
- name[i] = arc4random_uniform(255) + 1;
- name[SEM_RANDOM_NAME_LEN - 1] = '\0';
- sempshared = sem_open(name, O_CREAT | O_EXCL, 0, value);
- if (sempshared != SEM_FAILED)
- break;
- if (errno == EEXIST)
- continue;
- if (errno != EPERM)
- errno = ENOSPC;
- return (-1);
- }
-
- /* unnamed semaphore should not be opened twice */
- if (sem_unlink(name) == -1) {
- sem_close(sempshared);
- errno = ENOSPC;
- return (-1);
- }
-
- *semp = *sempshared;
- free(sempshared);
- return (0);
-#endif
- }
-
- sem = calloc(1, sizeof(*sem));
- if (!sem) {
- errno = ENOSPC;
- return (-1);
- }
+ memset(sem, 0, sizeof(*sem));
sem->value = value;
- *semp = sem;
+ sem->shared = pshared;
return (0);
}
int
-sem_destroy(sem_t *semp)
+sem_destroy(sem_t *sem)
{
- sem_t sem;
if (!_threads_ready) /* for SEM_MMAP_SIZE */
_rthread_init();
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -174,21 +133,19 @@ sem_destroy(sem_t *semp)
return (-1);
}
- *semp = NULL;
if (sem->shared)
munmap(sem, SEM_MMAP_SIZE);
else
- free(sem);
+ memset(sem, 0, sizeof(*sem));
return (0);
}
int
-sem_getvalue(sem_t *semp, int *sval)
+sem_getvalue(sem_t *sem, int *sval)
{
- sem_t sem;
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -199,11 +156,10 @@ sem_getvalue(sem_t *semp, int *sval)
}
int
-sem_post(sem_t *semp)
+sem_post(sem_t *sem)
{
- sem_t sem;
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -214,11 +170,10 @@ sem_post(sem_t *semp)
}
int
-sem_wait(sem_t *semp)
+sem_wait(sem_t *sem)
{
struct tib *tib = TIB_GET();
pthread_t self;
- sem_t sem;
int error;
PREP_CANCEL_POINT(tib);
@@ -226,7 +181,7 @@ sem_wait(sem_t *semp)
_rthread_init();
self = tib->tib_thread;
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -246,15 +201,14 @@ sem_wait(sem_t *semp)
}
int
-sem_timedwait(sem_t *semp, const struct timespec *abstime)
+sem_timedwait(sem_t *sem, const struct timespec *abstime)
{
struct tib *tib = TIB_GET();
pthread_t self;
- sem_t sem;
int error;
PREP_CANCEL_POINT(tib);
- if (!semp || !(sem = *semp) || abstime == NULL ||
+ if (!sem || abstime == NULL ||
abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) {
errno = EINVAL;
return (-1);
@@ -279,12 +233,11 @@ sem_timedwait(sem_t *semp, const struct
}
int
-sem_trywait(sem_t *semp)
+sem_trywait(sem_t *sem)
{
- sem_t sem;
unsigned int val;
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -316,7 +269,7 @@ sem_open(const char *name, int oflag, ..
{
char sempath[SEM_PATH_SIZE];
struct stat sb;
- sem_t sem, *semp;
+ sem_t *sem;
unsigned int value = 0;
int created = 0, fd;
@@ -382,34 +335,24 @@ sem_open(const char *name, int oflag, ..
errno = EINVAL;
return (SEM_FAILED);
}
- semp = malloc(sizeof(*semp));
- if (!semp) {
- munmap(sem, SEM_MMAP_SIZE);
- errno = ENOSPC;
- return (SEM_FAILED);
- }
if (created) {
sem->value = value;
sem->shared = 1;
}
- *semp = sem;
- return (semp);
+ return (sem);
}
int
-sem_close(sem_t *semp)
+sem_close(sem_t *sem)
{
- sem_t sem;
- if (!semp || !(sem = *semp) || !sem->shared) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
- *semp = NULL;
munmap(sem, SEM_MMAP_SIZE);
- free(semp);
return (0);
}
Index: lib/librthread/rthread_sem_compat.c
===================================================================
RCS file: /home/cvs/src/lib/librthread/rthread_sem_compat.c,v
retrieving revision 1.1
diff -u -p -r1.1 rthread_sem_compat.c
--- lib/librthread/rthread_sem_compat.c 8 Jun 2018 13:53:01 -0000 1.1
+++ lib/librthread/rthread_sem_compat.c 8 Jul 2020 09:18:35 -0000
@@ -53,7 +53,7 @@
* Internal implementation of semaphores
*/
int
-_sem_wait(sem_t sem, int can_eintr, const struct timespec *abstime,
+_sem_wait(sem_t *sem, int can_eintr, const struct timespec *abstime,
int *delayed_cancel)
{
void *ident = (void *)&sem->waitcount;
@@ -87,7 +87,7 @@ _sem_wait(sem_t sem, int can_eintr, cons
/* always increment count */
int
-_sem_post(sem_t sem)
+_sem_post(sem_t *sem)
{
void *ident = (void *)&sem->waitcount;
int rv = 0;
@@ -109,71 +109,31 @@ _sem_post(sem_t sem)
* exported semaphores
*/
int
-sem_init(sem_t *semp, int pshared, unsigned int value)
+sem_init(sem_t *sem, int pshared, unsigned int value)
{
- sem_t sem;
if (value > SEM_VALUE_MAX) {
errno = EINVAL;
return (-1);
}
- if (pshared) {
- errno = EPERM;
- return (-1);
-#ifdef notyet
- char name[SEM_RANDOM_NAME_LEN];
- sem_t *sempshared;
- int i;
-
- for (;;) {
- for (i = 0; i < SEM_RANDOM_NAME_LEN - 1; i++)
- name[i] = arc4random_uniform(255) + 1;
- name[SEM_RANDOM_NAME_LEN - 1] = '\0';
- sempshared = sem_open(name, O_CREAT | O_EXCL, 0, value);
- if (sempshared != SEM_FAILED)
- break;
- if (errno == EEXIST)
- continue;
- if (errno != EPERM)
- errno = ENOSPC;
- return (-1);
- }
-
- /* unnamed semaphore should not be opened twice */
- if (sem_unlink(name) == -1) {
- sem_close(sempshared);
- errno = ENOSPC;
- return (-1);
- }
- *semp = *sempshared;
- free(sempshared);
- return (0);
-#endif
- }
-
- sem = calloc(1, sizeof(*sem));
- if (!sem) {
- errno = ENOSPC;
- return (-1);
- }
+ memset(sem, 0, sizeof(*sem));
sem->lock = _SPINLOCK_UNLOCKED;
sem->value = value;
- *semp = sem;
+ sem->shared = pshared;
return (0);
}
int
-sem_destroy(sem_t *semp)
+sem_destroy(sem_t *sem)
{
- sem_t sem;
if (!_threads_ready) /* for SEM_MMAP_SIZE */
_rthread_init();
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -186,21 +146,17 @@ sem_destroy(sem_t *semp)
return (-1);
}
- *semp = NULL;
if (sem->shared)
munmap(sem, SEM_MMAP_SIZE);
- else
- free(sem);
return (0);
}
int
-sem_getvalue(sem_t *semp, int *sval)
+sem_getvalue(sem_t *sem, int *sval)
{
- sem_t sem;
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -213,11 +169,10 @@ sem_getvalue(sem_t *semp, int *sval)
}
int
-sem_post(sem_t *semp)
+sem_post(sem_t *sem)
{
- sem_t sem;
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -228,11 +183,10 @@ sem_post(sem_t *semp)
}
int
-sem_wait(sem_t *semp)
+sem_wait(sem_t *sem)
{
struct tib *tib = TIB_GET();
pthread_t self;
- sem_t sem;
int r;
PREP_CANCEL_POINT(tib);
@@ -240,7 +194,7 @@ sem_wait(sem_t *semp)
_rthread_init();
self = tib->tib_thread;
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -258,15 +212,14 @@ sem_wait(sem_t *semp)
}
int
-sem_timedwait(sem_t *semp, const struct timespec *abstime)
+sem_timedwait(sem_t *sem, const struct timespec *abstime)
{
struct tib *tib = TIB_GET();
pthread_t self;
- sem_t sem;
int r;
PREP_CANCEL_POINT(tib);
- if (!semp || !(sem = *semp) || abstime == NULL ||
+ if (!sem || abstime == NULL ||
abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) {
errno = EINVAL;
return (-1);
@@ -289,12 +242,11 @@ sem_timedwait(sem_t *semp, const struct
}
int
-sem_trywait(sem_t *semp)
+sem_trywait(sem_t *sem)
{
- sem_t sem;
int r;
- if (!semp || !(sem = *semp)) {
+ if (!sem) {
errno = EINVAL;
return (-1);
}
@@ -330,7 +282,7 @@ sem_open(const char *name, int oflag, ..
{
char sempath[SEM_PATH_SIZE];
struct stat sb;
- sem_t sem, *semp;
+ sem_t *sem;
unsigned int value = 0;
int created = 0, fd;
@@ -396,35 +348,25 @@ sem_open(const char *name, int oflag, ..
errno = EINVAL;
return (SEM_FAILED);
}
- semp = malloc(sizeof(*semp));
- if (!semp) {
- munmap(sem, SEM_MMAP_SIZE);
- errno = ENOSPC;
- return (SEM_FAILED);
- }
if (created) {
sem->lock = _SPINLOCK_UNLOCKED;
sem->value = value;
sem->shared = 1;
}
- *semp = sem;
- return (semp);
+ return (sem);
}
int
-sem_close(sem_t *semp)
+sem_close(sem_t *sem)
{
- sem_t sem;
- if (!semp || !(sem = *semp) || !sem->shared) {
+ if (!sem || !sem->shared) {
errno = EINVAL;
return (-1);
}
- *semp = NULL;
munmap(sem, SEM_MMAP_SIZE);
- free(semp);
return (0);
}