Xref: utzoo comp.lang.misc:1370 comp.unix.wizards:7465 comp.lang.c:8688 Path: utzoo!mnetor!uunet!munnari!vuwcomp!cantuar!james From: james@cantuar.UUCP (J. Collier) Newsgroups: comp.lang.misc,comp.unix.wizards,comp.lang.c Subject: Re: From Modula to Oberon Message-ID: <269@cantuar.UUCP> Date: 28 Mar 88 21:16:56 GMT References: <2827@enea.se> <1557@pasteur.Berkeley.Edu> <3764@bloom-beacon.MIT.EDU> <1139@PT.CS.CMU.EDU> <1758@sugar.UUCP> Reply-To: james@cantuar.UUCP (J. Collier) Organization: University of Canterbury, Christchurch, New Zealand Lines: 60 Summary: Expires: Sender: Followup-To: Distribution: Keywords: Peter da Silva (peter@sugar.UUCP) writes: >.... >I'd like to see the following functions become standard in 'C': >.... >COROUTINE -- Build a jmp_buf for a coroutine. >.... >This sets up the stack and jmp_buf so that a call to "longjmp(jmp_buf)" >will appear to be a call to entry(). > [implementation outlines deleted] I seem to remember a minor war in the letters to 'Software Practice and Experience' [I think] on this subject a couple of years back. (Wasn't it peaceful in the days when it took a month or two to get the next installment..) Correct me if I'm wrong, but I find that on some machines (well, on BSD Vaxen anyway) setjmp()/longjmp() can't be used to implement coroutines because longjmp() unwinds the stack destructively while checking for botches. A small amount of in-line assembly language is therefore necessary for transferring control. I agree with Peter's view that coroutines should be supported in the C library. As he says, coroutine packages are quite easy to write and they are indispensible for certain classes of application (I wanted one originally for a window server/multiplexor). The current situation where everybody brews their own isn't really acceptable. The programs aren't portable, and the semantics differ sufficiently to make things confusing for the reader. The details will have to be thrashed out before a standard is defined. Pre-empting threads which share a common data space are probably not a good idea for most purposes - the synchronisation problems usually outweigh any advantages. Leave true multitasking to the operating system and keep to protected data spaces if possible, unless you enjoy wrapping semaphore primitives around every second line of code. (OK, I've just spent 2 years doing this on the Mac, but that's different - no OS processes). Threads with explicit sleep() calls and round-robin transfer - as suggested by Peter - are one way of organising things. I suppose it's a matter of personal taste, but I prefer a system where the 'new_coroutine()' call returns a pointer to a structure which contains at least the context information and the stack base pointer, a reduced form of Peter's 'proc' structure. This makes it easier to tailor your use of coroutines; sometimes you want to transfer control explicitly rather than set up a threads system, and you therefore need some way to identify coroutines throughout their lifespan. The switch()/transfer()/resume() call keeps track of the current coroutine through a static pointer, and hence needs no 'from' parameter. There are other issues, such as how best to set up the routines so that they exit cleanly, whether the original context should be set up as a coroutine, and whether to support special transfers such as resume_caller() or resume_(). Comments? ------------------------- James Collier Internet(ish): james@cantuar.uucp Computer Science Dept., UUCP: {watmath,munnari,mcvax}!cantuar!james University of Canterbury, Spearnet/Janet: j.collier@nz.ac.canty Christchurch, New Zealand. Office: +64 3 482 009 x8356 Home: +64 3 554 025