home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / oberon / system / coroutines.mod (.txt) < prev    next >
Oberon Text  |  1977-12-31  |  5KB  |  100 lines

  1. Syntax10.Scn.Fnt
  2. Syntax10b.Scn.Fnt
  3. Syntax10i.Scn.Fnt
  4. MODULE Coroutines; (* jr/14jul94, updated cn/20jan96 *)
  5.     This module implements coroutines as known from Modula-2. Although it is machine
  6.     dependent, it was programed in a way, which should make it adaptable to
  7.     differen platforms by just a few changes in constant definitions. See the section marked CHANGE.
  8.     There is one restriction which procedures, that you use to create processe in NEWPROCESS, 
  9.     have to obey. If they allocate space on the heap they must assure, that some global variable
  10.     points to this space during the entiere time this space is needed. If you don't follow this rule,
  11.     the garbage collector may reclaim the space, even though you still have some local
  12.     variables pointing to it.
  13.     On the Macintosh there is an additional restriction. The storage are used as stack for
  14.     a process has itself to be on the stack. Otherwise some check code will complain 
  15.     about illegal stack pointer values.
  16.     This module was used on the different platforms at different stages of its development.
  17.     It showed some strange efects on the Oberon system, which we suspected as
  18.     a problem with garbage collection. I've fixed it now for the SGI Oberon. As I don't have
  19.     access to the other platforms, I don't really know if this module is still usable on them.
  20.     In theory, this is expected:
  21.     Macintosh:
  22.         The Mac Oberon does never perform garbage collection while outside of the
  23.         Oberon.Loop and therefore does not have to inspect the stack when deciding
  24.         which memory space is to be marked as in use. Thus the disabling of the garbage
  25.         collector is not needed, and the statements using Kernel.GCenabled can be 
  26.         removed, maybe even have to be removed, as Kernel doesn't export GCenabled.
  27.     SGI,HP:
  28.         The garbage collector may be called when executing a command. It then scans
  29.         the stack to see, if there are pointer pointing to some heap ares, so it can mark
  30.         this area as in use. When executing a process, the stack pointer points to the
  31.         private stack of this process, and no more to the usual one. And if it points to the
  32.         wrong side of the stack, the garbage collector will not inspect the stack at all.
  33.         Therefore we disable the garbage collector when we are not in the main
  34.         execution thread, and reenable it, when we return to the main thread.
  35.         In case your command traps, while executing a coroutine, the garbage collector
  36.         remains disabled, and Coroutines continues to believe, that you are not in the
  37.         main thread. You should then use the Coroutines.Reset command to reenable the
  38.         garbage collector, and reset Coroutines.
  39.     Amiga:
  40.         The same as said for SGI and HP applies to the Amiga. But I don't know, if the
  41.         Amiga Kernel does export an GCenabled variable, as the Unix Kernel does.
  42.         If it doesn't, you have to wait for a future relase supporting it.
  43.     Later it was discovered, that the problem was cause by writing to the Log, while
  44.     executing code called from the handler in the SortBasic module.
  45.     Apart from the above mentioned problems, their might be others. So please be
  46.     carefull when using commands which use Coroutines. Don't do this, while you
  47.     have viewers with unsaved files open etc.
  48.     If you can identify problems with Coroutines, please send Mail to
  49.         claudio@dial.eunet.ch    or    joerg.straube@alcatel.ch
  50.     so we can improve this module.
  51.     The modifications for AXP were provided by
  52.         Guenter Dotzel <100023.2527@compuserve.com>
  53.     Thank you very much!
  54. IMPORT SYSTEM,Kernel;
  55. CONST    (* CHANGE *)
  56.     (* Amiga/Mac: *) MP=14; SP=15; negativeGrow=TRUE; align=4;
  57.     (* HP: MP=30; SP=30; negativeGrow=FALSE; align=4; *)
  58.     (* SGI: MP=29; SP=29; negativeGrow=TRUE; align=4; *)
  59.     (* AXP: MP=29; SP=30; negativeGrow=TRUE; align=16; TYPE LONGINT=SYSTEM.SIGNED_64; *)
  60.     PROC*=PROCEDURE;
  61.     PROCESS*=RECORD
  62.         p:PROC;
  63.         stackForP:LONGINT;
  64.         MP:LONGINT
  65.     END;
  66.     mainMP:LONGINT;
  67.     proc:PROC;
  68. PROCEDURE NEWPROCESS*(p:PROC; VAR stack:ARRAY OF SYSTEM.BYTE; VAR new:PROCESS);
  69.     BEGIN
  70.         new.p:=p;
  71.         IF negativeGrow THEN
  72.             new.stackForP:=((SYSTEM.ADR(stack)+LEN(stack)) DIV align)*align; (* respect alignment requirments *)
  73.         ELSE
  74.             new.stackForP:=((SYSTEM.ADR(stack)+3) DIV align)*align; (* long word align *)
  75.         END;
  76.         new.MP:=0;
  77.     END NEWPROCESS;
  78. PROCEDURE TRANSFER*(VAR from,to:PROCESS);
  79.     BEGIN
  80.         SYSTEM.GETREG(MP,from.MP);
  81.         IF mainMP=0 THEN Kernel.GCenabled:=FALSE; mainMP:=from.MP; END;
  82.         IF to.MP#0 THEN
  83.             SYSTEM.PUTREG(MP,to.MP)
  84.         ELSE
  85.             proc:=to.p; (* copy into global variable needed when MP=SP *)
  86.             SYSTEM.PUTREG(SP,to.stackForP);
  87.             IF to.MP=mainMP THEN Kernel.GCenabled:=TRUE; mainMP:=0; END;
  88.             proc;
  89.             HALT(100);
  90.         END;
  91.     END TRANSFER;
  92. PROCEDURE Reset*;
  93. BEGIN
  94.     mainMP:=0;
  95.     Kernel.GCenabled:=TRUE;
  96. END Reset;
  97. BEGIN
  98.     Reset;
  99. END Coroutines.
  100.