home *** CD-ROM | disk | FTP | other *** search
- [ 5. Real-Time Scheduling]
- EMBEDDED DOS THREAD SCHEDULING
- ════════════════════════════════════════════════════════════════════════
- The basic unit of asynchronous execution in the Embedded DOS system is
- the thread, and is implemented in the kernel with the thread object.
- Threads may be allocated and deallocated at any time, including interrupt
- time. The kernel schedules the execution of a thread whenever the CPU
- becomes free to execute a thread, and a thread is executable. Threads
- may voluntarily release control over the processor when they wait on
- events or mutexes (see semaphores). They also involuntarily release
- control of the processor when a timer interrupt occurs and the kernel
- decides to give CPU cycles to another thread.
-
- A thread's operating context consists simply of an initial stack segment
- with room to save the entire programmable register set of the CPU. For
- 8088, 8086, 80188, 80186, 80288, and 80286 processors, this includes the
- following registers:
-
- AX, BX, CX, DX, SI, DI, DS, ES, BP, CS, IP, SS, SP, FL
-
- One of the more typical uses of the thread object in the system is as a
- source of task-time control in an interrupt service routine (ISR). For
- example, the disk driver's BPB aging timer expiration routine receives
- control from the kernel at interrupt time, schedules a thread for
- execution to handle the timeout, and then returns control to the caller
- in parallel.
-
- 1. AllocateThread
-
- A thread object is created with the AllocateThread kernel AllocateThread
- function. Once the thread is allocated, it is automatically and
- independently scheduled for execution by the kernel until it is
- deallocated or aborted.
-
- Thread allocation is a lightweight operation. It is acceptable
- to create a thread at interrupt time to delay the bulk of the
- work to task time. The kernel immediately schedules the new
- thread for execution, so ISRs must first perform any interrupt
- cleanup operations before allocating the new thread. Failure to
- re-arm the 8259 before allocating a new thread in interrupt
- context could result in an interval of up to 55ms during which
- interrupts would be masked (this interval is based on a hardware
- timer timebase of 18.2 ticks/second for the typical PC
- implementation; the actual number may vary, depending on the OEM
- adaptation).
-
- The parent's DS and ES general purpose register set context is
- copied to the newly-allocated thread's context, so that the new
- thread starts running with the same values in its general
- register set as the parent. Naturally, the kernel allocates a
- different stack for the new thread, so the SS and SP registers
- are different.
-
- This short form thread allocator automatically allocates some
- kernel pool for the thread's stack, and initializes the thread's
- priority to THREAD_PRIORITY_DEFAULT, or 16384.
-
- Upon return, the macro instruction call clears the carry flag if
- the operation was successful, and sets it if the operation was
- not performed.
-
- Assembly Language Format:
-
- mov ax, OFFSET CGROUP:TargetLabel
- mov cx, CGROUP
- mov dl, SYS_ALLOCATE_THREAD
- int 2dh ; (AX) = new thread handle.
- jc Failure
-
- Macro Instruction Format:
-
- label AllocateThread <TargetLabel>
-
- Portable Request Format:
-
- STATUS AllocateThread(
- IN VOID far (*TargetLabel)()
- );
-
- Parameters:
-
- TargetLabel - Specifies far address of the label or function ___________
- that the new thread will begin executing at. For the
- Macro Instruction format only, the label is assumed to
- be relative to the parent's CS register. The C-language
- interface requires a FAR pointer to a function.
-
- 2. AllocateThreadLong
-
- A higher degree of control over thread allocation is accomplished
- with the long form kernel function, AllocateThreadLong. This AllocateThrea
- function allows the caller to specify the priority at which the
- thread is to start running, and an optional stack segment to be
- used for the thread. The stack segment must be at least 1Kb in
- size. Once the thread is allocated, it is automatically and
- independently scheduled for execution by the kernel until it is
- deallocated or aborted.
-
- Upon return, the macro instruction call clears the carry flag if
- the operation was successful, and sets it if the operation was
- not performed.
-
- Assembly Language Format:
-
- mov ax, OFFSET CGROUP:TargetLabel
- mov cx, CGROUP
- mov bx, <Priority> ; (BX) = thread's initial priority.
- mov es, SEG Stack ; (ES) = stack segment to use.
- mov dl, SYS_ALLOCATE_THREAD_LONG
- int 2dh ; (AX) = new thread handle.
- jc Failure
-
- Macro Instruction Format:
-
- none.
-
- Portable Request Format:
-
- STATUS AllocateThreadLong(
- IN VOID far (*TargetLabel)(),
- IN USHORT StackSegment,
- IN USHORT Priority
- );
-
- Parameters:
-
- TargetLabel - Specifies the far address of the label or
- function at which the new thread will begin executing.
-
- StackSegment - A 16-bit segment value that specifies the
- segment address of a 1K stack to be used by the thread.
- If the specified value is zero, then a stack will be
- automatically allocated from the kernel's memory pool,
- as is the case with AllocateThread.
-
- Priority - A 16-bit value that specifies the initial
- scheduling priority for the new thread. Higher values
- have more urgent priority than lower values. By
- definition, The AllocateThread allocator creates
- threads with a priority equal to THREAD_PRIORITY_DEFAULT.
- The following priority values are prearchitected:
-
- THREAD_PRIORITY_LOW - Lowest possible priority.
- THREAD_PRIORITY_DEFAULT - The default priority.
- THREAD_PRIORITY_HI - The highest priority.
- THREAD_PRIORITY_RESERVED - The lowest reserved priority.
-
- 3. DeallocateThread
-
- A thread object is removed from the system with the
- DeallocateThread kernel function. Once the thread is
- deallocated, its object is returned to the system to be recycled,
- and another thread is scheduled for execution. If no other
- threads in the system are available for execution, then the
- scheduler executes the idle loop until an interrupt routine is
- executed which causes a new thread to be allocated or a blocked
- thread to be released.
-
- A thread may only remove itself from the system with this
- function. A thread may remove another thread in the system
- through the AbortThread function, although this function must be AbortThread
- used with care as it does not clean-up acquired resources.
-
- Assembly Language Format:
-
- mov dl, SYS_DEALLOCATE_THREAD
- int 2dh ; never returns (current thread dies).
-
- Macro Instruction Format:
-
- label DeallocateThread
-
- Portable Request Format:
-
- STATUS DeallocateThread();
-
- Parameters:
-
- none.
-
- 4. AbortThread
-
- A thread may remove another thread object in the system with the
- AbortThread kernel function. The kernel does not perform cleanup
- with regard to resources held by the target thread, including but
- not limited to pool, events, mutexes, timers, or spinlocks.
-
- A thread may remove itself from the system with this function by
- specifying a thread handle equal to zero. This form has
- identical results to calling the DeallocateThread function.
-
- Upon return, the macro instruction call clears the carry flag if
- the operation was successful, and sets it if the operation was
- not performed.
-
- Assembly Language Format:
-
- mov dl, SYS_ABORT_THREAD
- mov ax, <ThreadHandle> ; (AX) = handle of thread to abort.
- int 2dh ; destroys target thread.
- jc Failure
-
- Macro Instruction Format:
-
- none.
-
- Portable Request Format:
-
- STATUS AbortThread(
- IN HANDLE ThreadHandle
- );
-
- Parameters:
-
- ThreadHandle - A 16-bit handle to a thread object as
- returned by the AllocateThread or AllocateThreadLong
- kernel functions. If the specified value is zero, then
- the current thread aborts itself.
-
- 5. PrioritizeThread
-
- A thread may change its priority with the PrioritizeThread kernel
- function. If a thread lowers its priority, then the kernel
- automatically performs a rescheduling to allow other threads with
- potentially higher priorities to run.
-
- Assembly Language Format:
-
- mov dl, SYS_PRIORITIZE_THREAD
- mov ax, <ThreadHandle> ; (AX) = thread handle.
- mov cx, <Priority> ; (CX) = new thread priority.
- int 2dh ; change the priority.
- jc Failure
-
- Macro Instruction Format:
-
- none.
-
- Portable Request Format:
-
- STATUS PrioritizeThread(
- IN HANDLE ThreadHandle,
- IN USHORT Priority
- );
-
- Parameters:
-
- ThreadHandle - A 16-bit handle to a thread object as
- returned by the AllocateThread or AllocateThreadLong
- kernel functions. If the specified value is zero, then
- the current thread's priority is adjusted.
-
- Priority - A 16-bit handle to a thread object as returned by
- the AllocateThread or AllocateThreadLong kernel
- functions. If the specified value is zero, then the
- current thread's priority is adjusted.
-
- 6. EnterCriticalSection
-
- A thread may disable context switching with the
- EnterCriticalSection kernel function. The kernel allows nesting
- of EnterCriticalSection calls and counts them as the number of
- reasons why round-robin reschedulings within a priority should
- not take place. The LeaveCriticalSection decrements this counter.
-
- After the EnterCriticalSection function returns, context
- switching is disabled. This is useful when manipulating data or
- hardware that cannot be shared among tasks, but that is under
- both task-time control and interrupt-time control.
-
- Assembly Language Format:
-
- mov dl, SYS_ENTER_CRITICAL_SECTION
- int 2dh ; go non-preemptive.
-
- Macro Instruction Format:
-
- none.
-
- Portable Request Format:
-
- STATUS EnterCriticalSection();
-
- Parameters:
-
- none.
-
- 7. LeaveCriticalSection
-
- A thread may reenable context switching with the
- EnterCriticalSection kernel function. The kernel allows nesting
- of EnterCriticalSection calls and counts them as the number of
- reasons why round-robin reschedulings within a priority should
- not take place.
-
- The LeaveCriticalSection decrements this counter, keeping context
- switching disabled until the EnterCriticalSection nesting level
- is zero. When this happens, a forced rescheduling occurs.
-
- Assembly Language Format:
-
- mov dl, SYS_LEAVE_CRITICAL_SECTION
- int 2dh ; allow preemption.
-
- Macro Instruction Format:
-
- none.
-
- Portable Request Format:
-
- STATUS LeaveCriticalSection();
-
- Parameters:
-
- none.
-
- 8. PassTimeSlice
-
- A thread may cause a forced rescheduling to occur with the
- PassTimeSlice kernel function. Regardless of the critical
- section level, this function immediately saves the state of the
- current thread, and looks for the next highest priority thread in
- the system, which may be the same thread.
-
- The reader should be advised that calling PassTimeSlice while the
- critical section level is non-zero will possibly result in
- another thread gaining control with preemption disabled. If the
- newly-executing thread is not prepared to decrement the critical
- section level on behalf of the first thread, or if it is not
- prepared to issue its own call to PassTimeSlice, the original
- thread might not again receive control.
-
- Assembly Language Format:
-
- mov dl, SYS_PASS_TIME_SLICE
- int 2dh ; force context switch.
-
- Macro Instruction Format:
-
- none.
-
- Portable Request Format:
-
- STATUS PassTimeSlice();
-
- Parameters:
-
- none.