KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
semaphore.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 include/semaphore.h
4 Copyright (C) 2026 Falco Girgis
5*/
6
7/*
8 This file is an extremely lightweight wrapper which simply "extends" KOS's
9 existing <kos/sem.h> kernel semaphores, which are already partially POSIX-
10 compliant, and implements the rest of the missing POSIX functionality as a
11 light-weight inline function wrapper API around them.
12*/
13
14#ifndef __SEMAPHORE_H
15#define __SEMAPHORE_H
16
17#include <kos/cdefs.h>
18#include <kos/sem.h>
19#include <errno.h>
20
21__BEGIN_DECLS
22
23/* POSIX semaphores are type-compatible with kernel semaphores. */
25
26/* Selector macro, which implements function overload resolution for 2 and 3
27 argument versions of the same function. Uses a "sliding argument" trick so
28 that NAME is selected based on the number of arguments it gets passed.
29*/
30#define SEM_INIT_SELECTOR(_1, _2, _3, NAME, ...) NAME
31
32/* Due to the fact that KOS's <kos/sem.h> is technically stomping on the POSIX
33 symbol, sem_init(), by providing its own two argument version, we must
34 implement some crazy macro shenanigans to allow both KOS's 2 argument
35 version of sem_init() and POSIX's 3 argument version of sem_init() to
36 coexist without causing errors on incompatible function declarations or
37 duplicate symbols.
38
39 What we do here, is use a macro named "sem_init()" to "hide" the KOS
40 declaration with the same name, forwarding the arguments on as __VA_ARGS__
41 into the selector macro, which will return either the identifier
42 "sem_init_posix," in the case when 3 arguments are provided, or
43 "(sem_init)," in the case when 2 arguments are provided.
44
45 Finally, we simply invoke the return expression of SEM_INIT_SELECTOR() as
46 if it were a function name (because it is). In the case of (sem_init)(),
47 the parentheses around the identifier name allow us to escape from macro
48 expansion, avoided infinite macro recursion and unhiding KOS's version of
49 sem_init(), which we will call into.
50*/
51#define sem_init(...) \
52 SEM_INIT_SELECTOR(__VA_ARGS__, sem_init_posix, (sem_init))(__VA_ARGS__)
53
54/* 3-argument POSIX-compliant implementation of sem_init(). */
55static inline int sem_init_posix(sem_t *sem, int shared, unsigned int value) {
56 if(shared) { /* We don't support shared semaphores. */
57 errno = ENOSYS;
58 return -1;
59 }
60 else
61 return sem_init(sem, value);
62}
63
64/* Forward POSIX sem_close() directly on to KOS's sem_destroy(). */
65static inline int sem_close(sem_t* sem) {
66 return sem_destroy(sem);
67}
68
69/* Implement POSIX's sem_getvalue() from KOS's sem_count(). */
70static inline int sem_getvalue(sem_t *sem, int *value) {
71 *value = sem_count(sem);
72 return 0;
73}
74
75/* Forward POSIX's sem_post() on to KOS's sem_signal(). */
76static inline int sem_post(sem_t *sem) {
77 return sem_signal(sem);
78}
79
80__END_DECLS
81
82#endif
Various common macros used throughout the codebase.
Errno helper functions.
semaphore_t sem
Definition general_threading_test.c:20
Semaphores.
int sem_count(const semaphore_t *sm) __nonnull_all
Retrieve the number of available resources.
int sem_destroy(semaphore_t *sm) __nonnull_all
Destroy a semaphore.
int sem_signal(semaphore_t *sm) __nonnull_all
Signal a semaphore.
static int sem_init_posix(sem_t *sem, int shared, unsigned int value)
Definition semaphore.h:55
#define sem_init(...)
Definition semaphore.h:51
semaphore_t sem_t
Definition semaphore.h:24
static int sem_post(sem_t *sem)
Definition semaphore.h:76
static int sem_close(sem_t *sem)
Definition semaphore.h:65
static int sem_getvalue(sem_t *sem, int *value)
Definition semaphore.h:70
Semaphore type.
Definition sem.h:37