Mercurial > repo
diff interps/c-intercal/pit/continuation.i @ 996:859f9b4339e6
<Gregor> tar xf egobot.tar.xz
author | HackBot |
---|---|
date | Sun, 09 Dec 2012 19:30:08 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interps/c-intercal/pit/continuation.i Sun Dec 09 19:30:08 2012 +0000 @@ -0,0 +1,298 @@ + PLEASE NOTE + +Copyright (C) 2008 Alex Smith + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + PLEASE NOTE Creating the continuation statements + DO CREATE (8200) GET CONTINUATION IN .1 GETTING .2 + DO CREATE (8200) GET CONTINUATION IN ,1 SUB #1 GETTING .2 + DO CREATE (8200) GET CONTINUATION IN .1 GETTING ,2 SUB #2 + DO CREATE (8200) GET CONTINUATION IN ,1 SUB #1 GETTING ,2 SUB #2 + DO CREATE (8210) CONTINUE WITH .1 SENDING .2 + DO CREATE (8210) CONTINUE WITH .1 SENDING .2~#2 + DO CREATE (8210) CONTINUE WITH .1 SENDING ,2 SUB #2 + DO CREATE (8210) CONTINUE WITH .1~#1 SENDING .2 + DO CREATE (8210) CONTINUE WITH .1~#1 SENDING .2~#2 + DO CREATE (8210) CONTINUE WITH .1~#1 SENDING ,2 SUB #2 + DO CREATE (8210) CONTINUE WITH ,1 SUB #1 SENDING .2 + DO CREATE (8210) CONTINUE WITH ,1 SUB #1 SENDING .2~#2 + DO CREATE (8210) CONTINUE WITH ,1 SUB #1 SENDING ,2 SUB #2 + DO CREATE (8205) KILL ALL THREADS + PLEASE NOTE Initialising the counting tracker thread + PLEASE DO .1 <- #0 +(8201) DO NOTHING + + PLEASE NOTE Definitions of the continuation statements +(8200) DO STASH .1 + PLEASE DO (8280) NEXT + PLEASE DO (1020) NEXT + PLEASE DO (8270) NEXT + PLEASE NOTE It's possible for .1 to equal :1601, so we + have to be careful about operating on the + arguments while stashed. So we use the + temporary global variable .8200. + DO .8200 <- .1 + DO RETRIEVE .1 + DO :1601 <- .8200 + DO (8202) NEXT + DO RESUME #1 +(8202) PLEASE NOTE Fork threads, one dormant, one alive + DO COME FROM (8202) + DO RESUME #1 +(8213) DO RESUME '?".1~.1"$#2'~#3 +(8212) DO (8213) NEXT + DO RETRIEVE .1 PLEASE NOTE Restoring .1's stash + DO COME FROM (8202) + PLEASE FORGET #1 +(8211) DO COME FROM (8211) + PLEASE NOTE We count how many threads are in 8275 using the + abstention count of 8214 and block until they're + all done. + PLEASE DO ABSTAIN #1 FROM (8214) + DO STASH .1 + DO (8275) NEXT + DO REINSTATE (8214) + DO COME FROM (8215) +(8216) DO NOTHING +(8215) DO NOTHING +(8214) DO COME FROM (8216) + PLEASE DO REINSTATE (8211) + PLEASE NOTE If .8200 matches .1, we activate. This uses + a NEXT/NEXT/RESUME-style check because it's + done on multiple threads at once and because + a computed COME FROM would slow down the + program even further. + DO .1 <- '?.8200$.1'~'#0$#65535' + DO (8212) NEXT + PLEASE NOTE that if this point is reached, we've reached + the point where unfreezing the thread is + necessary. First receive one datum from + 8277 so we can send something back in the + continuation (this involves signaling using + 8217), then the other thread kills itself and + we make a new continuation numbered the same + as the old one, and continue by doubleresuming + (so that an unfreeze can be told apart from an + initial call). As this is a CREATEd statement, + it's important to unstash :1601 and :1602 + ourselves when doubleresuming, as the runtime + only does it correctly on a single resume. + PLEASE DO ABSTAIN FROM (8217) + DO (8260) NEXT + DO (8276) NEXT + DO .8201 <- .1 + DO RETRIEVE .1 PLEASE NOTE Restoring .1's stash + DO (8202) NEXT PLEASE NOTE .8200 is still correct! + DO :1602 <- .8201 + PLEASE DO :1601 <- .8200 + DO RETRIEVE :1601 + DO RETRIEVE :1602 + DO RESUME #2 + +(8210) PLEASE NOTE Here we use the timing guarantees. Once we + ABSTAIN FROM 8211, all the threads looping + there become unblocked simultaneously, so + all of them abstain 8214 (which is 2-3 cycles) + before any of them REINSTATES 8211 (which is + way lower down, after the call to 8275), so + we can guarantee that all the threads get a + chance to check to see if they match. + DO .8210 <- .1 + PLEASE DO .1 <- :1601 + DO (8250) NEXT + DO (8270) NEXT + PLEASE DO ABSTAIN FROM (8211) +(8217) DO COME FROM (8217) AGAIN + PLEASE NOTE This double assignment is actually correct, + because :1602 is overloaded. + PLEASE DO .1 <- .8210 + DO .1 <- :1602 + PLEASE DO (8277) NEXT + PLEASE GIVE UP + + PLEASE NOTE A communications channel thread. + This acts like one 16-bit variable, where + 8250 stashes the variable + 8260 retrieves the variable + 8270 copies it from .1 + and 8280 copies it into .1 + + 8275 is a mutex version of 8280 so that multiple + threads can try to view .1 at once and only + one will get it at a time. + 8299 is a spinlock that traps until the current + operation is completed, which is needed as + part of the implementation of this, and then + double-resumes + +(8299) DO COME FROM (8299) AGAIN + PLEASE DO RESUME #2 + +(8250) DO REINSTATE (8251) + PLEASE DO (8299) NEXT + +(8260) DO REINSTATE (8261) + PLEASE DO (8299) NEXT + +(8270) DO REINSTATE (8271) + DO (8277) NEXT + PLEASE DO (8299) NEXT + +(8280) DO REINSTATE (8281) + DO (8276) NEXT + PLEASE DO (8299) NEXT + +(8275) DO COME FROM (8274) +(8274) DO (8273) NEXT ONCE +(8273) DO (8280) NEXT + PLEASE DO REINSTATE (8274) + DO RESUME #2 + + PLEASE NOTE main part of the communications channel thread + DO COME FROM (8201) + PLEASE DO COME FROM (8259) +(8252) DO NOTHING +(8262) DO NOTHING +(8272) DO NOTHING +(8282) DO NOTHING +(8259) PLEASE DO NOTHING + +(8251) DON'T NEXT FROM (8252) AGAIN + DO STASH .1 + PLEASE DO ABSTAIN FROM (8299) + DO RESUME #1 + +(8261) DON'T NEXT FROM (8262) AGAIN + DO RETRIEVE .1 + DO ABSTAIN FROM (8299) + DO RESUME #1 + +(8271) DON'T NEXT FROM (8272) AGAIN + DO (8276) NEXT + DO ABSTAIN FROM (8299) + PLEASE DO RESUME #1 + +(8281) DON'T NEXT FROM (8282) AGAIN + DO (8277) NEXT + DO ABSTAIN FROM (8299) + PLEASE DO RESUME #1 + + + PLEASE NOTE 16-bit communications channel + 8276 will block until data is sent + 8277 will send the data + data transferred from .1 to .1 + +(8276) DO COME FROM (8276) AGAIN + DO .1 <- #65535 +(8283) DO .1 <- '?.1$# 1'~'#0$#65535' AGAIN +(8284) DO .1 <- '?.1$# 2'~'#0$#65535' AGAIN +(8285) DO .1 <- '?.1$# 4'~'#0$#65535' AGAIN +(8286) DO .1 <- '?.1$# 8'~'#0$#65535' AGAIN +(8287) DO .1 <- '?.1$# 16'~'#0$#65535' AGAIN +(8288) DO .1 <- '?.1$# 32'~'#0$#65535' AGAIN +(8289) DO .1 <- '?.1$# 64'~'#0$#65535' AGAIN +(8290) DO .1 <- '?.1$# 128'~'#0$#65535' AGAIN +(8291) DO .1 <- '?.1$# 256'~'#0$#65535' AGAIN +(8292) DO .1 <- '?.1$# 512'~'#0$#65535' AGAIN +(8293) DO .1 <- '?.1$# 1024'~'#0$#65535' AGAIN +(8294) DO .1 <- '?.1$# 2048'~'#0$#65535' AGAIN +(8295) DO .1 <- '?.1$# 4096'~'#0$#65535' AGAIN +(8296) DO .1 <- '?.1$# 8192'~'#0$#65535' AGAIN +(8297) DO .1 <- '?.1$#16384'~'#0$#65535' AGAIN +(8298) DO .1 <- '?.1$#32768'~'#0$#65535' AGAIN + DO ABSTAIN FROM (8278) + DO RESUME #1 + +(8277) DO ABSTAIN .1~# 1 FROM (8283) + DO ABSTAIN .1~# 2 FROM (8284) + DO ABSTAIN .1~# 4 FROM (8285) + DO ABSTAIN .1~# 8 FROM (8286) + DO ABSTAIN .1~# 16 FROM (8287) + DO ABSTAIN .1~# 32 FROM (8288) + DO ABSTAIN .1~# 64 FROM (8289) + DO ABSTAIN .1~# 128 FROM (8290) + DO ABSTAIN .1~# 256 FROM (8291) + DO ABSTAIN .1~# 512 FROM (8292) + DO ABSTAIN .1~# 1024 FROM (8293) + DO ABSTAIN .1~# 2048 FROM (8294) + DO ABSTAIN .1~# 4096 FROM (8295) + DO ABSTAIN .1~# 8192 FROM (8296) + DO ABSTAIN .1~#16384 FROM (8297) + DO ABSTAIN .1~#32768 FROM (8298) + DO ABSTAIN FROM (8276) +(8278) PLEASE DO COME FROM (8278) AGAIN + PLEASE DO RESUME #1 + + PLEASE NOTE Code for killing all threads. This + is achieved by hoping none of them are + in syslib (which is after the end + of the program), and abstaining from + all flow control operations in the + program, all operations that hold up + execution, and all operations that + could error. Unfortunately, this + can be affected by ONCE/AGAIN, so + each thread will twice more repeat + the abstention in the hope of catching + other threads as it comes past to quit. + Not perfect, but hopefully good enough. + (Of course, a simple E000 would be + better at this job, but it's an error + and non-erroring solutions are better.) + PLEASE DO REINSTATE (8205) AGAIN + PLEASE DO REINSTATE (8206) AGAIN +(8205) PLEASE DO ABSTAIN FROM ABSTAINING + REINSTATING + + CALCULATING + NEXTING + COMING FROM + RESUMING + + FORGETTING + STASHING + RETRIEVING + WRITING IN + + READING OUT + COMMENT AGAIN + DON'T DO ANYTHING FOR A BIT + PLEASE NOTE THAT THIS IS MORE TIME WASTING +(8206) PLEASE DO ABSTAIN FROM ABSTAINING + REINSTATING + + CALCULATING + NEXTING + COMING FROM + RESUMING + + FORGETTING + STASHING + RETRIEVING + WRITING IN + + READING OUT + COMMENT AGAIN + PLEASE GIVE UP + + PLEASE NOTE The main program. + DO COME FROM (8201) + DO .2 <- #0 + DO (8) NEXT +(9) DO GET CONTINUATION IN .1 GETTING .2 + DO (10) NEXT + DO (7) NEXT +(8) DO (9) NEXT +(7) DO FORGET #1 + PLEASE DO READ OUT .2 + DO CONTINUE WITH .1 SENDING #3 ONCE + DO CONTINUE WITH .1 SENDING #4 ONCE + DO CONTINUE WITH .1 SENDING #5 ONCE + DO CONTINUE WITH .1 SENDING #6 ONCE + DO CONTINUE WITH .1 SENDING #7 ONCE + DO .2 <- .1 ONCE + DO (11) NEXT +(12) DO GET CONTINUATION IN .3 GETTING .2 + DO READ OUT #31 + .1 + .2 + .3 + DO CONTINUE WITH .3 SENDING .2 +(11) DO (12) NEXT + PLEASE DO READ OUT #30 + .1 + .2 + .3 + PLEASE DO CONTINUE WITH .2 SENDING .3 + PLEASE KILL ALL THREADS + +(10) DO .2 <- #1 + DO READ OUT #10 + DO CONTINUE WITH .1 SENDING #2 + DO RESUME #1