toma@tekgvs.TEK.COM (Tom Almy) (07/29/87)
In the recent deluge of postings, I seem to remember someone asking about multitasking/multiuser Forths. I have modified a copy of the public domain F83 (by Laxen and Perry) for multiuser (it is normally just multitasking). I will supply it (sources included, of course) to anyone who requests it. I did the modifications several years ago on the 8080 version 1.0, so anyone wanting multiuser on the 8086 version will have to examine the sources and make the appropriate modification to the 8086 version. I ran the program with three users on a Lobo MAX-80 (5 Mhz Z-80, 8" DSDD floppies, and 256k ram disk) with excellent performance. The program should work on an IBM PC if UNIDOS is used, with the only necessary mods being serial port access. Important details: The FORTH vocabulary "forks" so that each user additions to FORTH are private to his/her tasks. Other vocabularies existing before switching to multiuser are shared, allowing shared variables between users. Sufficient variables have been converted to user variables so that each user can edit separate screen files, and can have different terminal definitions. The editor has been modified for much more efficient display update (very important when running multiuser or over serial ports). A PolyForth "TYPIST" like task is provided. The typist can be considered as another user task which can receive character input from any user and sends all output to the printer. To use, type a line "TYPIST: <commands>". If the typist is busy, you will be told so, and you can wait or hit a key to abort the (queued) command. When the typist is ready to accept the command, your task resumes. If the typist encounters any error, the error will be reported back to your terminal! A multitasking demo is provided -- Tower of Hanoi using message passing among a dozen tasks rather than recursion. This demo can be executed by all users simultaneously! (A problem: FORGET needs to be modified so as to delete any forgotten tasks, currently it leaves them chained in and the system will soon crash after forgetting). (Totally irrelevent to this discussion) the words INSTANCES_OF and USERS_OF are provided which do entire vocabuary (or all vocabulary) searches for words which either use a given word or are instances of (i.e. CREATE DOES>) a given word. I got the idea for this from the Smalltalk browser. Reply to me if interested. I could try emailing it, or can USmail it if sent a Self Addressed Stamped Mailer and a floppy (IBM PC Format only!!). Tom Almy toma@tekgvs.TEK.COM {most hubs}!tektronix!tekgvs!toma
rat@circle.UUCP (08/14/87)
I would think that task-switching during NEXT would create too high of an overhead. Seems to me that switching during : or ; would be more reasonable. However, I would still prefer PAUSE and similar for more control. However, I would like to be able to have a multitasking Forth which can handle having more than one file open at a time; this is with a single-user operating system (namely Prodos, but MS-DOS or CP/M are also single-user similarly). How in tarnation would you keep track of the open files? The big problem is that I want two users to be able to write in the same file at the same time; so I need record-locking but dont know how to implement it. Any thoughts? By the way, I would say that there are SOME of us STILL using CP/M out here... too bad the F83 isnt Z80 code though. Better yet, somebody otta write a decent F83 for ZCPR3. "Curiouser and curiouser," said Alice. -- ::: David Douthitt ::: Madison, Wisc ::: uucp mail: ...!uwvax!geowhiz!uwspan!hobbes!circle!rat fidonet mail: 121/1
toma@tekgvs.TEK.COM (Tom Almy) (08/18/87)
In article <9.2122EF36@circle.UUCP> rat@circle.UUCP (David Douthitt) writes: >I would think that task-switching during NEXT would create too high of an >overhead. Seems to me that switching during : or ; would be more >reasonable. However, I would still prefer PAUSE and similar for more >control. The scheme used in the Multi User Forth that I posted last week changes on "PAUSE". (This is F83) > >However, I would like to be able to have a multitasking Forth which can >handle having more than one file open at a time; this is with a >single-user operating system (namely Prodos, but MS-DOS or CP/M are also >single-user similarly). How in tarnation would you keep track of the open >files? Each task has a file number as one of its user variables. So each user can do a "1 LIST" simultaneously and yet each may be displaying a different screen! The block buffers' headers have both the block number and file number and the LRU assignment algorith works over all users-- the buffer pool is shared rather than assigned. For smoothest operation there should be at least as many buffers as users, but it is not required (ever see disk thrashing?). > >The big problem is that I want two users to be able to write in the same >file at the same time; so I need record-locking but dont know how to >implement it. Any thoughts? Yes, use semaphores on the block buffers, and add a new word, RELEASE, to signify release of the block buffer. Change the block allocation algorithm to skip locked block buffers. Of course, if the task can get all of its work done without doing anything that causes a PAUSE, then you are home free without going to this trouble. USER VARIABLE curblk : LOCKINGBLOCK DUP curblk ! BLOCK ( the old code ) DUP { offset to header semaphore location } SEMA ; : RELEASE curblk @ BLOCK { offset to header semaphore location } PHORE ; Where SEMA and PHORE are implemented as: : SEMA ( locationToLock -- ) BEGIN DUP @ WHILE PAUSE REPEAT ON ; : PHORE ( locationToRelease -- ) OFF ; >By the way, I would say that there are SOME of us STILL using CP/M out >here... too bad the F83 isnt Z80 code though. Better yet, somebody otta >write a decent F83 for ZCPR3. I recently stopped using a Z80, but the F83 code can be Z80ized. The inner interpreter address should be put in IX (or IY) and JMP [IX] used to get to it. The multiply and divide primitives can be rewritten to get MUCH better performance, and of course CMOVE can be improved. The improvement in speed won't be anything to write home about, though. The best bet for speed improvement is to change the implementation to direct threaded code. Tom Almy Tektronix, Inc. toma@tekgvs.TEK.COM (Standard disclaimer applies)
willner@cfa.harvard.EDU (Steve Willner) (08/19/87)
> In article <9.2122EF36@circle.UUCP> rat@circle.UUCP (David Douthitt) writes: > >I would think that task-switching during NEXT would create too high of an > >overhead. Seems to me that switching during : or ; would be more > >reasonable. However, I would still prefer PAUSE and similar for more > >control. > In article <2573@tekgvs.TEK.COM>, toma@tekgvs.TEK.COM (Tom Almy) writes: > The scheme used in the Multi User Forth that I posted last week changes on > "PAUSE". (This is F83) Changing only on PAUSE certainly makes it easier to write code, but it is far too restrictive in an instrument control application where a task might be time-critical. The alternative is to _patch_ either ; or NEXT. Most of the time the word just executes an extra no-op, but when an interrupt schedules a new task, the interrupt service routine changes the no-op to be a jump to the priority-checking word (PAUSE in many systems), which patches the no-op back in and then gives control to the highest priority process that is ready to run. Of course this scheme isn't needed if _all_ the time-critical processing can be done within the interrupt service routine, but that condition greatly restricts the amount of processing that can be done. The price one pays for the extra capability, of course, is that code must be carefully written to be interruptible; semaphores must be used frequently (and in the right order!), global variables and pointers must be maintained in a fully consistent manner, etc. The benefit is that a real-time process can proceed unaffected by user activities. -- Steve Willner Phone 617-495-7123 Bitnet: willner@cfa1 60 Garden St. FTS: 830-7123 UUCP: willner@cfa Cambridge, MA 02138 USA Telex: 921428 satellite cam
andrew@teletron.UUCP (Andrew Scott) (08/20/87)
In article <9.2122EF36@circle.UUCP>, rat@circle.UUCP (David Douthitt) writes: > I would think that task-switching during NEXT would create too high of an > overhead. Seems to me that switching during : or ; would be more > reasonable. However, I would still prefer PAUSE and similar for more > control. There must be some misunderstanding of my explanation of task switching during NEXT which I described in a previous posting. We don't switch at every NEXT (which would be incredibly inefficient), only when we want to. Normal PAUSE is still used to relenquish control to another process, however we can patch NEXT to perform a PAUSEish task switch when special situations arise. For example, should some active task fail to relenquish control through PAUSE for any reason, a clock interrupt could limit a time slice to some maximum value and force a PAUSE. Also, this mechanism could be used to synchronize some task with an external interrupt. NEXT is a more convenient place to perform the task switch than : or ; because it will be executed much sooner. If NEXT is implemented as an indirect call (e.g. jsr (a0), where the a0 register holds the address to NEXT), the interrupt code merely has to patch the register with the task switching routine's address. This code can restore the register to point to NEXT when it's finished the task switch. As for concerns (expressed by some others) that this technique would be impractical when dealing with disk buffers etc., I never claimed that this was a good technique in a multi-USER environment, but a multi-TASKING environment. There is a difference! FORTH is great for real-time systems, and working with interrupts is a must. This technique is an easy way to interface processor interrupts with FORTH tasks. Andrew
tenney@well.UUCP (Glenn S. Tenney) (08/21/87)
I believe that "you" must understand that there is a difference between multitasking and interrupts. A hi speed time-critical routine really should be an interrupt routine written in hi level or assembler. By having the context switch occur at PAUSE (which, btw, is implied at any I/O type word such as BLOCK) a whole slew of problems disappear. It then becomes the programmer's responsibility to put PAUSE in lot's of extra places when you think you're going to be doing something cpu intensive AND when you know it's safe. It's also your job to be sure things are safe before ANY I/O word. All in all, multitasking with PAUSE is much nicer, but it is not what most CS people are used to since there is no time slicing. There are MANY time critical applications running tons of software on lots of terminals etc. using just such a multitasker. Btw, such a multitasker can be written entirely in hi level. I did it to test things out about 4 years ago (or was it 5?). Glenn Tenney