diff options
| author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2013-07-20 08:41:41 +0200 | 
|---|---|---|
| committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2013-07-20 08:43:10 +0200 | 
| commit | e14b2f0d2406311a6fcdaea313584995ec8adefd (patch) | |
| tree | f2cffca4fe334aeb873cce8a77bd5b6f98cc0096 /os | |
| parent | 657d427aa41e6e05c8c4d4b1179b42d3363e8018 (diff) | |
Add support for sleeping threads.scheduler_improvements
Diffstat (limited to 'os')
| -rw-r--r-- | os/thread.cpp | 1 | ||||
| -rw-r--r-- | os/thread.h | 55 | ||||
| -rw-r--r-- | os/time.h | 9 | 
3 files changed, 53 insertions, 12 deletions
| diff --git a/os/thread.cpp b/os/thread.cpp index 0f2437d..432727a 100644 --- a/os/thread.cpp +++ b/os/thread.cpp @@ -1,5 +1,6 @@  #include "thread.h"  List<Thread> Thread::ready_queue __attribute__ ((init_priority (1000))); +List<Thread> Thread::sleep_queue;  Thread Thread::main_thread __attribute__ ((init_priority (1001)));  Thread* Thread::active_thread = &Thread::main_thread; diff --git a/os/thread.h b/os/thread.h index 72ee275..9270727 100644 --- a/os/thread.h +++ b/os/thread.h @@ -4,6 +4,8 @@  #include <stdint.h>  #include <util/intrusive_list.h> +#include "time.h" +  class Thread {  	friend void switch_context(); @@ -33,20 +35,42 @@ class Thread {  		int_frame_t* sp; +		enum State { +			Running, +			Sleeping, +		}; +		 +		State state; +		uint32_t sleep_deadline; +		  		ListHandle<Thread> queue_handle;  		static List<Thread> ready_queue; +		static List<Thread> sleep_queue;  		static Thread* active_thread;  		static Thread main_thread;  		static bool reschedule() { -			//active_thread = active_thread->next; +			uint32_t now = Time::time(); -			// TODO: Check whether active thread still is ready. +			// Go through sleep queue. +			for(auto h : sleep_queue) { +				// Move to ready queue if deadline has expired. +				if(h->p->sleep_deadline <= now) { +					h->p->state = Running; +					ready_queue.append(*h); +					 +					// Moving one element makes the iterator unusable, so break here. +					break; +				} +			} -			// Move thread to end of ready queue. -			ready_queue.append(active_thread->queue_handle); +			// Check whether active thread still is ready. +			if(active_thread->state == Running) { +				// Move thread to end of ready queue. +				ready_queue.append(active_thread->queue_handle); +			}  			// Check whether any threads are ready to run.  			if(ready_queue.empty()) { @@ -78,6 +102,29 @@ class Thread {  			ready_queue.append(queue_handle);  		} +		void set_sleeping(uint32_t until) { +			sleep_deadline = until; +			state = Sleeping; +			 +			// Search for thread with later deadline. +			for(auto h : sleep_queue) { +				// Insert before if found. +				if(h->p->sleep_deadline > sleep_deadline) { +					queue_handle.insert_before(*h); +					return; +				} +			} +			 +			// Otherwise append to end of queue. +			sleep_queue.append(queue_handle); +		} +		 +		static void sleep(uint32_t delay) { +			active_thread->set_sleeping(Time::time() + delay); +			 +			yield(); +		} +		  		static inline void yield() {  			asm volatile("svc 0" ::: "memory");  		} @@ -1,7 +1,7 @@  #ifndef TIME_H  #define TIME_H -#include "thread.h" +#include <stdint.h>  struct STK_t {  	volatile uint32_t CTRL; @@ -24,13 +24,6 @@ class Time {  		inline static uint32_t time() {  			return systime;  		} -		 -		inline static void sleep(uint32_t ms) { -			ms += systime; -			while(systime < ms) { -				Thread::yield(); -			} -		}  };  #endif | 
