Zephyr API Documentation 4.0.0
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
sem.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
13#ifndef ZEPHYR_INCLUDE_SYS_SEM_H_
14#define ZEPHYR_INCLUDE_SYS_SEM_H_
15
16/*
17 * sys_sem exists in user memory working as counter semaphore for
18 * user mode thread when user mode enabled. When user mode isn't
19 * enabled, sys_sem behaves like k_sem.
20 */
21
22#include <zephyr/kernel.h>
23#include <zephyr/sys/atomic.h>
24#include <zephyr/types.h>
26#include <zephyr/sys/__assert.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
35struct sys_sem {
36#ifdef CONFIG_USERSPACE
37 struct k_futex futex;
38 int limit;
39#else
40 struct k_sem kernel_sem;
41#endif
42};
43
63#ifdef CONFIG_USERSPACE
64#define SYS_SEM_DEFINE(_name, _initial_count, _count_limit) \
65 struct sys_sem _name = { \
66 .futex = { _initial_count }, \
67 .limit = _count_limit \
68 }; \
69 BUILD_ASSERT(((_count_limit) != 0) && \
70 ((_initial_count) <= (_count_limit)))
71#else
72/* Stuff this in the section with the rest of the k_sem objects, since they
73 * are identical and can be treated as a k_sem in the boot initialization code
74 */
75#define SYS_SEM_DEFINE(_name, _initial_count, _count_limit) \
76 STRUCT_SECTION_ITERABLE_ALTERNATE(k_sem, sys_sem, _name) = { \
77 .kernel_sem = Z_SEM_INITIALIZER(_name.kernel_sem, \
78 _initial_count, _count_limit) \
79 }; \
80 BUILD_ASSERT(((_count_limit) != 0) && \
81 ((_initial_count) <= (_count_limit)))
82#endif
83
97int sys_sem_init(struct sys_sem *sem, unsigned int initial_count,
98 unsigned int limit);
99
113int sys_sem_give(struct sys_sem *sem);
114
129int sys_sem_take(struct sys_sem *sem, k_timeout_t timeout);
130
140unsigned int sys_sem_count_get(struct sys_sem *sem);
141
146#if defined(__GNUC__)
147static ALWAYS_INLINE void z_sys_sem_lock_onexit(__maybe_unused int *rc)
148{
149 __ASSERT(*rc == 1, "SYS_SEM_LOCK exited with goto, break or return, "
150 "use SYS_SEM_LOCK_BREAK instead.");
151}
152#define SYS_SEM_LOCK_ONEXIT __attribute__((__cleanup__(z_sys_sem_lock_onexit)))
153#else
154#define SYS_SEM_LOCK_ONEXIT
155#endif
156
167#define SYS_SEM_LOCK_BREAK continue
168
207#define SYS_SEM_LOCK(sem) \
208 for (int __rc SYS_SEM_LOCK_ONEXIT = sys_sem_take((sem), K_FOREVER); ({ \
209 __ASSERT(__rc >= 0, "Failed to take sem: %d", __rc); \
210 __rc == 0; \
211 }); \
212 ({ \
213 __rc = sys_sem_give((sem)); \
214 __ASSERT(__rc == 0, "Failed to give sem: %d", __rc); \
215 }), \
216 __rc = 1)
217
222#ifdef __cplusplus
223}
224#endif
225
226#endif
unsigned int sys_sem_count_get(struct sys_sem *sem)
Get sys_sem's value.
int sys_sem_give(struct sys_sem *sem)
Give a semaphore.
int sys_sem_init(struct sys_sem *sem, unsigned int initial_count, unsigned int limit)
Initialize a semaphore.
int sys_sem_take(struct sys_sem *sem, k_timeout_t timeout)
Take a sys_sem.
#define ALWAYS_INLINE
Definition common.h:129
Public kernel APIs.
futex structure
Definition kernel.h:2222
Kernel timeout type.
Definition sys_clock.h:65
sys_sem structure
Definition sem.h:35
struct k_futex futex
Definition sem.h:37
int limit
Definition sem.h:38