13f4cbf05Sopenharmony_ci/*
23f4cbf05Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License.
53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at
63f4cbf05Sopenharmony_ci *
73f4cbf05Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83f4cbf05Sopenharmony_ci *
93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and
133f4cbf05Sopenharmony_ci * limitations under the License.
143f4cbf05Sopenharmony_ci */
153f4cbf05Sopenharmony_ci
163f4cbf05Sopenharmony_ci/**
173f4cbf05Sopenharmony_ci * @file semaphore_ex.h
183f4cbf05Sopenharmony_ci *
193f4cbf05Sopenharmony_ci * @brief Provides interfaces of semaphores in c_utils,
203f4cbf05Sopenharmony_ci * including nameless and named semaphores.
213f4cbf05Sopenharmony_ci *
223f4cbf05Sopenharmony_ci * A semaphore is an atomic counter, which can act as a lock
233f4cbf05Sopenharmony_ci * to achieve mutual exclusion, synchronization, and other functions.
243f4cbf05Sopenharmony_ci * Used in a multithreaded environment, it prevents concurrent
253f4cbf05Sopenharmony_ci * calling of a critical piece of code or restricts the maximum number
263f4cbf05Sopenharmony_ci * of threads entering the code section.
273f4cbf05Sopenharmony_ci */
283f4cbf05Sopenharmony_ci
293f4cbf05Sopenharmony_ci#ifndef SEMAPHORE_EX_H
303f4cbf05Sopenharmony_ci#define SEMAPHORE_EX_H
313f4cbf05Sopenharmony_ci
323f4cbf05Sopenharmony_ci#include "nocopyable.h"
333f4cbf05Sopenharmony_ci
343f4cbf05Sopenharmony_ci#include <iostream>
353f4cbf05Sopenharmony_ci#include <thread>
363f4cbf05Sopenharmony_ci#include <mutex>
373f4cbf05Sopenharmony_ci#include <condition_variable>
383f4cbf05Sopenharmony_ci#include <string>
393f4cbf05Sopenharmony_ci#include <ctime> // timespec since c11
403f4cbf05Sopenharmony_ci
413f4cbf05Sopenharmony_cinamespace OHOS {
423f4cbf05Sopenharmony_ci/**
433f4cbf05Sopenharmony_ci * @brief Provides interfaces for operating semaphores.
443f4cbf05Sopenharmony_ci *
453f4cbf05Sopenharmony_ci * A semaphore is a counter used to implement functions, such as
463f4cbf05Sopenharmony_ci * mutual exclusion between processes/threads, synchronization, and more.
473f4cbf05Sopenharmony_ci * The difference between nameless semaphores and named semaphores lies
483f4cbf05Sopenharmony_ci * in the form of creation and destruction.
493f4cbf05Sopenharmony_ci * Semaphores exist only in memory. The process/thread
503f4cbf05Sopenharmony_ci * using the semaphore must access the memory where the semaphore is located.
513f4cbf05Sopenharmony_ci * Therefore, the nameless semaphore can only be in the thread of
523f4cbf05Sopenharmony_ci * the same process, or threads in different processes that have mapped
533f4cbf05Sopenharmony_ci * the same memory to their address space, that is, the nameless semaphores
543f4cbf05Sopenharmony_ci * can only be accessed through shared memory.
553f4cbf05Sopenharmony_ci */
563f4cbf05Sopenharmony_ciclass Semaphore : public NoCopyable {
573f4cbf05Sopenharmony_cipublic:
583f4cbf05Sopenharmony_ci/**
593f4cbf05Sopenharmony_ci * @brief A constructor used to create a semaphore object.
603f4cbf05Sopenharmony_ci *
613f4cbf05Sopenharmony_ci * @param Value Indicates the initial value of the semaphore object.
623f4cbf05Sopenharmony_ci */
633f4cbf05Sopenharmony_ci    explicit Semaphore(int value = 1) : count_(value) {}
643f4cbf05Sopenharmony_ci
653f4cbf05Sopenharmony_ci/**
663f4cbf05Sopenharmony_ci * @brief Acquires the semaphore.
673f4cbf05Sopenharmony_ci *
683f4cbf05Sopenharmony_ci * If the current semaphore count >= 0, the current thread continues.
693f4cbf05Sopenharmony_ci * If the current semaphore count < 0, the current thread will be blocked.
703f4cbf05Sopenharmony_ci */
713f4cbf05Sopenharmony_ci    void Wait();
723f4cbf05Sopenharmony_ci
733f4cbf05Sopenharmony_ci/**
743f4cbf05Sopenharmony_ci * @brief Releases the semaphore.
753f4cbf05Sopenharmony_ci *
763f4cbf05Sopenharmony_ci * If the current semaphore count > 0, there is no blocked thread.
773f4cbf05Sopenharmony_ci * If the current semaphore count <= 0, there are still
783f4cbf05Sopenharmony_ci * blocked threads. Then this method will wake one of them up.
793f4cbf05Sopenharmony_ci */
803f4cbf05Sopenharmony_ci    void Post();
813f4cbf05Sopenharmony_ci
823f4cbf05Sopenharmony_ciprivate:
833f4cbf05Sopenharmony_ci    int count_;   // Initial value of the semaphore object.
843f4cbf05Sopenharmony_ci    std::mutex mutex_;
853f4cbf05Sopenharmony_ci    std::condition_variable cv_;
863f4cbf05Sopenharmony_ci};
873f4cbf05Sopenharmony_ci
883f4cbf05Sopenharmony_ci} // OHOS
893f4cbf05Sopenharmony_ci
903f4cbf05Sopenharmony_ci#endif
913f4cbf05Sopenharmony_ci
92