1/*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/**
17 * @file semaphore_ex.h
18 *
19 * @brief Provides interfaces of semaphores in c_utils,
20 * including nameless and named semaphores.
21 *
22 * A semaphore is an atomic counter, which can act as a lock
23 * to achieve mutual exclusion, synchronization, and other functions.
24 * Used in a multithreaded environment, it prevents concurrent
25 * calling of a critical piece of code or restricts the maximum number
26 * of threads entering the code section.
27 */
28
29#ifndef SEMAPHORE_EX_H
30#define SEMAPHORE_EX_H
31
32#include "nocopyable.h"
33
34#include <iostream>
35#include <thread>
36#include <mutex>
37#include <condition_variable>
38#include <string>
39#include <ctime> // timespec since c11
40
41namespace OHOS {
42/**
43 * @brief Provides interfaces for operating semaphores.
44 *
45 * A semaphore is a counter used to implement functions, such as
46 * mutual exclusion between processes/threads, synchronization, and more.
47 * The difference between nameless semaphores and named semaphores lies
48 * in the form of creation and destruction.
49 * Semaphores exist only in memory. The process/thread
50 * using the semaphore must access the memory where the semaphore is located.
51 * Therefore, the nameless semaphore can only be in the thread of
52 * the same process, or threads in different processes that have mapped
53 * the same memory to their address space, that is, the nameless semaphores
54 * can only be accessed through shared memory.
55 */
56class Semaphore : public NoCopyable {
57public:
58/**
59 * @brief A constructor used to create a semaphore object.
60 *
61 * @param Value Indicates the initial value of the semaphore object.
62 */
63    explicit Semaphore(int value = 1) : count_(value) {}
64
65/**
66 * @brief Acquires the semaphore.
67 *
68 * If the current semaphore count >= 0, the current thread continues.
69 * If the current semaphore count < 0, the current thread will be blocked.
70 */
71    void Wait();
72
73/**
74 * @brief Releases the semaphore.
75 *
76 * If the current semaphore count > 0, there is no blocked thread.
77 * If the current semaphore count <= 0, there are still
78 * blocked threads. Then this method will wake one of them up.
79 */
80    void Post();
81
82private:
83    int count_;   // Initial value of the semaphore object.
84    std::mutex mutex_;
85    std::condition_variable cv_;
86};
87
88} // OHOS
89
90#endif
91
92