Does anyone know of a Forth with traditional cooperative multitasking,
that I can run under Linux? Not too worried about other features, just
want to try benchmarking it against some other lightweight multitasking >schemes. Thanks.
See the library source of ciforth.
Note: If the purpose is to full use of cores, only pre-emptive
albert@cherry.(none) (albert) writes:
See the library source of ciforth.Thanks, I'll give that a try.
Note: If the purpose is to full use of cores, only pre-emptiveNo I don't care about that, I specifically want to benchmark Forth cooperative multitasking (single cpu) against an interesting C coroutine scheme that someone posted.
Wouldn't it be more accurate to compare Forth co-routines to the C
version? Aside from being cooperative, the traditional Forth systems
are a real context switch. Co-routines, at least in Forth, are just a
bit of return stack chicanery.
Forth multtasking usually doesn't involve a hardware context switch if
that's what you mean?
What I think of as a coroutine (and what the C
coroutine lib I mention does) is similar to what Forth's multitasker
does, minus the scheduler (but the user has to supply that).
I'm aware
of a Forth "coroutine swap" word that maybe just swaps the TOS with the
top of the return stack. Is that what you mean by return stack
chicanery?
This is the C library I was looking at, and the article has some
benchmarks comparing it to various other languages, so I wanted to
compare it with Forth:
http://www.cofault.com/2022/10/usched-stackswap-coroutines-neither.html
On Friday, October 14, 2022 at 12:20:59 PM UTC-4, Paul Rubin wrote:
Forth multtasking usually doesn't involve a hardware context switch if
that's what you mean?
I spin in circles with old machines so my knowledge is not current.
I am not familiar with what a hardware context switch means in
the "context" of an intel CPU these days or an ARM CPU.
Forth multtasking usually doesn't involve a hardware context switch if
On Friday, October 14, 2022 at 11:20:59 AM UTC-5, Paul Rubin wrote:
Forth multtasking usually doesn't involve a hardware context switch ifI went from working with an 8080 to a 32-bit mini that had 16 sets of
16 general-purpose registers. What luxury! A context switch was
hardware switching in the desired set of 16 registers.
The context switching was interesting but of little concern for me.
The project only had two tasks, one multi-user terminal task and one
message handling task. The latter was a state-machine that exchanged
messages with hundreds of z-80's and handled up to 8,000 concurrent processes. The state-machine, not multi-tasking, provided the
concurrency.
When I first got into Forth, I was very interested in adding
multi-tasking to my FigForth, which I did. I didn't have any need for
it, nothing hanging off my home computer, so I only had a dancing
stick figure, taking up valuable space, sharing the screen as I
worked. That was quickly put aside and my interest in multi-tasking
waned.
Whenever I get a urge to implement one again, I always get side-tracked thinking of other possibilities such as making use of the host's
background task to run additional Forths or other programs to function
in a more loosely coupled manner. I have a coproc setup for running
with Bash but again, don't have pressing need so don't do much with
it.
In a token-based system, Forth core + application program can be as small
as 1 k-plus for its byte-code image. Given a simple VM with all stacks and global variables in a packed structure, it is not difficult to switch between several running Forths in a round-robin fashion (through PAUSE) because
every Forth instance consists only of its double-set of image and global stack/variables pack, with all sharing the same single VM. No big deal.
I spin in circles with old machines so my knowledge is not current.
I am not familiar with what a hardware context switch means in
the "context" of an intel CPU these days or an ARM CPU.
(The machine I play with actually does have a single instruction
context switch via register windows in memory which I use for
my cooperative multi-tasker)
Of note: The old Forth systems in my experience didn't have a scheduler.
The primitives did their own scheduling with PAUSE.
...
Traditionally Forth used round robin
scheduling, but you could also imagine a Forth multitasker that let
tasks have separate priority levels.
"minf...@arcor.de" <minf...@arcor.de> writes:
In a token-based system, Forth core + application program can be as small as 1 k-plus for its byte-code image. Given a simple VM with all stacks and global variables in a packed structure, it is not difficult to switch betweenDo you mean no shared memory between the instances? Was there message passing? Was there any buffering for the mailboxes? What did you do
several running Forths in a round-robin fashion (through PAUSE) because every Forth instance consists only of its double-set of image and global stack/variables pack, with all sharing the same single VM. No big deal.
about stopping them from being overrun, or using too much memory
compared to the 1k or whatever?
"minf...@arcor.de" <minforth@arcor.de> writes:
In a token-based system, Forth core + application program can be as small
as 1 k-plus for its byte-code image. Given a simple VM with all stacks and >> global variables in a packed structure, it is not difficult to switch between
several running Forths in a round-robin fashion (through PAUSE) because
every Forth instance consists only of its double-set of image and global
stack/variables pack, with all sharing the same single VM. No big deal.
Do you mean no shared memory between the instances? Was there message >passing? Was there any buffering for the mailboxes? What did you do
about stopping them from being overrun, or using too much memory
compared to the 1k or whatever?
I usually think of a Forth multitasker as having separate D and R stacksYou are right about the setup. The task are pre-emptable,
per task, plus a user variable segment per task, plus a shared global
memory area. Simple memory race conditions are avoided because the
tasks aren't preemptable (they switch on PAUSE).
You still need
synchronization if you want longer duration transactions. Andrew Haley
(who we haven't heard from in a while) implemented software
transactional memory (STM) for a system like that a while back, but I
don't know what its constraints were.
Cool, can I ask what kind of machine?TMS9900 :-)
When the code in a task executes PAUSE, it transfers control to some
other code, that decides what task to run next. That other code is
what I mean by scheduler. Traditionally Forth used round robin
scheduling, but you could also imagine a Forth multitasker that let
tasks have separate priority levels.
The typical level of that control is pretty trivial.
The task is asleep and so skipped in the round-robin queue or awake
and it runs.
Brian Fox <bria...@brianfox.ca> writes:
The typical level of that control is pretty trivial.I remember reading that Polyforth stayed cpu busy even if no tasks were runnable. These days you would put the scheduler and cpu to sleep if
The task is asleep and so skipped in the round-robin queue or awake
and it runs.
there were no runnable tasks. It would sleep until there was a hardware interrupt, such as a timer tick.
Unix (idk about Linux) had "wait channels" (wchan, basically arbitrary integers, conventionally memory addresses) that processes could sleep
on. If you ran "wakeup(w)" then all processes sleeping on wait channel
w would awaken. I don't know how the kernel found those processes.
Early on, it may have scanned the whole proc table, since memory on the PDP-11 was scarce and the number or processes necessarily couldn't be
very large. These days I guess you'd want a fancier lookup structure.
ISTM that a Forth multitasker might also want something like that. The coroutine library that I linked to appears designed to handle millions
of tasks, but the typical MCU Forth app that I'm imagining might have
5-10 tasks that all run through the app's entire duration.
Yes if you put all the tasks to sleep in PolyForth there would still be CPU activity. It would be PAUSE running in an endless loop. :-)
Here is the file since you seem curious. https://github.com/bfox9900/CAMEL99-ITC/blob/master/LIB.ITC/MTASK99.FTH
Brian Fox <brian.fox@brianfox.ca> writes:
Yes if you put all the tasks to sleep in PolyForth there would still be CPU >> activity. It would be PAUSE running in an endless loop. :-)
I guess cpu's in that era didn't have low powered sleep modes.
Otherwise you'd just drop into one until an interrupt came.
Here is the file since you seem curious.
https://github.com/bfox9900/CAMEL99-ITC/blob/master/LIB.ITC/MTASK99.FTH
Thanks, I'll try to understand this. What did you do about task to task communication? In systems like Erlang, sometimes there are unbounded
queues, hopefully with some back pressure to prevent getting flooded.
That seems a bit extravagant for Forth. In Brad Rodriguez's example
there was a single mailbox cell per task, but that seems inadequate,
since you could deadlock easily.
Elizabeth describes the system Forth Inc uses here: https://groups.google.com/g/comp.lang.forth/c/88t12ePk_eg/m/NFKqe-Hh79EJ
It's likely discussed in the docs that come with SwiftX.
dxforth <dxforth@gmail.com> writes:
Elizabeth describes the system Forth Inc uses here:
https://groups.google.com/g/comp.lang.forth/c/88t12ePk_eg/m/NFKqe-Hh79EJ
It's likely discussed in the docs that come with SwiftX.
Thanks, this is a traditional low level lock. I was hoping for
something like mailboxes as a built-in feature, that allow tasks to communicate with each other by message passing. Brad Rodriguez's system
has that, but each task's mailbox is just a single cell, iirc.
I think that can lead to some problems. I will think about it more.
Brian Fox <bria...@brianfox.ca> writes:
Yes if you put all the tasks to sleep in PolyForth there would still be CPU activity. It would be PAUSE running in an endless loop. :-)I guess cpu's in that era didn't have low powered sleep modes.
Otherwise you'd just drop into one until an interrupt came.
Here is the file since you seem curious. https://github.com/bfox9900/CAMEL99-ITC/blob/master/LIB.ITC/MTASK99.FTHThanks, I'll try to understand this. What did you do about task to task communication? In systems like Erlang, sometimes there are unbounded
queues, hopefully with some back pressure to prevent getting flooded.
That seems a bit extravagant for Forth. In Brad Rodriguez's example
there was a single mailbox cell per task, but that seems inadequate,
since you could deadlock easily.
Thanks, this is a traditional low level lock. I was hoping for
something like mailboxes as a built-in feature, that allow tasks to communicate with each other by message passing. Brad Rodriguez's system
has that, but each task's mailbox is just a single cell, iirc.
I think that can lead to some problems. I will think about it more.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 34:47:57 |
Calls: | 6,707 |
Files: | 12,239 |
Messages: | 5,353,338 |