summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/KernelKit/Semaphore.h
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-08-16 19:56:21 +0200
committerGitHub <noreply@github.com>2025-08-16 19:56:21 +0200
commit1a32b9307357ac0fc9095e853b2b6d94f9fe62bb (patch)
treef41f723659c8926e38182fbe062746d821ab487e /dev/kernel/KernelKit/Semaphore.h
parenteb9df5eea339812513c25a8d3b2eeb03c633e7ac (diff)
parentb301047903b79560dce69085fc271a653a1eb4b6 (diff)
Merge pull request #55 from nekernel-org/dev
v0.0.4
Diffstat (limited to 'dev/kernel/KernelKit/Semaphore.h')
-rw-r--r--dev/kernel/KernelKit/Semaphore.h97
1 files changed, 96 insertions, 1 deletions
diff --git a/dev/kernel/KernelKit/Semaphore.h b/dev/kernel/KernelKit/Semaphore.h
index a1b5ecad..f73f36ed 100644
--- a/dev/kernel/KernelKit/Semaphore.h
+++ b/dev/kernel/KernelKit/Semaphore.h
@@ -6,10 +6,105 @@
#pragma once
+/// @author Amlal El Mahrouss
+/// @file Semaphore.h
+/// @brief Semaphore structure and functions for synchronization in the kernel.
+
#include <CompilerKit/CompilerKit.h>
#include <KernelKit/Timer.h>
#include <NeKit/Defines.h>
+#define kSemaphoreOwnerIndex (0U)
+#define kSemaphoreCountIndex (1U)
+
+#define kSemaphoreCount (2U)
+
+#define kSemaphoreIncrementOwner(sem) (sem[kSemaphoreOwnerIndex]++)
+#define kSemaphoreDecrementOwner(sem) (sem[kSemaphoreOwnerIndex]--)
+
namespace Kernel {
-typedef Int64 Semaphore;
+/// @brief Semaphore structure used for synchronization.
+typedef UInt64 SemaphoreArr[kSemaphoreCount];
+
+/// @brief Checks if the semaphore is valid.
+inline BOOL rtl_sem_is_valid(const SemaphoreArr& sem, UInt64 owner = 0) {
+ return sem[kSemaphoreOwnerIndex] == owner && sem[kSemaphoreCountIndex] > 0;
+}
+
+/// @brief Releases the semaphore, resetting its owner and count.
+/// @param sem
+/// @return
+inline BOOL rtl_sem_release(SemaphoreArr& sem) {
+ sem[kSemaphoreOwnerIndex] = 0;
+ sem[kSemaphoreCountIndex] = 0;
+
+ return TRUE;
+}
+
+/// @brief Initializes the semaphore with an owner and a count of zero.
+/// @param sem the semaphore array to use.
+/// @param owner the owner to set, could be anything identifitable.
+/// @return
+inline BOOL rtl_sem_acquire(SemaphoreArr& sem, UInt64 owner) {
+ if (!owner) {
+ err_global_get() = kErrorInvalidData;
+ return FALSE; // Invalid owner
+ }
+
+ sem[kSemaphoreOwnerIndex] = owner;
+ sem[kSemaphoreCountIndex] = 0;
+
+ return TRUE;
+}
+
+/// @brief Waits for the semaphore to be available, blocking until it is.
+/// @param sem
+/// @param timeout
+/// @param condition condition pointer.
+/// @return
+inline BOOL rtl_sem_wait(SemaphoreArr& sem, UInt64 owner, UInt64 timeout,
+ BOOL* condition = nullptr) {
+ if (!rtl_sem_is_valid(sem, owner)) {
+ return FALSE;
+ }
+
+ if (timeout <= 0) {
+ err_global_get() = kErrorTimeout;
+
+ return FALSE;
+ }
+
+ if (!condition || *condition) {
+ if (sem[kSemaphoreCountIndex] == 0) {
+ err_global_get() = kErrorUnavailable;
+ return FALSE;
+ }
+
+ err_global_get() = kErrorSuccess;
+ sem[kSemaphoreCountIndex]--;
+
+ return TRUE;
+ }
+
+ HardwareTimer timer(timeout);
+ BOOL ret = timer.Wait();
+
+ if (ret) {
+ if (!condition || *condition) {
+ if (sem[kSemaphoreCountIndex] == 0) {
+ err_global_get() = kErrorUnavailable;
+ return FALSE;
+ }
+
+ err_global_get() = kErrorSuccess;
+ sem[kSemaphoreCountIndex]--;
+
+ return TRUE;
+ }
+ }
+
+ err_global_get() = kErrorTimeout;
+
+ return FALSE; // Failed to acquire semaphore
+}
} // namespace Kernel \ No newline at end of file