This page is part of the web mail archives of SRFI 21 from before July 7th, 2015. The new archives for SRFI 21 contain all messages, not just those from before July 7th, 2015.
Here is a summary of the real-time extensions that were added to SRFI 18. 1) The concept of "base priority", "boosted priority", and "effective priority". All of these priorities are represented with real numbers (the maximum and minimum are plus and minus infinity). This allows deadlines to be expressed by setting the base priority to the negation of the deadline time, i.e. (thread-base-priority-set! thread (- (+ (time->seconds (current-time)) 10))) The "priority boost" (which should be 0 when deadlines are used) is added to the base priority to get the boosted priority, when the thread blocks. By carefully choosing the base priority and priority boost it is possible to set up an interactive thread so that it has good I/O response time without being a CPU hog when it performs long computations. The effective priority of a thread T is equal to the maximum of T's boosted priority and the effective priority of all the threads that are blocked on a mutex owned by T. This "priority inheritance" avoids priority inversion problems that would prevent a high priority thread blocked at the entry of a critical section to progress because a low priority thread inside the critical section is preempted for an arbitrary long time by a medium priority thread. 2) A precise definition of scheduling constraints based on priorities and blocking time, and a notion of time ordering of events based on a clock with a finite resolution. The following are other changes which I also intend to add to SRFI 18: 3) Threads have a "specific" field which can be used to store thread specific data (i.e. the "thread local storage" of other thread systems). 4) Mutexes now have 4 states: locked (either owned or not owned) and unlocked (either abandoned or not abandoned). A locked/not-owned mutex is not linked to a particular thread, which means no priority inheritance will occur if a thread blocks on that mutex. 5) "mutex-owner" has been renamed "mutex-state". 6) "mutex-lock!" can be passed a third argument to specify how the ownership of the mutex is changed. If the argument is #f the mutex will become locked/not-owned, if the argument is a thread the mutex will become locked/owned and owned by that thread, and if the argument is not supplied the mutex will become locked/owned by the current thread. 7) "make-mutex" can no longer create a mutex that is initially owned by a thread. This is so the only places a mutex is locked and unlocked is when "mutex-lock!" and "mutex-unlock!" are called, making it easier to reason about locks. 8) The functionality of "condition-variable-wait!" has been folded into "mutex-unlock!", for the reason given in 7) and also because there are two ways to lock a mutex and extra parameters would have to be passed to condition-variable-wait! to specify the type of locking to use once the wait is over. Note that this means an explicit call to mutex-lock! is needed, for example: (define (semaphore-wait! sema) (mutex-lock! (vector-ref sema 1)) (let ((n (vector-ref sema 0))) (if (> n 0) (begin (vector-set! sema 0 (- n 1)) (mutex-unlock! (vector-ref sema 1))) (begin (mutex-unlock! (vector-ref sema 1) (vector-ref sema 2)) (semaphore-wait! sema)))) Marc