Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Alex Newsgroups: comp.lang.forth Subject: Re: Really? Date: Wed, 8 Feb 2017 13:43:28 +0000 Organization: A noiseless patient Spider Lines: 90 Message-ID: References: <1239a88b-a574-401b-9454-50ac7e000049@googlegroups.com> <5899a408.386236853@news.eternal-september.org> <87shnqw989.fsf@nightsong.com> <589a303c.422128955@news.eternal-september.org> <01fb25bd-7975-4ca5-b9e6-1024cb772c7a@googlegroups.com> <1207313c-ffcd-4640-a619-f1424dcf75cc@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Wed, 8 Feb 2017 13:41:42 -0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="5a5587626bd3f27417c51034cb1db992"; logging-data="9257"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18WCqjFjbuHDDrqedLqS1G7QoUw7/GDKOY=" User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 In-Reply-To: Cancel-Lock: sha1:dgMsqnBwnnWowjP5pTVEHEO+3mo= Xref: csiph.com comp.lang.forth:54720 On 2/8/2017 08:34, rickman wrote: >>>> Looking at the whole application is going to be difficult when there >>>> is 16MB of source-code --- the programmers need to understand the >>>> concept of re-entrancy --- they can't pass data between functions in >>>> global variables. >> >>> You are aware that re-entrancy is only an issue with multitasking, >>> right? Was this OS multitasking? >> >> Re-entrancy is not just an issue with multi-tasking. >> >> If a function uses PAD internally and calls another function that uses >> PAD internally, then chaos will result. >> >> This should be obvious to anybody! Function A setting PAD and calling B that sets PAD is a simple case of the side effect of using global variables, specifically when they are modified. (No-one objects to constants as globals, because they are only ever read and not set.) For this kind of problem, only rewriting the code will fix it, but it definitely does not need to be reentrant. > > I don't know I've ever seen this referred to as reentrancy. Looking on > the web it's hard to find authoritative sources about reentrancy... but > here is wikipedia, not that I consider wikipedia to necessarily be > authoritative. > > ******************************** > In computing, a computer program or subroutine is called reentrant if it > can be interrupted in the middle of its execution, and then be safely > called again ("re-entered") before its previous invocations complete > execution. The interruption could be caused by an internal action such > as a jump or call, or by an external action such as a hardware interrupt > or signal. Once the reentered invocation completes, the previous > invocations will resume correct execution. > ******************************** It's not very good. > > So they do allow for the case of a routine calling another and ending up > calling itself. But what you describe is one routine calling another > that shares a common data structure. That's not technically reentrancy. > Still, I suppose I get your point. Recursion is a form of reentrancy. > But that simply means you need to be aware when routines can be called > recursively which is very infrequent. Otherwise, you simply have to be > aware when you are sharing data structures. That's exactly the point. Excuse my lecture, but... External hardware interrupts may cause key components of the OS or application to be entered while they are executing on behalf of another task. When multiprogramming (more than one processor), even the software can interfere with itself. There are a few solutions. 1. Suspend interrupts while dealing with interrupts. Doesn't really provide a solution when multiple processors are involved, since the same code can be executed by several processors. 2. Make sure that the routines do not refer to global areas, so that each incomplete execution is not interfered with by a new execution of the same code. This can be problematic (we may have only 1 of a given resource, but several tasks sharing it for example), so another technique is used; 3. For small shared resources like counters or addresses, get the processors to help by using atmoic operations that most provide. For instance, the Intel x86 LOCK prefix and CMPXCHG instructions do this. 4. For larger shared resources, employ software locking or enqueuing, where tasks will wait for shared resources to be free. Tasks that can get the lock proceed and then release it; tasks that can't, wait until the lock is released. This generally requires atomic operations to accomplish. Back to Hugh's comments about passing data via global variables making code non-reentrant. : increment ( addr -- ) dup @ 1+ swap ! ; \ increment value at address Even though INCREMENT does not itself refer to global variables and appears at first sight to be reentrant, two tasks using the shared area SHARED invoking SHARED INCREMENT will give inconsistent results when SHARED is fetched. -- Alex