Quellcode durchsuchen

Implement semaphore class

DricomDragon vor 5 Jahren
Ursprung
Commit
f8319adb2f
4 geänderte Dateien mit 46 neuen und 1 gelöschten Zeilen
  1. 23 0
      prog/sources/Semaphore.cpp
  2. 20 0
      prog/sources/Semaphore.h
  3. 1 1
      prog/sources/xtr.cpp
  4. 2 0
      prog/sources/xtr.h

+ 23 - 0
prog/sources/Semaphore.cpp

@@ -0,0 +1,23 @@
+#include "all-headers.h"
+
+Semaphore::Semaphore (const uint32_t inInitialValue) :
+mWaitingTaskList(), mValue (inInitialValue) {}
+
+void Semaphore::sys_P (KERNEL_MODE) {
+	if (mValue == 0) {
+		kernel_blockRunningTaskInList(MODE_ mWaitingTaskList);
+	}
+	else {
+		mValue --;
+	}
+}
+
+void Semaphore::sys_V (IRQ_MODE) {
+	TaskControlBlock * taskToRelease( mWaitingTaskList.removeFirstTask(MODE) );
+	if (taskToRelease == nullptr) {
+		mValue ++;
+	}
+	else {
+		kernel_makeTaskReady(MODE_ taskToRelease);
+	}
+}

+ 20 - 0
prog/sources/Semaphore.h

@@ -0,0 +1,20 @@
+# include "task-list-32-tasks.h"
+
+class Semaphore {
+	protected: TaskList mWaitingTaskList ;
+	protected: uint32_t mValue ;
+
+	public: Semaphore (const uint32_t inInitialValue) ;
+
+	//$service semaphore.V
+	public: void V (USER_MODE) asm ("semaphore.V") ;
+	public: void sys_V (IRQ_MODE) asm ("service.semaphore.V") ;
+
+	//$service semaphore.P
+	public: void P (USER_MODE) asm ("semaphore.P") ;
+	public: void sys_P (KERNEL_MODE) asm ("service.semaphore.P") ;
+
+	// Disable copy
+	private: Semaphore (const Semaphore &) = delete ;
+	private: Semaphore & operator = (const Semaphore &) = delete ;
+};

+ 1 - 1
prog/sources/xtr.cpp

@@ -154,7 +154,7 @@ static TaskList gReadyTaskList ;
 static TaskList gDeadlineWaitingTaskList ;
 
 
-static void kernel_makeTaskReady (IRQ_MODE_ TaskControlBlock * inTaskPtr) {
+void kernel_makeTaskReady (IRQ_MODE_ TaskControlBlock * inTaskPtr) {
 	XTR_ASSERT_NON_NULL_POINTER (inTaskPtr) ;
 	gReadyTaskList.enterTask (MODE_ inTaskPtr) ;
 }

+ 2 - 0
prog/sources/xtr.h

@@ -17,6 +17,8 @@ void kernel_createTask (INIT_MODE_
 
 struct TaskControlBlock ;
 
+void kernel_makeTaskReady (IRQ_MODE_ TaskControlBlock * inTaskPtr);
+
 TaskControlBlock * descriptorPointerForTaskIndex (const uint8_t inTaskIndex) ;
 
 uint8_t indexForDescriptorTask (const TaskControlBlock * inTaskPtr) ; // should be not nullptr