Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!ames!eos!shelby!lindy!news From: BR.SJE@forsythe.stanford.edu (Steve Eastman) Newsgroups: comp.lang.modula2 Subject: TRANSFER(p1,p2) In a Clock Tick ISR Message-ID: <4887@lindy.Stanford.EDU> Date: 25 Sep 89 20:06:51 GMT Sender: news@lindy.Stanford.EDU (News Service) Distribution: na Lines: 61 Remember, in M2 things of type PROCESS must function in a certain way, else the thing you've got isn't M2. If the thing you've got isn't M2, you won't be able to use any one else's modules in a program of your own. Hereafter I will call Modula-2 processes "threads". This term may help reduce the confusion that I think exists for UNIX programmers that use M2. Usually a thing called a "process" has its own address space and communicates with other processes in a way that coordinates both processes at the time of the communication--when data transfer takes place. Threads on the other hand are low overhead, low level, things. They have nothing to do with processes (except they me be used as part of the implementation of processes). In the definition of Modula-2 a thread (or as Wirth calls them "process") must be sequential. That is, they must not be mutually preemptive. The exception is that an interrupt service routines (ISR) thread may preempt another thread of lower priority. A monitor (priority module) must protect its shared variables against alteration during its execution. When a monitor contains an ISR a very interesting state of affairs develops. All ISRs have at least one shared variable which they alter. This variable is passed to it when an interrupt occurs--the thing pointed to by the pointer that is the second parameter to the IOTRANSFER procedure--the interrupted thread. The way in which the variable is altered is that it is changed to the "not running" state. When the ISR is done it will change the state of the interrupted thread back to "running" via IOTRANSFER. It can only make this second change with impunity because it knows the thread was in the "running" state in the beginning and has protected it from alteration through out its execution. Therefore, all ISRs must execute in such a way that the state of the interrupted thread is not altered in any way, then execute the interrupted thread. The only way to make sure of this is to (A) not transfer to any other thread, or (B) transfer only to threads in the same priority module as the ISR such that the priority level never is lowered. The reason for this is that if the thread being transferred to is of a lower priority, then the owner of the interrupted thread could come back into control and change the state of the interrupted thread to "not running" or destroy it altogether. Then, when the ISR comes back into control, the ISR would, believing the thread to be runnable as a matter of course, IOTRANSFER to it. Thus, it would have transferred to and made "running" a thread which its owner believes to be "blocked" or nonexistent. This conflict as to the state of an interrupted process probably will have tragic consequences on the execution of a program. Until I discovered the above described tangle of threads, my multi-threaded system had some very weird bugs: threads running when they were "blocked", programs running away, etc..