summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'dev/kernel')
-rw-r--r--dev/kernel/HALKit/AMD64/HalTimer.cc18
-rw-r--r--dev/kernel/KernelKit/KPC.h1
-rw-r--r--dev/kernel/KernelKit/Semaphore.h79
3 files changed, 88 insertions, 10 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalTimer.cc b/dev/kernel/HALKit/AMD64/HalTimer.cc
index 13573880..ae3271f6 100644
--- a/dev/kernel/HALKit/AMD64/HalTimer.cc
+++ b/dev/kernel/HALKit/AMD64/HalTimer.cc
@@ -61,11 +61,8 @@ HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) {
// if not enabled yet.
if (!(*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) & (1 << 0))) {
*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) =
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) |
- (1 << 0); // enable timer
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) =
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) |
- (1 << 3); // one shot conf
+ *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) | (1 << 0) |
+ (1 << 3); // enable timer
}
}
@@ -80,18 +77,21 @@ HardwareTimer::~HardwareTimer() {
BOOL HardwareTimer::Wait() noexcept {
if (fWaitFor < 1) return NO;
+ if (fWaitFor > 1'000'000) return NO; // max 1000s = 16 minutes
- UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue));
+ UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer));
UInt64 femtoseconds_per_tick = (hpet_cap >> 32);
if (femtoseconds_per_tick == 0) return NO;
volatile UInt64* timer = (volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue);
- UInt64 now = *timer;
- UInt64 prev = now + (fWaitFor / femtoseconds_per_tick);
+ UInt64 now = *timer;
+
+ UInt64 fs_wait = fWaitFor * 1'000'000'000'000ULL;
+ UInt64 stop_at = now + (fs_wait / femtoseconds_per_tick);
- while (*timer < (prev)) asm volatile("pause");
+ while (*timer < (stop_at)) asm volatile("pause");
return YES;
}
diff --git a/dev/kernel/KernelKit/KPC.h b/dev/kernel/KernelKit/KPC.h
index a3b13de6..26d1b113 100644
--- a/dev/kernel/KernelKit/KPC.h
+++ b/dev/kernel/KernelKit/KPC.h
@@ -65,6 +65,7 @@ inline constexpr KPCError kErrorFileLocked = 64;
inline constexpr KPCError kErrorDiskIsTooTiny = 65;
inline constexpr KPCError kErrorDmaExhausted = 66;
inline constexpr KPCError kErrorOutOfBitMapMemory = 67;
+inline constexpr KPCError kErrorNetworkTimeout = 68;
/// Generic errors.
inline constexpr KPCError kErrorUnimplemented = -1;
diff --git a/dev/kernel/KernelKit/Semaphore.h b/dev/kernel/KernelKit/Semaphore.h
index a1b5ecad..7fa05008 100644
--- a/dev/kernel/KernelKit/Semaphore.h
+++ b/dev/kernel/KernelKit/Semaphore.h
@@ -6,10 +6,87 @@
#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 (0)
+#define kSemaphoreCountIndex (1)
+
+#define kSemaphoreCount (2)
+
namespace Kernel {
-typedef Int64 Semaphore;
+/// @brief Semaphore structure used for synchronization.
+typedef UInt64 Semaphore[kSemaphoreCount];
+
+/// @brief Checks if the semaphore is valid.
+inline BOOL rtl_sem_is_valid(const Semaphore& sem) {
+ return sem[kSemaphoreOwnerIndex] != 0 || sem[kSemaphoreCountIndex] > 0;
+}
+
+/// @brief Releases the semaphore, resetting its owner and count.
+/// @param sem
+/// @return
+inline BOOL rtl_sem_release(Semaphore& sem) {
+ sem[kSemaphoreOwnerIndex] = 0;
+ sem[kSemaphoreCountIndex] = 0;
+
+ return TRUE;
+}
+
+/// @brief Initializes the semaphore with an owner and a count of zero.
+/// @param sem
+/// @param owner
+/// @return
+inline BOOL rtl_sem_init(Semaphore& sem, Int64 owner) {
+ if (!owner || sem[kSemaphoreOwnerIndex] > 0) {
+ return FALSE;
+ }
+
+ sem[kSemaphoreOwnerIndex] = owner;
+ sem[kSemaphoreCountIndex] = 0;
+
+ return TRUE;
+}
+
+/// @brief Waits for the semaphore to be available, blocking until it is.
+/// @param sem
+/// @param timeout
+/// @return
+inline BOOL rtl_sem_wait(Semaphore& sem, Int64 timeout) {
+ if (!rtl_sem_is_valid(sem)) {
+ return FALSE;
+ }
+
+ if (timeout <= 0) {
+ err_global_get() = kErrorNetworkTimeout;
+
+ return FALSE;
+ }
+
+ if (sem[kSemaphoreCountIndex] > 0) {
+ err_global_get() = kErrorSuccess;
+ sem[kSemaphoreCountIndex]--;
+
+ return TRUE;
+ }
+
+ HardwareTimer timer(timeout);
+ timer.Wait();
+
+ if (sem[kSemaphoreCountIndex] > 0) {
+ err_global_get() = kErrorSuccess;
+ sem[kSemaphoreCountIndex]--;
+
+ return TRUE;
+ }
+
+ err_global_get() = kErrorNetworkTimeout;
+
+ return FALSE; // Failed to acquire semaphore
+} // namespace Kernel
} // namespace Kernel \ No newline at end of file