diff options
| -rw-r--r-- | include/cpu.h | 2 | ||||
| -rw-r--r-- | include/sys/schedule.h | 2 | ||||
| -rw-r--r-- | src/sys/schedule.c | 39 | 
3 files changed, 41 insertions, 2 deletions
diff --git a/include/cpu.h b/include/cpu.h index 9bda3e8..393fe2f 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -94,5 +94,7 @@ static inline void* getirqstack(void)  #define SYS_FREE_STACK  3  #define SYS_LOCK        4  #define SYS_UNLOCK      5 +#define SYS_SEMAPHORE_P 6 +#define SYS_SEMAPHORE_V 7  #endif diff --git a/include/sys/schedule.h b/include/sys/schedule.h index 12c8fec..d0d938c 100644 --- a/include/sys/schedule.h +++ b/include/sys/schedule.h @@ -62,6 +62,8 @@ extern void schedule(void);  extern void cleanup(void);  void yield(void);  void sched_mutex_yield(void* m); +void sched_semaphore_yield(void* s);  void sched_mutex_resurrect(void* m); +void sched_semaphore_resurrect(void* s);  #endif diff --git a/src/sys/schedule.c b/src/sys/schedule.c index 0a62350..389aa1d 100644 --- a/src/sys/schedule.c +++ b/src/sys/schedule.c @@ -194,14 +194,14 @@ struct ThreadEntry* find_mutex_wait_next(void* m)  	return 0;  } -struct ThreadEntry* find_signal_wait_next(void* m) +struct ThreadEntry* find_signal_wait_next(void* s)  {  	for (unsigned char p = 0; p < PRIORITIES; p++) {  		struct ThreadQueue* queue = &scheduler.swait[p];  		struct ThreadEntry* prev = &queue->start;  		struct ThreadEntry* entry = prev->next;  		while (entry->entry_type != END_ENTRY) { -			if (entry->thread->mptr == m) +			if (entry->thread->mptr == s)  				return prev;  			prev = entry;  			entry = entry->next; @@ -404,6 +404,23 @@ void sched_mutex_yield(void* m)  	}  } +void sched_semaphore_yield(void* s) +{ +	struct Thread* rthread = scheduler.rthread; +	// usrloopthread should not be yielded +	if (rthread == &usrloopthread) +		return; +	unsigned char priority = rthread->priority; +	// Signify which lock this thread is waiting for +	rthread->mptr = s; +	struct ThreadEntry* rt; +	// Remove from top of running queue +	rt = pop_from_queue(THREAD_READY, priority); +	if (rt != 0) +		// Push to bottom of wait queue +		push_to_queue(rt->thread, THREAD_SWAIT, priority); +} +  void sched_mutex_resurrect(void* m)  {  	// Find any mutex to resurrect @@ -432,3 +449,21 @@ void sched_mutex_resurrect(void* m)  		prepend_to_queue(tentry->thread, THREAD_READY, op);  	}  } + +void sched_semaphore_resurrect(void* s) +{ +	// Find any signal/ semaphore to resurrect +	struct ThreadEntry* prev = find_signal_wait_next(s); +	if (prev == 0) +		return; +	struct ThreadEntry* entry = prev->next; +	struct Thread* thread = entry->thread; +	// Resurrect the thread +	thread->mptr = 0; +	// Remove from wait queue +	entry = remove_next_from_queue(prev); +	if (entry == 0) +		return; +	// Add to ready queue +	push_to_queue(entry->thread, THREAD_READY, entry->thread->priority); +}  | 
