The Pedigree Project 0.1
Semaphore.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef SEMAPHORE_H
21#define SEMAPHORE_H
22#include "pedigree/kernel/Atomic.h"
23#include "pedigree/kernel/Spinlock.h"
24#include "pedigree/kernel/compiler.h"
25#include "pedigree/kernel/process/Event.h"
26#include "pedigree/kernel/process/WaitQueue.h"
27#include "pedigree/kernel/processor/types.h"
28#include "pedigree/kernel/utilities/Result.h"
29#include "pedigree/kernel/utilities/new"
30
31#include <config.h>
32
36class EXPORTED_PUBLIC Semaphore {
37 public:
38 enum SemaphoreError {
39 TimedOut,
40 Interrupted,
41 NoError,
42 };
43
44#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
45 using BeforeWaitHook = void (*)(Semaphore*);
46 static void setBeforeWaitHook(BeforeWaitHook hook);
47
48 enum MutexTransitionWindow {
49 MutexCounterAcquired,
50 MutexOwnerReleased,
51 };
52 using MutexTransitionHook = void (*)(MutexTransitionWindow window);
53
55 static void setMutexTransitionHook(MutexTransitionHook hook);
56
57 static size_t getHostedTimeoutCreateCount();
58 static size_t getHostedTimeoutDestroyCount();
59#endif
60
65 Semaphore(size_t nInitialValue, bool canInterrupt = true);
67 virtual ~Semaphore();
68
70 MUST_USE_RESULT bool acquireWithError(size_t n, size_t timeoutSecs, size_t timeoutUsecs,
71 SemaphoreError& error);
72
82 MUST_USE_RESULT bool acquireForCompletion(size_t n = 1, size_t timeoutSecs = 0,
83 size_t timeoutUsecs = 0);
84
86 bool acquire(size_t n = 1, size_t timeoutSecs = 0, size_t timeoutUsecs = 0);
87
91 bool tryAcquire(size_t n = 1);
92
94 MUST_USE_RESULT size_t drainAvailable();
95
98 void release(size_t n = 1);
99
101 ssize_t getValue();
102
109 const void* getDebugMutexOwner() const;
110
111 protected:
118 void initialiseMutex(bool locked);
119 void destroyMutex();
120 bool mutexOwnedByCurrentThread() const;
121
122 private:
124
125 MUST_USE_RESULT SemaphoreResult acquireWithResult(size_t n = 1, size_t timeoutSecs = 0,
126 size_t timeoutUsecs = 0,
127 bool deferTerminal = false);
128
134 void operator=(const Semaphore&);
135
138 class SemaphoreEvent : public Event {
139 public:
140 explicit SemaphoreEvent(size_t nestingLevel);
141 virtual ~SemaphoreEvent();
142 virtual size_t serialize(uint8_t* pBuffer);
143 static bool unserialize(uint8_t* pBuffer, SemaphoreEvent& event);
144 virtual size_t getNumber();
145 };
146
147 size_t magic;
148
149 Atomic<ssize_t> m_Counter;
150 WaitQueue m_Waiters;
151 bool m_bCanInterrupt;
152};
153
154#endif
Definition Event.h:49
void operator=(const Semaphore &)
Semaphore(const Semaphore &)