IntrOS
Loading...
Searching...
No Matches
ossemaphore.h
1/******************************************************************************
2
3 @file IntrOS: ossemaphore.h
4 @author Rajmund Szymanski
5 @date 18.11.2025
6 @brief This file contains definitions for IntrOS.
7
8 ******************************************************************************
9
10 Copyright (c) 2018-2022 Rajmund Szymanski. All rights reserved.
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to
14 deal in the Software without restriction, including without limitation the
15 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 sell copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included
20 in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 IN THE SOFTWARE.
29
30 ******************************************************************************/
31
32#ifndef __INTROS_SEM_H
33#define __INTROS_SEM_H
34
35#include "oskernel.h"
36#include "osclock.h"
37
43
44/* -------------------------------------------------------------------------- */
45
46#define semDirect ( 0U )
47#define semBinary ( 1U )
48#define semCounting ( 0U-1 )
49#define semDefault semCounting
50
54
55typedef struct __sem sem_t;
56
57struct __sem
58{
59 obj_t obj;
60
61 unsigned count;
62 unsigned limit;
63};
64
65typedef struct __sem sem_id [];
66
67/******************************************************************************
68 *
69 * Name : _SEM_INIT
70 *
71 * Description : create and initialize a semaphore object
72 *
73 * Parameters
74 * init : initial value of semaphore counter
75 * limit : maximum value of semaphore counter
76 * semDirect: direct semaphore
77 * semBinary: binary semaphore
78 * semCounting: counting semaphore
79 * otherwise: limited semaphore
80 *
81 * Return : semaphore object
82 *
83 * Note : for internal use
84 *
85 ******************************************************************************/
86
87#define _SEM_INIT( _init, _limit ) { _OBJ_INIT(), _init < _limit ? _init : _limit, _limit }
88
89/******************************************************************************
90 *
91 * Name : _VA_SEM
92 *
93 * Description : calculate maximum value of semaphore counter from optional parameter
94 *
95 * Note : for internal use
96 *
97 ******************************************************************************/
98
99#define _VA_SEM( _limit ) ( (_limit + 0) ? (_limit + 0) : (semDefault) )
100
113#define OS_SEM( sem, init, ... ) \
114 sem_t sem[] = { _SEM_INIT( init, _VA_SEM(__VA_ARGS__) ) }
115
116/** static alias of OS_SEM() */
117#define static_SEM( sem, init, ... ) \
118 static sem_t sem[] = { _SEM_INIT( init, _VA_SEM(__VA_ARGS__) ) }
119
134
135#ifndef __cplusplus
136#define SEM_INIT( init, ... ) \
137 _SEM_INIT( init, _VA_SEM(__VA_ARGS__) )
138#endif
139
154
155#ifndef __cplusplus
156#define SEM_CREATE( init, ... ) \
157 { SEM_INIT ( init, _VA_SEM(__VA_ARGS__) ) }
158/** alias of SEM_CREATE() */
159#define SEM_NEW \
160 SEM_CREATE
161#endif
162
163#ifdef __cplusplus
164extern "C" {
165#endif
166
179void sem_init( sem_t *sem, unsigned init, unsigned limit );
180
189void sem_reset( sem_t *sem );
190
192__STATIC_INLINE
193void sem_kill( sem_t *sem ) { sem_reset(sem); }
194
207int sem_take( sem_t *sem );
208
210__STATIC_INLINE
211int sem_tryWait( sem_t *sem ) { return sem_take(sem); }
212
213#if OS_ATOMICS
215int sem_takeAsync( sem_t *sem );
216#endif
217
232int sem_waitFor( sem_t *sem, cnt_t delay );
233
246int sem_waitUntil( sem_t *sem, cnt_t time );
247
259
260__STATIC_INLINE
261int sem_wait( sem_t *sem ) { return sem_waitFor(sem, INFINITE); }
262
263#if OS_ATOMICS
265int sem_waitAsync( sem_t *sem );
266#endif
267
280int sem_give( sem_t *sem );
281
283__STATIC_INLINE
284int sem_post( sem_t *sem ) { return sem_give(sem); }
285
286#if OS_ATOMICS
288int sem_giveAsync( sem_t *sem );
289#endif
290
301int sem_release( sem_t *sem, unsigned num );
302
311unsigned sem_getValue( sem_t *sem );
312
313#ifdef __cplusplus
314}
315#endif
316
317/* -------------------------------------------------------------------------- */
318
319#if defined(__cplusplus)
320namespace intros {
321
334struct Semaphore : public __sem
335{
337 constexpr
338 Semaphore(): __sem _SEM_INIT(0, semDefault) {}
340 constexpr
341 Semaphore( const unsigned _init, const unsigned _limit = semDefault ): __sem _SEM_INIT(_init, _limit) {}
342
343 ~Semaphore() { assert(__sem::obj.queue == nullptr); }
344
345 /// move constructor
346 Semaphore( Semaphore&& _src ): __sem(_src)
347 {
348 assert(_src.obj.queue == nullptr);
349 }
350
351 Semaphore( const Semaphore& ) = delete;
352 Semaphore& operator=( Semaphore&& ) = delete;
353 Semaphore& operator=( const Semaphore& ) = delete;
355 void reset () { sem_reset (this); }
356 void kill () { sem_kill (this); }
357 int take () { return sem_take (this); }
358 int tryWait () { return sem_tryWait (this); }
359 template<typename T>
360 int waitFor ( const T& _delay ) { return sem_waitFor (this, Clock::count(_delay)); }
361 template<typename T>
362 int waitUntil ( const T& _time ) { return sem_waitUntil (this, Clock::until(_time)); }
363 int wait () { return sem_wait (this); }
364 int give () { return sem_give (this); }
365 int post () { return sem_post (this); }
366 int release ( unsigned _num ) { return sem_release (this, _num); }
367 unsigned getValue () { return sem_getValue (this); }
368#if OS_ATOMICS
369 int takeAsync () { return sem_takeAsync (this); }
370 int waitAsync () { return sem_waitAsync (this); }
371 int giveAsync () { return sem_giveAsync (this); }
372#endif
373
374#if __cplusplus >= 201402L
375 using Ptr = std::unique_ptr<Semaphore>;
376#else
377 using Ptr = Semaphore *;
378#endif
379
385
386 static
388 {
389 return { 0, semDirect };
390 }
391
399
400 static
401 Semaphore Binary( const unsigned _init = 0 )
402 {
403 return { _init, semBinary };
404 }
405
413
414 static
415 Semaphore Counting( const unsigned _init = 0 )
416 {
417 return { _init, semCounting };
418 }
419
420};
421
422} // namespace
423#endif//__cplusplus
424
425/* -------------------------------------------------------------------------- */
426
428
429#endif//__INTROS_SEM_H
#define INFINITE
infinite waiting
Definition osbase.h:250
int sem_post(sem_t *sem)
alias of sem_give()
Definition ossemaphore.h:283
int sem_takeAsync(sem_t *sem)
Async alias of sem_take().
int sem_waitFor(sem_t *sem, cnt_t delay)
try to lock the semaphore object, wait for given duration of time if the semaphore object can't be lo...
void sem_init(sem_t *sem, unsigned init, unsigned limit)
initialize a semaphore object
int sem_tryWait(sem_t *sem)
alias of sem_take()
Definition ossemaphore.h:210
#define semDefault
default semaphore type
Definition ossemaphore.h:49
void sem_kill(sem_t *sem)
alias of sem_reset()
Definition ossemaphore.h:192
int sem_take(sem_t *sem)
try to lock the semaphore object, don't wait if the semaphore object can't be locked immediately
int sem_waitUntil(sem_t *sem, cnt_t time)
try to lock the semaphore object, wait until given timepoint if the semaphore object can't be locked ...
#define semDirect
direct semaphore (producer can't free the semaphore, it can post the semaphore only to the pending ta...
Definition ossemaphore.h:46
unsigned sem_getValue(sem_t *sem)
return current value of semaphore
#define semBinary
binary semaphore
Definition ossemaphore.h:47
int sem_wait(sem_t *sem)
try to lock the semaphore object, wait indefinitely if the semaphore object can't be locked immediate...
Definition ossemaphore.h:260
int sem_release(sem_t *sem, unsigned num)
try to increment the internal semaphore counter by the value of num
int sem_waitAsync(sem_t *sem)
Async alias of sem_wait().
int sem_give(sem_t *sem)
try to unlock the semaphore object, don't wait if the semaphore object can't be unlocked immediately
int sem_giveAsync(sem_t *sem)
Async alias of sem_give().
#define semCounting
counting semaphore
Definition ossemaphore.h:48
void sem_reset(sem_t *sem)
reset the semaphore object and wake up all waiting tasks with 'E_STOPPED' event value
static constexpr rep until(const std::chrono::time_point< Clock, _Duration > &_time)
time point in ticks, rounded up to whole ticks (only a time point of this clock)
Definition osclock.h:109
static constexpr rep count(const std::chrono::duration< _Rep, _Period > &_delay)
delay in ticks, rounded up to whole ticks; negative delay: IMMEDIATE, delay out of range: INFINITE
Definition osclock.h:102
create and initialize a semaphore object
Definition ossemaphore.h:334
int wait()
sem_wait()
Definition ossemaphore.h:362
int take()
sem_take()
Definition ossemaphore.h:356
int waitUntil(const T &_time)
sem_waitUntil()
Definition ossemaphore.h:361
int tryWait()
sem_tryWait()
Definition ossemaphore.h:357
std::unique_ptr< Semaphore > Ptr
result type of Create()
Definition ossemaphore.h:374
int post()
sem_post()
Definition ossemaphore.h:364
static Semaphore Binary(const unsigned _init=0)
create and initialize static binary semaphore
Definition ossemaphore.h:400
unsigned getValue()
sem_getValue()
Definition ossemaphore.h:366
constexpr Semaphore()
constructor, see the constructor parameters of the class
Definition ossemaphore.h:337
void reset()
sem_reset()
Definition ossemaphore.h:354
int takeAsync()
sem_takeAsync()
Definition ossemaphore.h:368
int giveAsync()
sem_giveAsync()
Definition ossemaphore.h:370
void kill()
sem_kill()
Definition ossemaphore.h:355
int waitFor(const T &_delay)
sem_waitFor()
Definition ossemaphore.h:359
int release(unsigned _num)
sem_release()
Definition ossemaphore.h:365
static Semaphore Counting(const unsigned _init=0)
create and initialize static counting semaphore
Definition ossemaphore.h:414
static Semaphore Direct()
create and initialize static direct semaphore
Definition ossemaphore.h:386
int give()
sem_give()
Definition ossemaphore.h:363
int waitAsync()
sem_waitAsync()
Definition ossemaphore.h:369