Home |
RTKernel-32 Programming Manual Multitasking, Real-Time, and RTKernel-32 Reentrance Alternate APIs for RTKernel-32 |
ReentranceThe term reentrance denotes the problems that can occur when the same code is simultaneously executed by several tasks or when global data is simultaneously accessed by several tasks. Reentrant code means that a task may "re-enter" the code before another task has left it. In a multitasking environment, care should be taken that as much code as possible is reentrant so that it may be used by several tasks simultaneously. The problems that can occur when global data is used shall be illustrated by a little example. Assuming that two tasks are supposed to count something and the program contains a global variable "Counter" of type int which is initialized with the value 0. Both tasks perform the statement Counter = Counter + 1; whenever an event to be counted occurs. This statement might be translated by the compiler as follows: MOV EAX, [Counter] ; line 1 ADD EAX, 1 ; line 2 MOV [Counter], EAX ; line 3 For the sake of simplicity, assume that both tasks have the same priority, preemptive scheduling is enabled, and time slicing is active. Now the following could happen: Task 1 recognizes an event and begins to execute the machine language instructions given above. After line 1 has been executed (register EAX contains 0), a time slice task switch occurs and Task 2 is activated. Task 2 also recognizes an event and increments variable Counter to a value of 1 without being interrupted. At some later time, Task 1 resumes (at line 2), increments EAX from 0 to 1 and stores this value in the variable Counter. Even though Counter has been incremented twice, it now has a value of 1 and not 2. This example shows that two - or more - tasks must never access global data simultaneously if at least one of the tasks can modify the data. Actually, it is not the code which is non-reentrant, but rather, it is the data being manipulated by the code. Even when the statement "Counter = Counter + 1;" is included in both tasks separately, the reentrance problem is not solved. As a consequence, shared global data should be avoided. The same is true for local variables declared as static. If this is impossible, access to global data should be protected by semaphores. Advanced Topics, Mutual Exclusion discusses how to implement mutual exclusion areas in order to avoid access conflicts. Multitasking, Real-Time, and RTKernel-32
|