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