113546fd1SIngo Weinhold/*
213546fd1SIngo Weinhold * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
313546fd1SIngo Weinhold * Distributed under the terms of the MIT License.
413546fd1SIngo Weinhold */
513546fd1SIngo Weinhold
613546fd1SIngo Weinhold#include <errno.h>
713546fd1SIngo Weinhold#include <fcntl.h>
813546fd1SIngo Weinhold#include <stdint.h>
913546fd1SIngo Weinhold#include <stdio.h>
1013546fd1SIngo Weinhold#include <stdlib.h>
1113546fd1SIngo Weinhold#include <string.h>
1213546fd1SIngo Weinhold#include <unistd.h>
1313546fd1SIngo Weinhold#include <semaphore.h>
14e01137a6SIngo Weinhold#include <sys/mman.h>
1513546fd1SIngo Weinhold#include <sys/stat.h>
1613546fd1SIngo Weinhold#include <sys/time.h>
1713546fd1SIngo Weinhold#include <sys/wait.h>
1813546fd1SIngo Weinhold#include <time.h>
1913546fd1SIngo Weinhold
2013546fd1SIngo Weinhold
2113546fd1SIngo Weinhold#ifdef __HAIKU__
2213546fd1SIngo Weinhold#	include <OS.h>
2313546fd1SIngo Weinhold#else
2413546fd1SIngo Weinhold
2513546fd1SIngo Weinholdtypedef int64_t bigtime_t;
2613546fd1SIngo Weinhold
2713546fd1SIngo Weinholdstatic bigtime_t
2813546fd1SIngo Weinholdsystem_time()
2913546fd1SIngo Weinhold{
3013546fd1SIngo Weinhold	timeval tv;
3113546fd1SIngo Weinhold	gettimeofday(&tv, NULL);
3213546fd1SIngo Weinhold	return (bigtime_t)tv.tv_sec * 1000000 + tv.tv_usec;
3313546fd1SIngo Weinhold}
3413546fd1SIngo Weinhold
3513546fd1SIngo Weinhold
3613546fd1SIngo Weinhold#endif	// !__HAIKU__
3713546fd1SIngo Weinhold
38cefb0690SSalvatore Benedetto#include "TestUnitUtils.h"
39e01137a6SIngo Weinhold
40e01137a6SIngo Weinhold#if 0
41e01137a6SIngo Weinholdstatic void
42e01137a6SIngo Weinholddump_sem(const char* name, sem_t* sem)
43e01137a6SIngo Weinhold{
44e01137a6SIngo Weinhold	printf("%s, %p: ", name, sem);
45e01137a6SIngo Weinhold	for (size_t i = 0; i < sizeof(sem_t); i++)
46e01137a6SIngo Weinhold		printf("%02x", ((char*)sem)[i]);
47e01137a6SIngo Weinhold	printf("\n");
4813546fd1SIngo Weinhold}
49e01137a6SIngo Weinhold#endif
5013546fd1SIngo Weinhold
5113546fd1SIngo Weinhold
5213546fd1SIngo Weinholdstatic const char* const kSemName1 = "/test_sem1";
5313546fd1SIngo Weinhold
5413546fd1SIngo Weinhold
5513546fd1SIngo Weinholdstatic void
5613546fd1SIngo Weinholdtest_open_close_unlink()
5713546fd1SIngo Weinhold{
58e01137a6SIngo Weinhold	TEST_SET("sem_{open,close,unlink}()");
59e01137a6SIngo Weinhold
6013546fd1SIngo Weinhold	const char* currentTest = NULL;
6113546fd1SIngo Weinhold
6213546fd1SIngo Weinhold	// open non-existing with O_CREAT
6313546fd1SIngo Weinhold	TEST("sem_open(O_CREAT) non-existing");
6413546fd1SIngo Weinhold	sem_t* sem = sem_open(kSemName1, O_CREAT, S_IRUSR | S_IWUSR, 1);
6513546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
6613546fd1SIngo Weinhold
6713546fd1SIngo Weinhold	// close
6813546fd1SIngo Weinhold	TEST("sem_close()");
6913546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
7013546fd1SIngo Weinhold
7113546fd1SIngo Weinhold	// open existing with O_CREAT
7213546fd1SIngo Weinhold	TEST("sem_open(O_CREAT) existing");
7313546fd1SIngo Weinhold	sem = sem_open(kSemName1, O_CREAT, S_IRUSR | S_IWUSR, 1);
7413546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
7513546fd1SIngo Weinhold
7613546fd1SIngo Weinhold	// close
7713546fd1SIngo Weinhold	TEST("sem_close()");
7813546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
7913546fd1SIngo Weinhold
8013546fd1SIngo Weinhold	// open existing without O_CREAT
8113546fd1SIngo Weinhold	TEST("sem_open() existing");
8213546fd1SIngo Weinhold	sem = sem_open(kSemName1, 0);
8313546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
8413546fd1SIngo Weinhold
8513546fd1SIngo Weinhold	// re-open existing without O_CREAT
8613546fd1SIngo Weinhold	TEST("sem_open() existing");
8713546fd1SIngo Weinhold	sem_t* sem2 = sem_open(kSemName1, 0);
8813546fd1SIngo Weinhold	assert_posix_bool_success(sem2 != SEM_FAILED);
8913546fd1SIngo Weinhold	assert_equals(sem, sem2);
9013546fd1SIngo Weinhold
9113546fd1SIngo Weinhold	// close
9213546fd1SIngo Weinhold	TEST("sem_close()");
9313546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
9413546fd1SIngo Weinhold
9513546fd1SIngo Weinhold	// close
9613546fd1SIngo Weinhold	TEST("sem_close()");
9713546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
9813546fd1SIngo Weinhold
9913546fd1SIngo Weinhold	// open existing with O_CREAT | O_EXCL
10013546fd1SIngo Weinhold	TEST("sem_open(O_CREAT | O_EXCL) existing");
10113546fd1SIngo Weinhold	sem = sem_open(kSemName1, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 1);
10213546fd1SIngo Weinhold	assert_posix_bool_error(EEXIST, sem != SEM_FAILED);
10313546fd1SIngo Weinhold
10413546fd1SIngo Weinhold	// open existing without O_CREAT
10513546fd1SIngo Weinhold	TEST("sem_open() existing");
10613546fd1SIngo Weinhold	sem = sem_open(kSemName1, 0);
10713546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
10813546fd1SIngo Weinhold
10913546fd1SIngo Weinhold	// unlink
11013546fd1SIngo Weinhold	TEST("unlink() existing");
11113546fd1SIngo Weinhold	assert_posix_success(sem_unlink(kSemName1));
11213546fd1SIngo Weinhold
11313546fd1SIngo Weinhold	// open non-existing with O_CREAT | O_EXCL
11413546fd1SIngo Weinhold	TEST("sem_open(O_CREAT | O_EXCL) non-existing");
11513546fd1SIngo Weinhold	sem2 = sem_open(kSemName1, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 2);
11613546fd1SIngo Weinhold	assert_posix_bool_success(sem2 != SEM_FAILED);
11713546fd1SIngo Weinhold	assert_equals_not(sem, sem2);
11813546fd1SIngo Weinhold
11913546fd1SIngo Weinhold	// unlink
12013546fd1SIngo Weinhold	TEST("unlink() existing");
12113546fd1SIngo Weinhold	assert_posix_success(sem_unlink(kSemName1));
12213546fd1SIngo Weinhold
12313546fd1SIngo Weinhold	// unlink
12413546fd1SIngo Weinhold	TEST("unlink() non-existing");
12513546fd1SIngo Weinhold	assert_posix_error(ENOENT, sem_unlink(kSemName1));
12613546fd1SIngo Weinhold
12713546fd1SIngo Weinhold	// close
12813546fd1SIngo Weinhold	TEST("sem_close()");
12913546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
13013546fd1SIngo Weinhold
13113546fd1SIngo Weinhold	// close
13213546fd1SIngo Weinhold	TEST("sem_close()");
13313546fd1SIngo Weinhold	assert_posix_success(sem_close(sem2));
13413546fd1SIngo Weinhold
13513546fd1SIngo Weinhold	TEST("done");
13613546fd1SIngo Weinhold}
13713546fd1SIngo Weinhold
13813546fd1SIngo Weinhold
13913546fd1SIngo Weinholdstatic void
14013546fd1SIngo Weinholdtest_init_destroy()
14113546fd1SIngo Weinhold{
142e01137a6SIngo Weinhold	TEST_SET("sem_{init,destroy}()");
143e01137a6SIngo Weinhold
14413546fd1SIngo Weinhold	const char* currentTest = NULL;
14513546fd1SIngo Weinhold
14613546fd1SIngo Weinhold	// init
14713546fd1SIngo Weinhold	TEST("sem_init()");
14813546fd1SIngo Weinhold	sem_t sem;
14913546fd1SIngo Weinhold	assert_posix_success(sem_init(&sem, 0, 1));
15013546fd1SIngo Weinhold
15113546fd1SIngo Weinhold	// destroy
15213546fd1SIngo Weinhold	TEST("sem_destroy()");
15313546fd1SIngo Weinhold	assert_posix_success(sem_destroy(&sem));
15413546fd1SIngo Weinhold
15513546fd1SIngo Weinhold	// init
15613546fd1SIngo Weinhold	TEST("sem_init()");
15713546fd1SIngo Weinhold	assert_posix_success(sem_init(&sem, 0, 1));
15813546fd1SIngo Weinhold
15913546fd1SIngo Weinhold	// init
16013546fd1SIngo Weinhold	TEST("sem_init()");
16113546fd1SIngo Weinhold	sem_t sem2;
16213546fd1SIngo Weinhold	assert_posix_success(sem_init(&sem2, 0, 2));
16313546fd1SIngo Weinhold
16413546fd1SIngo Weinhold	// destroy
16513546fd1SIngo Weinhold	TEST("sem_destroy()");
16613546fd1SIngo Weinhold	assert_posix_success(sem_destroy(&sem));
16713546fd1SIngo Weinhold
16813546fd1SIngo Weinhold	// destroy
16913546fd1SIngo Weinhold	TEST("sem_destroy()");
17013546fd1SIngo Weinhold	assert_posix_success(sem_destroy(&sem2));
17113546fd1SIngo Weinhold
17213546fd1SIngo Weinhold	TEST("done");
17313546fd1SIngo Weinhold}
17413546fd1SIngo Weinhold
17513546fd1SIngo Weinhold
17613546fd1SIngo Weinholdstatic void
17713546fd1SIngo Weinholdtest_open_close_fork()
17813546fd1SIngo Weinhold{
179e01137a6SIngo Weinhold	TEST_SET("sem_{open,close}() with fork()");
180e01137a6SIngo Weinhold
18113546fd1SIngo Weinhold	const char* currentTest = NULL;
18213546fd1SIngo Weinhold
18313546fd1SIngo Weinhold	// open non-existing with O_CREAT
18413546fd1SIngo Weinhold	TEST("sem_open(O_CREAT) non-existing");
18513546fd1SIngo Weinhold	sem_t* sem = sem_open(kSemName1, O_CREAT, S_IRUSR | S_IWUSR, 1);
18613546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
18713546fd1SIngo Weinhold
18813546fd1SIngo Weinhold	TEST("close_sem() forked");
18913546fd1SIngo Weinhold	pid_t child = fork();
19013546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
19113546fd1SIngo Weinhold
19213546fd1SIngo Weinhold	if (child == 0) {
19313546fd1SIngo Weinhold		// child
19413546fd1SIngo Weinhold		assert_posix_success(sem_close(sem));
19513546fd1SIngo Weinhold		exit(0);
19613546fd1SIngo Weinhold	} else {
19713546fd1SIngo Weinhold		// parent
19813546fd1SIngo Weinhold		assert_posix_success(sem_close(sem));
19913546fd1SIngo Weinhold		wait_for_child(child);
20013546fd1SIngo Weinhold	}
20113546fd1SIngo Weinhold
20213546fd1SIngo Weinhold	TEST("sem_open() existing forked");
20313546fd1SIngo Weinhold	child = fork();
20413546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
20513546fd1SIngo Weinhold
20613546fd1SIngo Weinhold	if (child == 0) {
20713546fd1SIngo Weinhold		// child
20813546fd1SIngo Weinhold		sem = sem_open(kSemName1, O_CREAT);
20913546fd1SIngo Weinhold		assert_posix_bool_success(sem != SEM_FAILED);
21013546fd1SIngo Weinhold		exit(0);
21113546fd1SIngo Weinhold	} else {
21213546fd1SIngo Weinhold		// parent
21313546fd1SIngo Weinhold		sem = sem_open(kSemName1, O_CREAT);
21413546fd1SIngo Weinhold		wait_for_child(child);
21513546fd1SIngo Weinhold		assert_posix_success(sem_close(sem));
21613546fd1SIngo Weinhold	}
21713546fd1SIngo Weinhold
21813546fd1SIngo Weinhold	TEST("done");
21913546fd1SIngo Weinhold}
22013546fd1SIngo Weinhold
22113546fd1SIngo Weinhold
22213546fd1SIngo Weinholdstatic void
22313546fd1SIngo Weinholdtest_init_destroy_fork()
22413546fd1SIngo Weinhold{
225e01137a6SIngo Weinhold	TEST_SET("sem_{init,destroy}() with fork()");
226e01137a6SIngo Weinhold
22713546fd1SIngo Weinhold	const char* currentTest = NULL;
22813546fd1SIngo Weinhold
22913546fd1SIngo Weinhold	// init
23013546fd1SIngo Weinhold	TEST("sem_init()");
23113546fd1SIngo Weinhold	sem_t sem;
23213546fd1SIngo Weinhold	assert_posix_success(sem_init(&sem, 0, 1));
23313546fd1SIngo Weinhold
23413546fd1SIngo Weinhold	// destroy
23513546fd1SIngo Weinhold	TEST("sem_destroy() forked");
23613546fd1SIngo Weinhold	pid_t child = fork();
23713546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
23813546fd1SIngo Weinhold
23913546fd1SIngo Weinhold	if (child == 0) {
24013546fd1SIngo Weinhold		// child
24113546fd1SIngo Weinhold		assert_posix_success(sem_destroy(&sem));
24213546fd1SIngo Weinhold		exit(0);
24313546fd1SIngo Weinhold	} else {
24413546fd1SIngo Weinhold		// parent
24513546fd1SIngo Weinhold		assert_posix_success(sem_destroy(&sem));
24613546fd1SIngo Weinhold		wait_for_child(child);
24713546fd1SIngo Weinhold	}
24813546fd1SIngo Weinhold
24913546fd1SIngo Weinhold	TEST("done");
25013546fd1SIngo Weinhold}
25113546fd1SIngo Weinhold
25213546fd1SIngo Weinhold
25313546fd1SIngo Weinholdstatic void
25413546fd1SIngo Weinholdtest_post_wait_named()
25513546fd1SIngo Weinhold{
256e01137a6SIngo Weinhold	TEST_SET("sem_{post,wait,trywait,timedwait}() named semaphore");
257e01137a6SIngo Weinhold
25813546fd1SIngo Weinhold	const char* currentTest = NULL;
25913546fd1SIngo Weinhold
26013546fd1SIngo Weinhold	// make sure the sem doesn't exist yet
26113546fd1SIngo Weinhold	sem_unlink(kSemName1);
26213546fd1SIngo Weinhold
26313546fd1SIngo Weinhold	// open non-existing with O_CREAT
26413546fd1SIngo Weinhold	TEST("sem_open(O_CREAT) non-existing");
26513546fd1SIngo Weinhold	sem_t* sem = sem_open(kSemName1, O_CREAT, S_IRUSR | S_IWUSR, 1);
26613546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
26713546fd1SIngo Weinhold
26813546fd1SIngo Weinhold	TEST("sem_getvalue()");
26913546fd1SIngo Weinhold	int value;
27013546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
27113546fd1SIngo Weinhold	assert_equals(1, value);
27213546fd1SIngo Weinhold
27313546fd1SIngo Weinhold	// post
27413546fd1SIngo Weinhold	TEST("sem_post() no waiting");
27513546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
27613546fd1SIngo Weinhold
27713546fd1SIngo Weinhold	TEST("sem_getvalue()");
27813546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
27913546fd1SIngo Weinhold	assert_equals(2, value);
28013546fd1SIngo Weinhold
28113546fd1SIngo Weinhold	// wait
28213546fd1SIngo Weinhold	TEST("sem_wait() non-blocking");
28313546fd1SIngo Weinhold	assert_posix_success(sem_wait(sem));
28413546fd1SIngo Weinhold
28513546fd1SIngo Weinhold	TEST("sem_getvalue()");
28613546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
28713546fd1SIngo Weinhold	assert_equals(1, value);
28813546fd1SIngo Weinhold
28913546fd1SIngo Weinhold	// wait
29013546fd1SIngo Weinhold	TEST("sem_wait() non-blocking");
29113546fd1SIngo Weinhold	assert_posix_success(sem_wait(sem));
29213546fd1SIngo Weinhold
29313546fd1SIngo Weinhold	TEST("sem_getvalue()");
29413546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
29513546fd1SIngo Weinhold	assert_equals(0, value);
29613546fd1SIngo Weinhold
29713546fd1SIngo Weinhold	// close
29813546fd1SIngo Weinhold	TEST("sem_close()");
29913546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
30013546fd1SIngo Weinhold
30113546fd1SIngo Weinhold	// re-open existing
30213546fd1SIngo Weinhold	TEST("sem_open() existing");
30313546fd1SIngo Weinhold	sem = sem_open(kSemName1, 0);
30413546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
30513546fd1SIngo Weinhold
30613546fd1SIngo Weinhold	TEST("sem_getvalue()");
30713546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
30813546fd1SIngo Weinhold	assert_equals(0, value);
30913546fd1SIngo Weinhold
31013546fd1SIngo Weinhold	// post
31113546fd1SIngo Weinhold	TEST("sem_post() no waiting");
31213546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
31313546fd1SIngo Weinhold
31413546fd1SIngo Weinhold	TEST("sem_getvalue()");
31513546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
31613546fd1SIngo Weinhold	assert_equals(1, value);
31713546fd1SIngo Weinhold
31813546fd1SIngo Weinhold	// post
31913546fd1SIngo Weinhold	TEST("sem_post() no waiting");
32013546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
32113546fd1SIngo Weinhold
32213546fd1SIngo Weinhold	TEST("sem_getvalue()");
32313546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
32413546fd1SIngo Weinhold	assert_equals(2, value);
32513546fd1SIngo Weinhold
32613546fd1SIngo Weinhold	// trywait
32713546fd1SIngo Weinhold	TEST("sem_trywait() success");
32813546fd1SIngo Weinhold	assert_posix_success(sem_trywait(sem));
32913546fd1SIngo Weinhold
33013546fd1SIngo Weinhold	TEST("sem_getvalue()");
33113546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
33213546fd1SIngo Weinhold	assert_equals(1, value);
33313546fd1SIngo Weinhold
33413546fd1SIngo Weinhold	// trywait
33513546fd1SIngo Weinhold	TEST("sem_trywait() success");
33613546fd1SIngo Weinhold	assert_posix_success(sem_trywait(sem));
33713546fd1SIngo Weinhold
33813546fd1SIngo Weinhold	TEST("sem_getvalue()");
33913546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
34013546fd1SIngo Weinhold	assert_equals(0, value);
34113546fd1SIngo Weinhold
34213546fd1SIngo Weinhold	// trywait failure
34313546fd1SIngo Weinhold	TEST("sem_trywait() failure");
34413546fd1SIngo Weinhold	assert_posix_error(EAGAIN, sem_trywait(sem));
34513546fd1SIngo Weinhold
34613546fd1SIngo Weinhold	TEST("sem_getvalue()");
34713546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
34813546fd1SIngo Weinhold	assert_equals(0, value);
34913546fd1SIngo Weinhold
35013546fd1SIngo Weinhold	// post
35113546fd1SIngo Weinhold	TEST("sem_post() no waiting");
35213546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
35313546fd1SIngo Weinhold
35413546fd1SIngo Weinhold	TEST("sem_getvalue()");
35513546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
35613546fd1SIngo Weinhold	assert_equals(1, value);
35713546fd1SIngo Weinhold
35813546fd1SIngo Weinhold	// post
35913546fd1SIngo Weinhold	TEST("sem_post() no waiting");
36013546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
36113546fd1SIngo Weinhold
36213546fd1SIngo Weinhold	TEST("sem_getvalue()");
36313546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
36413546fd1SIngo Weinhold	assert_equals(2, value);
36513546fd1SIngo Weinhold
36613546fd1SIngo Weinhold	// timedwait
36713546fd1SIngo Weinhold	TEST("sem_timedwait() success");
36813546fd1SIngo Weinhold	timespec timeout;
36913546fd1SIngo Weinhold	assert_posix_success(sem_timedwait(sem,
37013546fd1SIngo Weinhold		absolute_timeout(timeout, 1000000)));
37113546fd1SIngo Weinhold
37213546fd1SIngo Weinhold	TEST("sem_getvalue()");
37313546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
37413546fd1SIngo Weinhold	assert_equals(1, value);
37513546fd1SIngo Weinhold
37613546fd1SIngo Weinhold	TEST("sem_timedwait() success");
37713546fd1SIngo Weinhold	assert_posix_success(sem_timedwait(sem,
37813546fd1SIngo Weinhold		absolute_timeout(timeout, 1000000)));
37913546fd1SIngo Weinhold
38013546fd1SIngo Weinhold	TEST("sem_getvalue()");
38113546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
38213546fd1SIngo Weinhold	assert_equals(0, value);
38313546fd1SIngo Weinhold
38413546fd1SIngo Weinhold	TEST("sem_timedwait() timeout");
38513546fd1SIngo Weinhold	bigtime_t startTime = system_time();
38613546fd1SIngo Weinhold	assert_posix_error(ETIMEDOUT, sem_timedwait(sem,
38713546fd1SIngo Weinhold		absolute_timeout(timeout, 1000000)));
38813546fd1SIngo Weinhold	bigtime_t diffTime = system_time() - startTime;
38913546fd1SIngo Weinhold	assert_time_equals(1000000, diffTime);
39013546fd1SIngo Weinhold
39113546fd1SIngo Weinhold	TEST("sem_getvalue()");
39213546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
39313546fd1SIngo Weinhold	assert_equals(0, value);
39413546fd1SIngo Weinhold
39513546fd1SIngo Weinhold	// close
39613546fd1SIngo Weinhold	TEST("sem_close()");
39713546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
39813546fd1SIngo Weinhold
39913546fd1SIngo Weinhold	TEST("done");
40013546fd1SIngo Weinhold}
40113546fd1SIngo Weinhold
40213546fd1SIngo Weinhold
40313546fd1SIngo Weinholdstatic void
40413546fd1SIngo Weinholdtest_post_wait_unnamed()
40513546fd1SIngo Weinhold{
406e01137a6SIngo Weinhold	TEST_SET("sem_{post,wait,trywait,timedwait}() unnamed semaphore");
407e01137a6SIngo Weinhold
40813546fd1SIngo Weinhold	const char* currentTest = NULL;
40913546fd1SIngo Weinhold
41013546fd1SIngo Weinhold	// init
41113546fd1SIngo Weinhold	TEST("sem_init()");
41213546fd1SIngo Weinhold	sem_t _sem;
41313546fd1SIngo Weinhold	assert_posix_success(sem_init(&_sem, 0, 1));
41413546fd1SIngo Weinhold	sem_t* sem = &_sem;
41513546fd1SIngo Weinhold
41613546fd1SIngo Weinhold	TEST("sem_getvalue()");
41713546fd1SIngo Weinhold	int value;
41813546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
41913546fd1SIngo Weinhold	assert_equals(1, value);
42013546fd1SIngo Weinhold
42113546fd1SIngo Weinhold	// post
42213546fd1SIngo Weinhold	TEST("sem_post() no waiting");
42313546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
42413546fd1SIngo Weinhold
42513546fd1SIngo Weinhold	TEST("sem_getvalue()");
42613546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
42713546fd1SIngo Weinhold	assert_equals(2, value);
42813546fd1SIngo Weinhold
42913546fd1SIngo Weinhold	// wait
43013546fd1SIngo Weinhold	TEST("sem_wait() non-blocking");
43113546fd1SIngo Weinhold	assert_posix_success(sem_wait(sem));
43213546fd1SIngo Weinhold
43313546fd1SIngo Weinhold	TEST("sem_getvalue()");
43413546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
43513546fd1SIngo Weinhold	assert_equals(1, value);
43613546fd1SIngo Weinhold
43713546fd1SIngo Weinhold	// wait
43813546fd1SIngo Weinhold	TEST("sem_wait() non-blocking");
43913546fd1SIngo Weinhold	assert_posix_success(sem_wait(sem));
44013546fd1SIngo Weinhold
44113546fd1SIngo Weinhold	TEST("sem_getvalue()");
44213546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
44313546fd1SIngo Weinhold	assert_equals(0, value);
44413546fd1SIngo Weinhold
44513546fd1SIngo Weinhold	// post
44613546fd1SIngo Weinhold	TEST("sem_post() no waiting");
44713546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
44813546fd1SIngo Weinhold
44913546fd1SIngo Weinhold	TEST("sem_getvalue()");
45013546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
45113546fd1SIngo Weinhold	assert_equals(1, value);
45213546fd1SIngo Weinhold
45313546fd1SIngo Weinhold	// post
45413546fd1SIngo Weinhold	TEST("sem_post() no waiting");
45513546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
45613546fd1SIngo Weinhold
45713546fd1SIngo Weinhold	TEST("sem_getvalue()");
45813546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
45913546fd1SIngo Weinhold	assert_equals(2, value);
46013546fd1SIngo Weinhold
46113546fd1SIngo Weinhold	// trywait
46213546fd1SIngo Weinhold	TEST("sem_trywait() success");
46313546fd1SIngo Weinhold	assert_posix_success(sem_trywait(sem));
46413546fd1SIngo Weinhold
46513546fd1SIngo Weinhold	TEST("sem_getvalue()");
46613546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
46713546fd1SIngo Weinhold	assert_equals(1, value);
46813546fd1SIngo Weinhold
46913546fd1SIngo Weinhold	// trywait
47013546fd1SIngo Weinhold	TEST("sem_trywait() success");
47113546fd1SIngo Weinhold	assert_posix_success(sem_trywait(sem));
47213546fd1SIngo Weinhold
47313546fd1SIngo Weinhold	TEST("sem_getvalue()");
47413546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
47513546fd1SIngo Weinhold	assert_equals(0, value);
47613546fd1SIngo Weinhold
47713546fd1SIngo Weinhold	// trywait failure
47813546fd1SIngo Weinhold	TEST("sem_trywait() failure");
47913546fd1SIngo Weinhold	assert_posix_error(EAGAIN, sem_trywait(sem));
48013546fd1SIngo Weinhold
48113546fd1SIngo Weinhold	TEST("sem_getvalue()");
48213546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
48313546fd1SIngo Weinhold	assert_equals(0, value);
48413546fd1SIngo Weinhold
48513546fd1SIngo Weinhold	// post
48613546fd1SIngo Weinhold	TEST("sem_post() no waiting");
48713546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
48813546fd1SIngo Weinhold
48913546fd1SIngo Weinhold	TEST("sem_getvalue()");
49013546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
49113546fd1SIngo Weinhold	assert_equals(1, value);
49213546fd1SIngo Weinhold
49313546fd1SIngo Weinhold	// post
49413546fd1SIngo Weinhold	TEST("sem_post() no waiting");
49513546fd1SIngo Weinhold	assert_posix_success(sem_post(sem));
49613546fd1SIngo Weinhold
49713546fd1SIngo Weinhold	TEST("sem_getvalue()");
49813546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
49913546fd1SIngo Weinhold	assert_equals(2, value);
50013546fd1SIngo Weinhold
50113546fd1SIngo Weinhold	// timedwait
50213546fd1SIngo Weinhold	TEST("sem_timedwait() success");
50313546fd1SIngo Weinhold	timespec timeout;
50413546fd1SIngo Weinhold	assert_posix_success(sem_timedwait(sem,
50513546fd1SIngo Weinhold		absolute_timeout(timeout, 1000000)));
50613546fd1SIngo Weinhold
50713546fd1SIngo Weinhold	TEST("sem_getvalue()");
50813546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
50913546fd1SIngo Weinhold	assert_equals(1, value);
51013546fd1SIngo Weinhold
51113546fd1SIngo Weinhold	TEST("sem_timedwait() success");
51213546fd1SIngo Weinhold	assert_posix_success(sem_timedwait(sem,
51313546fd1SIngo Weinhold		absolute_timeout(timeout, 1000000)));
51413546fd1SIngo Weinhold
51513546fd1SIngo Weinhold	TEST("sem_getvalue()");
51613546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
51713546fd1SIngo Weinhold	assert_equals(0, value);
51813546fd1SIngo Weinhold
51913546fd1SIngo Weinhold	TEST("sem_timedwait() timeout");
52013546fd1SIngo Weinhold	bigtime_t startTime = system_time();
52113546fd1SIngo Weinhold	assert_posix_error(ETIMEDOUT, sem_timedwait(sem,
52213546fd1SIngo Weinhold		absolute_timeout(timeout, 1000000)));
52313546fd1SIngo Weinhold	bigtime_t diffTime = system_time() - startTime;
52413546fd1SIngo Weinhold	assert_time_equals(1000000, diffTime);
52513546fd1SIngo Weinhold
52613546fd1SIngo Weinhold	TEST("sem_getvalue()");
52713546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
52813546fd1SIngo Weinhold	assert_equals(0, value);
52913546fd1SIngo Weinhold
53013546fd1SIngo Weinhold	// destroy
53113546fd1SIngo Weinhold	TEST("sem_destroy()");
53213546fd1SIngo Weinhold	assert_posix_success(sem_destroy(sem));
53313546fd1SIngo Weinhold
53413546fd1SIngo Weinhold	TEST("done");
53513546fd1SIngo Weinhold}
53613546fd1SIngo Weinhold
53713546fd1SIngo Weinhold
53813546fd1SIngo Weinholdstatic void
53913546fd1SIngo Weinholdtest_post_wait_named_fork()
54013546fd1SIngo Weinhold{
541e01137a6SIngo Weinhold	TEST_SET("sem_{post,wait,trywait,timedwait}() named semaphore with fork()");
542e01137a6SIngo Weinhold
54313546fd1SIngo Weinhold	const char* currentTest = NULL;
54413546fd1SIngo Weinhold
54513546fd1SIngo Weinhold	// make sure the sem doesn't exist yet
54613546fd1SIngo Weinhold	sem_unlink(kSemName1);
54713546fd1SIngo Weinhold
54813546fd1SIngo Weinhold	// open non-existing with O_CREAT
54913546fd1SIngo Weinhold	TEST("sem_open(O_CREAT) non-existing");
55013546fd1SIngo Weinhold	sem_t* sem = sem_open(kSemName1, O_CREAT, S_IRUSR | S_IWUSR, 0);
55113546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
55213546fd1SIngo Weinhold
55313546fd1SIngo Weinhold	TEST("sem_getvalue()");
55413546fd1SIngo Weinhold	int value;
55513546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
55613546fd1SIngo Weinhold	assert_equals(0, value);
55713546fd1SIngo Weinhold
55813546fd1SIngo Weinhold	TEST("unblock child after wait");
55913546fd1SIngo Weinhold	pid_t child = fork();
56013546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
56113546fd1SIngo Weinhold
56213546fd1SIngo Weinhold	if (child == 0) {
56313546fd1SIngo Weinhold		// child
56413546fd1SIngo Weinhold		bigtime_t startTime = system_time();
56513546fd1SIngo Weinhold		assert_posix_success(sem_wait(sem));
56613546fd1SIngo Weinhold		bigtime_t diffTime = system_time() - startTime;
56713546fd1SIngo Weinhold		assert_time_equals(1000000, diffTime);
56813546fd1SIngo Weinhold
56913546fd1SIngo Weinhold		exit(0);
57013546fd1SIngo Weinhold	} else {
57113546fd1SIngo Weinhold		// parent
57213546fd1SIngo Weinhold		sleep(1);
57313546fd1SIngo Weinhold		assert_posix_success(sem_post(sem));
57413546fd1SIngo Weinhold		wait_for_child(child);
57513546fd1SIngo Weinhold	}
57613546fd1SIngo Weinhold
57713546fd1SIngo Weinhold	TEST("sem_getvalue()");
57813546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
57913546fd1SIngo Weinhold	assert_equals(0, value);
58013546fd1SIngo Weinhold
58113546fd1SIngo Weinhold	TEST("unblock parent after wait");
58213546fd1SIngo Weinhold	child = fork();
58313546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
58413546fd1SIngo Weinhold
58513546fd1SIngo Weinhold	if (child == 0) {
58613546fd1SIngo Weinhold		// child
58713546fd1SIngo Weinhold		sleep(1);
58813546fd1SIngo Weinhold		assert_posix_success(sem_post(sem));
58913546fd1SIngo Weinhold
59013546fd1SIngo Weinhold		exit(0);
59113546fd1SIngo Weinhold	} else {
59213546fd1SIngo Weinhold		// parent
59313546fd1SIngo Weinhold		bigtime_t startTime = system_time();
59413546fd1SIngo Weinhold		assert_posix_success(sem_wait(sem));
59513546fd1SIngo Weinhold		bigtime_t diffTime = system_time() - startTime;
59613546fd1SIngo Weinhold		assert_time_equals(1000000, diffTime);
59713546fd1SIngo Weinhold
59813546fd1SIngo Weinhold		wait_for_child(child);
59913546fd1SIngo Weinhold	}
60013546fd1SIngo Weinhold
60113546fd1SIngo Weinhold	TEST("sem_getvalue()");
60213546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
60313546fd1SIngo Weinhold	assert_equals(0, value);
60413546fd1SIngo Weinhold
60513546fd1SIngo Weinhold	TEST("unblock child after wait before timeout");
60613546fd1SIngo Weinhold	child = fork();
60713546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
60813546fd1SIngo Weinhold
60913546fd1SIngo Weinhold	if (child == 0) {
61013546fd1SIngo Weinhold		// child
61113546fd1SIngo Weinhold		timespec timeout;
61213546fd1SIngo Weinhold		bigtime_t startTime = system_time();
61313546fd1SIngo Weinhold		assert_posix_success(sem_timedwait(sem,
61413546fd1SIngo Weinhold			absolute_timeout(timeout, 2000000)));
61513546fd1SIngo Weinhold		bigtime_t diffTime = system_time() - startTime;
61613546fd1SIngo Weinhold		assert_time_equals(1000000, diffTime);
61713546fd1SIngo Weinhold
61813546fd1SIngo Weinhold		exit(0);
61913546fd1SIngo Weinhold	} else {
62013546fd1SIngo Weinhold		// parent
62113546fd1SIngo Weinhold		sleep(1);
62213546fd1SIngo Weinhold		assert_posix_success(sem_post(sem));
62313546fd1SIngo Weinhold		wait_for_child(child);
62413546fd1SIngo Weinhold	}
62513546fd1SIngo Weinhold
62613546fd1SIngo Weinhold	TEST("sem_getvalue()");
62713546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
62813546fd1SIngo Weinhold	assert_equals(0, value);
62913546fd1SIngo Weinhold
63013546fd1SIngo Weinhold	TEST("unblock child after wait after timeout");
63113546fd1SIngo Weinhold	child = fork();
63213546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
63313546fd1SIngo Weinhold
63413546fd1SIngo Weinhold	if (child == 0) {
63513546fd1SIngo Weinhold		// child
63613546fd1SIngo Weinhold		timespec timeout;
63713546fd1SIngo Weinhold		bigtime_t startTime = system_time();
63813546fd1SIngo Weinhold		assert_posix_error(ETIMEDOUT, sem_timedwait(sem,
63913546fd1SIngo Weinhold			absolute_timeout(timeout, 1000000)));
64013546fd1SIngo Weinhold		bigtime_t diffTime = system_time() - startTime;
64113546fd1SIngo Weinhold		assert_time_equals(1000000, diffTime);
64213546fd1SIngo Weinhold
64313546fd1SIngo Weinhold		exit(0);
64413546fd1SIngo Weinhold	} else {
64513546fd1SIngo Weinhold		// parent
64613546fd1SIngo Weinhold		sleep(2);
64713546fd1SIngo Weinhold		assert_posix_success(sem_post(sem));
64813546fd1SIngo Weinhold		wait_for_child(child);
64913546fd1SIngo Weinhold	}
65013546fd1SIngo Weinhold
65113546fd1SIngo Weinhold	TEST("sem_getvalue()");
65213546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
65313546fd1SIngo Weinhold	assert_equals(1, value);
65413546fd1SIngo Weinhold
65513546fd1SIngo Weinhold	// close
65613546fd1SIngo Weinhold	TEST("sem_close()");
65713546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
65813546fd1SIngo Weinhold
65913546fd1SIngo Weinhold	TEST("done");
66013546fd1SIngo Weinhold}
66113546fd1SIngo Weinhold
66213546fd1SIngo Weinhold
66313546fd1SIngo Weinholdstatic void
66413546fd1SIngo Weinholdtest_post_wait_named_fork2()
66513546fd1SIngo Weinhold{
666e01137a6SIngo Weinhold	TEST_SET("sem_{post,wait,trywait,timedwait}() named semaphore open after "
667e01137a6SIngo Weinhold		"fork");
668e01137a6SIngo Weinhold
66913546fd1SIngo Weinhold	const char* currentTest = NULL;
67013546fd1SIngo Weinhold
67113546fd1SIngo Weinhold	// make sure the sem doesn't exist yet
67213546fd1SIngo Weinhold	sem_unlink(kSemName1);
67313546fd1SIngo Weinhold
67413546fd1SIngo Weinhold	// open non-existing with O_CREAT
67513546fd1SIngo Weinhold	TEST("sem_open(O_CREAT) non-existing");
67613546fd1SIngo Weinhold	sem_t* sem = sem_open(kSemName1, O_CREAT, S_IRUSR | S_IWUSR, 0);
67713546fd1SIngo Weinhold	assert_posix_bool_success(sem != SEM_FAILED);
67813546fd1SIngo Weinhold
67913546fd1SIngo Weinhold	TEST("sem_getvalue()");
68013546fd1SIngo Weinhold	int value;
68113546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
68213546fd1SIngo Weinhold	assert_equals(0, value);
68313546fd1SIngo Weinhold
68413546fd1SIngo Weinhold	// close
68513546fd1SIngo Weinhold	TEST("sem_close()");
68613546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
68713546fd1SIngo Weinhold	sem = NULL;
68813546fd1SIngo Weinhold
68913546fd1SIngo Weinhold	TEST("unblock child after wait");
69013546fd1SIngo Weinhold	pid_t child = fork();
69113546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
69213546fd1SIngo Weinhold
69313546fd1SIngo Weinhold	if (child == 0) {
69413546fd1SIngo Weinhold		// child
69513546fd1SIngo Weinhold		sem = sem_open(kSemName1, 0);
69613546fd1SIngo Weinhold		assert_posix_bool_success(sem != SEM_FAILED);
69713546fd1SIngo Weinhold
69813546fd1SIngo Weinhold		bigtime_t startTime = system_time();
69913546fd1SIngo Weinhold		assert_posix_success(sem_wait(sem));
70013546fd1SIngo Weinhold		bigtime_t diffTime = system_time() - startTime;
70113546fd1SIngo Weinhold		assert_time_equals(1000000, diffTime);
70213546fd1SIngo Weinhold
70313546fd1SIngo Weinhold		exit(0);
70413546fd1SIngo Weinhold	} else {
70513546fd1SIngo Weinhold		// parent
70613546fd1SIngo Weinhold		sem = sem_open(kSemName1, 0);
70713546fd1SIngo Weinhold		assert_posix_bool_success(sem != SEM_FAILED);
70813546fd1SIngo Weinhold
70913546fd1SIngo Weinhold		sleep(1);
71013546fd1SIngo Weinhold		assert_posix_success(sem_post(sem));
71113546fd1SIngo Weinhold		wait_for_child(child);
71213546fd1SIngo Weinhold	}
71313546fd1SIngo Weinhold
71413546fd1SIngo Weinhold	TEST("sem_getvalue()");
71513546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
71613546fd1SIngo Weinhold	assert_equals(0, value);
71713546fd1SIngo Weinhold
71813546fd1SIngo Weinhold	// close
71913546fd1SIngo Weinhold	TEST("sem_close()");
72013546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
72113546fd1SIngo Weinhold	sem = NULL;
72213546fd1SIngo Weinhold
72313546fd1SIngo Weinhold	TEST("unblock child after wait before timeout");
72413546fd1SIngo Weinhold	child = fork();
72513546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
72613546fd1SIngo Weinhold
72713546fd1SIngo Weinhold	if (child == 0) {
72813546fd1SIngo Weinhold		// child
72913546fd1SIngo Weinhold		sem = sem_open(kSemName1, 0);
73013546fd1SIngo Weinhold		assert_posix_bool_success(sem != SEM_FAILED);
73113546fd1SIngo Weinhold
73213546fd1SIngo Weinhold		timespec timeout;
73313546fd1SIngo Weinhold		bigtime_t startTime = system_time();
73413546fd1SIngo Weinhold		assert_posix_success(sem_timedwait(sem,
73513546fd1SIngo Weinhold			absolute_timeout(timeout, 2000000)));
73613546fd1SIngo Weinhold		bigtime_t diffTime = system_time() - startTime;
73713546fd1SIngo Weinhold		assert_time_equals(1000000, diffTime);
73813546fd1SIngo Weinhold
73913546fd1SIngo Weinhold		exit(0);
74013546fd1SIngo Weinhold	} else {
74113546fd1SIngo Weinhold		// parent
74213546fd1SIngo Weinhold		sem = sem_open(kSemName1, 0);
74313546fd1SIngo Weinhold		assert_posix_bool_success(sem != SEM_FAILED);
74413546fd1SIngo Weinhold
74513546fd1SIngo Weinhold		sleep(1);
74613546fd1SIngo Weinhold		assert_posix_success(sem_post(sem));
74713546fd1SIngo Weinhold		wait_for_child(child);
74813546fd1SIngo Weinhold	}
74913546fd1SIngo Weinhold
75013546fd1SIngo Weinhold	TEST("sem_getvalue()");
75113546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
75213546fd1SIngo Weinhold	assert_equals(0, value);
75313546fd1SIngo Weinhold
75413546fd1SIngo Weinhold	// close
75513546fd1SIngo Weinhold	TEST("sem_close()");
75613546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
75713546fd1SIngo Weinhold	sem = NULL;
75813546fd1SIngo Weinhold
75913546fd1SIngo Weinhold	TEST("unblock child after wait after timeout");
76013546fd1SIngo Weinhold	child = fork();
76113546fd1SIngo Weinhold	assert_posix_bool_success(child >= 0);
76213546fd1SIngo Weinhold
76313546fd1SIngo Weinhold	if (child == 0) {
76413546fd1SIngo Weinhold		// child
76513546fd1SIngo Weinhold		sem = sem_open(kSemName1, 0);
76613546fd1SIngo Weinhold		assert_posix_bool_success(sem != SEM_FAILED);
76713546fd1SIngo Weinhold
76813546fd1SIngo Weinhold		timespec timeout;
76913546fd1SIngo Weinhold		bigtime_t startTime = system_time();
77013546fd1SIngo Weinhold		assert_posix_error(ETIMEDOUT, sem_timedwait(sem,
77113546fd1SIngo Weinhold			absolute_timeout(timeout, 1000000)));
77213546fd1SIngo Weinhold		bigtime_t diffTime = system_time() - startTime;
77313546fd1SIngo Weinhold		assert_time_equals(1000000, diffTime);
77413546fd1SIngo Weinhold
77513546fd1SIngo Weinhold		exit(0);
77613546fd1SIngo Weinhold	} else {
77713546fd1SIngo Weinhold		// parent
77813546fd1SIngo Weinhold		sem = sem_open(kSemName1, 0);
77913546fd1SIngo Weinhold		assert_posix_bool_success(sem != SEM_FAILED);
78013546fd1SIngo Weinhold
78113546fd1SIngo Weinhold		sleep(2);
78213546fd1SIngo Weinhold		assert_posix_success(sem_post(sem));
78313546fd1SIngo Weinhold		wait_for_child(child);
78413546fd1SIngo Weinhold	}
78513546fd1SIngo Weinhold
78613546fd1SIngo Weinhold	TEST("sem_getvalue()");
78713546fd1SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
78813546fd1SIngo Weinhold	assert_equals(1, value);
78913546fd1SIngo Weinhold
79013546fd1SIngo Weinhold	// close
79113546fd1SIngo Weinhold	TEST("sem_close()");
79213546fd1SIngo Weinhold	assert_posix_success(sem_close(sem));
79313546fd1SIngo Weinhold
79413546fd1SIngo Weinhold	TEST("done");
79513546fd1SIngo Weinhold}
79613546fd1SIngo Weinhold
79713546fd1SIngo Weinhold
79813546fd1SIngo Weinholdstatic void
79913546fd1SIngo Weinholdtest_post_wait_unnamed_fork()
80013546fd1SIngo Weinhold{
801e01137a6SIngo Weinhold	TEST_SET("sem_{post,wait,trywait,timedwait}() unnamed semaphore with "
802e01137a6SIngo Weinhold		"fork()");
803e01137a6SIngo Weinhold
80413546fd1SIngo Weinhold	const char* currentTest = NULL;
80513546fd1SIngo Weinhold
80613546fd1SIngo Weinhold	// init
80713546fd1SIngo Weinhold	TEST("sem_init()");
80813546fd1SIngo Weinhold	sem_t _sem;
8095a5ff851SIngo Weinhold	assert_posix_success(sem_init(&_sem, 0, 1));
81013546fd1SIngo Weinhold	sem_t* sem = &_sem;
81113546fd1SIngo Weinhold
812e01137a6SIngo Weinhold	TEST("sem_getvalue()");
813e01137a6SIngo Weinhold	int value;
814e01137a6SIngo Weinhold	assert_posix_success(sem_getvalue(sem, &value));
815e01137a6SIngo Weinhold	assert_equals(1, value);
816e01137a6SIngo Weinhold
817e01137a6SIngo Weinhold	TEST("sem_wait() on fork()ed unnamed sem in parent and child");
818e01137a6SIngo Weinhold	pid_t child = fork();
819e01137a6SIngo Weinhold	assert_posix_bool_success(child >= 0);
820e01137a6SIngo Weinhold
821e01137a6SIngo Weinhold	if (child == 0) {
822e01137a6SIngo Weinhold		// child
823e01137a6SIngo Weinhold		sleep(1);
824e01137a6S