Semaphore with a timeout
Posted: Sun May 27, 2012 10:22 pm
My OS is generally coming along nicely, and one thing that I want to implement now is the ability to block, but with a timeout. One of my major API pet-peeves is when a function can block, but there is no way to specify a timeout. (linux wait() comes to mind as particularly annoying). So I would like to get this right before implementing most of my system calls.
Currently, my scheduling design is as follows:
there is an array of run-lists, (one for each priority level).
when a thread becomes blocked, it is NOT queued into a run-list. Instead it is expected to be held in some semaphores wait queue.
to wake a thread, the semaphore marks the thread as runnable and en-queue's it into one of the scheduler's run-lists.
This works great, and is efficient since the scheduler doesn't need to even look at blocked threads. But it makes the idea of implementing a timeout a little less obvious.
So, thoughts about timeouts:
Clearly each scheduler tick (or some fixed interval), the scheduler needs to test blocked threads to see if enough time has passed that they need to wake up.
But my scheduler doesn't have an explicit list of blocked threads. Even if it did, Threads don't have any knowledge of which semaphore (if any) is "holding it". So I would need to add some extra data to threads.
I could implement things this way:
Threads would have a pointer to a semaphore which asked it to block, or null if it is runnable.
When a semaphore blocks with a timeout, the scheduler will put the thread into a special "sleepers" list, which gets checked routinely (no need to specially threat threads that block forever)
if the scheduler sees a thread that needs to be woken up, it gets the owning semaphore from it, removes the thread from its list, marks the thread as runnable and finally put it into the runqueue.
While I believe this would work, It doesn't strike me as a very clean or efficient design. So I was wondering how (if any of you have) you guys have implemented blocking with a timeout.
Currently, my scheduling design is as follows:
there is an array of run-lists, (one for each priority level).
when a thread becomes blocked, it is NOT queued into a run-list. Instead it is expected to be held in some semaphores wait queue.
to wake a thread, the semaphore marks the thread as runnable and en-queue's it into one of the scheduler's run-lists.
This works great, and is efficient since the scheduler doesn't need to even look at blocked threads. But it makes the idea of implementing a timeout a little less obvious.
So, thoughts about timeouts:
Clearly each scheduler tick (or some fixed interval), the scheduler needs to test blocked threads to see if enough time has passed that they need to wake up.
But my scheduler doesn't have an explicit list of blocked threads. Even if it did, Threads don't have any knowledge of which semaphore (if any) is "holding it". So I would need to add some extra data to threads.
I could implement things this way:
Threads would have a pointer to a semaphore which asked it to block, or null if it is runnable.
When a semaphore blocks with a timeout, the scheduler will put the thread into a special "sleepers" list, which gets checked routinely (no need to specially threat threads that block forever)
if the scheduler sees a thread that needs to be woken up, it gets the owning semaphore from it, removes the thread from its list, marks the thread as runnable and finally put it into the runqueue.
While I believe this would work, It doesn't strike me as a very clean or efficient design. So I was wondering how (if any of you have) you guys have implemented blocking with a timeout.