unnamed semaphore test
authorSzabolcs Nagy <nsz@port70.net>
Mon, 5 Aug 2013 15:59:48 +0000 (15:59 +0000)
committerSzabolcs Nagy <nsz@port70.net>
Mon, 5 Aug 2013 15:59:48 +0000 (15:59 +0000)
src/functional/sem.c [deleted file]
src/functional/sem_init.c [new file with mode: 0644]
src/functional/sem_open.c [new file with mode: 0644]

diff --git a/src/functional/sem.c b/src/functional/sem.c
deleted file mode 100644 (file)
index 86662b6..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <semaphore.h>
-#include <time.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "test.h"
-
-#define TEST(c, ...) \
-       ( (c) || (t_error(#c " failed: " __VA_ARGS__),0) )
-
-int main(void)
-{
-       char buf[100];
-       struct timespec ts;
-       sem_t *sem, *sem2;
-       int val;
-
-       clock_gettime(CLOCK_REALTIME, &ts);
-       snprintf(buf, sizeof buf, "/testsuite-%d-%d", (int)getpid(), (int)ts.tv_nsec);
-
-       TEST((sem=sem_open(buf, O_CREAT|O_EXCL, 0700, 1)) != SEM_FAILED,
-               "could not open sem: %s\n", strerror(errno));
-       errno = 0;
-       TEST(sem_open(buf, O_CREAT|O_EXCL, 0700, 1) == SEM_FAILED,
-               "reopening should fail with O_EXCL\n");
-       TEST(errno == EEXIST,
-               "after reopen failure errno is \"%s\" (%d); want EEXIST (%d)\n", strerror(errno), errno, EEXIST);
-
-       TEST(sem_getvalue(sem, &val) == 0, "failed to get sem value\n");
-       TEST(val == 1, "wrong initial semaphore value: %d\n", val);
-
-       TEST((sem2=sem_open(buf, 0)) == sem,
-               "could not reopen sem: got %p, want %p\n", sem2, sem);
-
-       errno = 0;
-       TEST(sem_wait(sem) == 0, "%s\n", strerror(errno));
-       TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno));
-       TEST(val == 0, "wrong semaphore value on second handle: %d\n", val);
-
-       errno = 0;
-       TEST(sem_trywait(sem) == -1 && errno == EAGAIN,
-               "trywait on locked sem: got errno \"%s\" (%d), want EAGAIN (%d)\n", strerror(errno), errno, EAGAIN);
-
-       TEST(sem_post(sem) == 0, "%s\n", strerror(errno));
-       TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno));
-       TEST(val == 1, "wrong semaphore value on second handle: %d\n", val);
-
-       TEST(sem_close(sem) == 0, "%s\n", strerror(errno));
-       TEST(sem_close(sem) == 0, "%s\n", strerror(errno));
-       TEST(sem_unlink(buf) == 0, "%s\n", strerror(errno));
-       return t_status;
-}
diff --git a/src/functional/sem_init.c b/src/functional/sem_init.c
new file mode 100644 (file)
index 0000000..0d30f02
--- /dev/null
@@ -0,0 +1,79 @@
+/* unnamed semaphore sanity check */
+#include <pthread.h>
+#include <semaphore.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include "test.h"
+
+#define T(f) if(f) t_error(#f" failed: %s\n", strerror(errno))
+#define T2(r,f) if((r=(f))) t_error(#f" failed: %s\n", strerror(r))
+
+static void *start(void *arg)
+{
+       struct timespec ts;
+       sem_t *s = arg;
+       T(clock_gettime(CLOCK_REALTIME, &ts));
+       ts.tv_sec += 1;
+       T(sem_post(s));
+       T(sem_timedwait(s+1, &ts));
+       return 0;
+}
+
+static void many_waiters()
+{
+       pthread_t t[3];
+       sem_t s[2];
+       int r;
+       void *p;
+
+       T(sem_init(s, 0, 0));
+       T(sem_init(s+1, 0, 0));
+       T2(r,pthread_create(t, 0, start, s));
+       T2(r,pthread_create(t+1, 0, start, s));
+       T2(r,pthread_create(t+2, 0, start, s));
+       T(sem_wait(s));
+       T(sem_wait(s));
+       T(sem_wait(s));
+       T(sem_getvalue(s, &r));
+       if (r)
+               t_error("sem value should be 0, got %d\n", r);
+       T(sem_post(s+1));
+       T(sem_post(s+1));
+       T(sem_post(s+1));
+       T2(r,pthread_join(t[0],&p));
+       T2(r,pthread_join(t[1],&p));
+       T2(r,pthread_join(t[2],&p));
+       T(sem_getvalue(s+1, &r));
+       if (r)
+               t_error("sem value should be 0, got %d\n", r);
+       T(sem_destroy(s));
+       T(sem_destroy(s+1));
+}
+
+static void single_thread()
+{
+       struct timespec ts;
+       sem_t s;
+       int r;
+
+       T(sem_init(&s, 0, 1));
+       T(sem_wait(&s));
+       T(sem_getvalue(&s, &r));
+       if (r)
+               t_error("sem value should be 0, got %d\n", r);
+       if (sem_trywait(&s) != -1 || errno != EAGAIN)
+               t_error("sem_trywait should fail with EAGAIN, got %s\n", strerror(errno));
+       errno = 0;
+       T(clock_gettime(CLOCK_REALTIME, &ts));
+       if (sem_timedwait(&s, &ts)!=-1 || errno != ETIMEDOUT)
+               t_error("sem_timedwait should fail with ETIMEDOUT, got %s\n", strerror(errno));
+       T(sem_destroy(&s));
+}
+
+int main(void)
+{
+       single_thread();
+       many_waiters();
+       return t_status;
+}
diff --git a/src/functional/sem_open.c b/src/functional/sem_open.c
new file mode 100644 (file)
index 0000000..360e491
--- /dev/null
@@ -0,0 +1,56 @@
+/* named semaphore sanity check */
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <semaphore.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "test.h"
+
+#define TEST(c, ...) \
+       ( (c) || (t_error(#c " failed: " __VA_ARGS__),0) )
+
+int main(void)
+{
+       char buf[100];
+       struct timespec ts;
+       sem_t *sem, *sem2;
+       int val;
+
+       clock_gettime(CLOCK_REALTIME, &ts);
+       snprintf(buf, sizeof buf, "/testsuite-%d-%d", (int)getpid(), (int)ts.tv_nsec);
+
+       TEST((sem=sem_open(buf, O_CREAT|O_EXCL, 0700, 1)) != SEM_FAILED,
+               "could not open sem: %s\n", strerror(errno));
+       errno = 0;
+       TEST(sem_open(buf, O_CREAT|O_EXCL, 0700, 1) == SEM_FAILED,
+               "reopening should fail with O_EXCL\n");
+       TEST(errno == EEXIST,
+               "after reopen failure errno is \"%s\" (%d); want EEXIST (%d)\n", strerror(errno), errno, EEXIST);
+
+       TEST(sem_getvalue(sem, &val) == 0, "failed to get sem value\n");
+       TEST(val == 1, "wrong initial semaphore value: %d\n", val);
+
+       TEST((sem2=sem_open(buf, 0)) == sem,
+               "could not reopen sem: got %p, want %p\n", sem2, sem);
+
+       errno = 0;
+       TEST(sem_wait(sem) == 0, "%s\n", strerror(errno));
+       TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno));
+       TEST(val == 0, "wrong semaphore value on second handle: %d\n", val);
+
+       errno = 0;
+       TEST(sem_trywait(sem) == -1 && errno == EAGAIN,
+               "trywait on locked sem: got errno \"%s\" (%d), want EAGAIN (%d)\n", strerror(errno), errno, EAGAIN);
+
+       TEST(sem_post(sem) == 0, "%s\n", strerror(errno));
+       TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno));
+       TEST(val == 1, "wrong semaphore value on second handle: %d\n", val);
+
+       TEST(sem_close(sem) == 0, "%s\n", strerror(errno));
+       TEST(sem_close(sem) == 0, "%s\n", strerror(errno));
+       TEST(sem_unlink(buf) == 0, "%s\n", strerror(errno));
+       return t_status;
+}