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 
41 namespace 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  */
56 class Semaphore : public NoCopyable {
57 public:
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 
82 private:
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