Discussion:
PAD and preemptive multi-tasking
Add Reply
Anton Ertl
2024-12-20 10:10:31 UTC
Reply
Permalink
Bernd Paysan have been wondering what to do about PAD in the presence
of preemptive multitasking (but not multi-user) as implemented in
Gforth.

We see two possible scenarios:

If PAD is used only directly by the user for interactive work, only
one PAD is needed.

OTOH, if PAD is used as temporary storage in words that may be called
by any task, PAD needs to be part of the per-task (aka USER) data.

My understanding is that classical multi-tasking Forth systems
(polyForth, I guess) were also multi-user and had one dictionary per
task, so they also had one dictionary pointer and therefore one PAD
per task, but I have not worked with any of them and the descriptions
I have read have been very sketchy, so this could be wrong.

In any case, the question is how PAD is used by current programs that
might be run on Gforth.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: https://forth-standard.org/
EuroForth 2024: https://euro.theforth.net
a***@spenarnc.xs4all.nl
2024-12-20 12:00:30 UTC
Reply
Permalink
Post by Anton Ertl
Bernd Paysan have been wondering what to do about PAD in the presence
of preemptive multitasking (but not multi-user) as implemented in
Gforth.
If PAD is used only directly by the user for interactive work, only
one PAD is needed.
OTOH, if PAD is used as temporary storage in words that may be called
by any task, PAD needs to be part of the per-task (aka USER) data.
My understanding is that classical multi-tasking Forth systems
(polyForth, I guess) were also multi-user and had one dictionary per
task, so they also had one dictionary pointer and therefore one PAD
per task, but I have not worked with any of them and the descriptions
I have read have been very sketchy, so this could be wrong.
This model is followed by ciforth.
Note that ciforth manages its own memory, and it is in one segment;
it can be huge if need be, hundreds of Gbyte.
Three parts: forth, dictionary space , and stacks and buffers.
[ In Fig Forth fashion the dictionary could be huge growing up and
the same area could be used by the data stack growing down,
accommodating some weird Euler problems.]
In multi tasking: a new dictionary space and s&b is carved out
from the mother dictionary space, multiple times if need be.
The forth area is common, however, you can defined compiled words
in your own dictionary space.
But now you have to decide on a restricted dictionary space,
[it can be large, Gbytes.]
This accommodates pre-emptive and cooperating tasks alike.
Child task area's can be forgotten as you long as you exit pre-emptive
tasks.

A SAVE-SYSTEM stores all the space reserved for child task area's,
so including the empty dictionary spaces.
A single task needs to save only the first part (forth), so this is
exponentially smaller, the dictionary and s&b is not saved.

User variable and transient areas are independant and pose no problem.
There is no reason real "preemptive" multitasking couldn't accommodate
multiple users, it also makes no sense.

This is so simple because the dictionary model is a single linked list
per wordlist. So the child tasks can link to this. This happens
automagically by cloning user variables like CONTEXT and CURRENT.
Post by Anton Ertl
In any case, the question is how PAD is used by current programs that
might be run on Gforth.
- anton
Groetjes Albert
--
Temu exploits Christians: (Disclaimer, only 10 apostles)
Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
And Gifts For Friends Family And Colleagues.
Paul Rubin
2024-12-20 21:17:54 UTC
Reply
Permalink
Post by Anton Ertl
In any case, the question is how PAD is used by current programs that
might be run on Gforth.
I thought the standard required PAD to be usable as random scratch
memory. So I'd expect Gforth to allocate one for each task. Gforth
systems aren't likely to suffer memory shortages from doing that. It
would be more of an issue for Polyforth.
Anton Ertl
2024-12-21 11:44:22 UTC
Reply
Permalink
Post by Paul Rubin
Post by Anton Ertl
In any case, the question is how PAD is used by current programs that
might be run on Gforth.
I thought the standard required PAD to be usable as random scratch
memory.
The standard does not specify multi-tasking.
Post by Paul Rubin
So I'd expect Gforth to allocate one for each task.
My question is: How have you used PAD?
Post by Paul Rubin
Gforth
systems aren't likely to suffer memory shortages from doing that.
Depends on the number of tasks. If PAD is not used in a way that
requires one PAD per task, it's better not to implement that.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: https://forth-standard.org/
EuroForth 2024: https://euro.theforth.net
dxf
2024-12-20 23:49:48 UTC
Reply
Permalink
Post by Anton Ertl
Bernd Paysan have been wondering what to do about PAD in the presence
of preemptive multitasking (but not multi-user) as implemented in
Gforth.
You may need to explain 'preemptive' and its relevance here.
Post by Anton Ertl
If PAD is used only directly by the user for interactive work, only
one PAD is needed.
OTOH, if PAD is used as temporary storage in words that may be called
by any task, PAD needs to be part of the per-task (aka USER) data.
My understanding is that classical multi-tasking Forth systems
(polyForth, I guess) were also multi-user and had one dictionary per
task, so they also had one dictionary pointer and therefore one PAD
per task, but I have not worked with any of them and the descriptions
I have read have been very sketchy, so this could be wrong.
Based on a part disassembly the value of HERE (used as DP) was taken
from the user area and PAD was 34 bytes above that value.
Post by Anton Ertl
In any case, the question is how PAD is used by current programs that
might be run on Gforth.
- anton
Anton Ertl
2024-12-21 11:26:24 UTC
Reply
Permalink
Post by dxf
Post by Anton Ertl
Bernd Paysan have been wondering what to do about PAD in the presence
of preemptive multitasking (but not multi-user) as implemented in
Gforth.
You may need to explain 'preemptive' and its relevance here.
"Preemptive multi-tasking" means that a task switch can happen at any
time, not just at PAUSE or when invoking I/O words as with cooperative
multitasking in traditional Forth. What we have in Gforth is actually
that the tasks can run in parallel on several CPU cores, but the
effects on software are similar to preemptive multi-tasking (there's
the problem of weaker memory ordering (than sequential consistency),
but that's only an issue when you want to communicate through shared
memory).

The relevance is that with cooperative multi-tasking a possible usage
pattern of PAD would be to use it between two PAUSEs, but not across
PAUSE etc. That usage would be compatible with having only one PAD.
With preemptive multi-tasking (and parallel processing) one would need
to use a mutual exclusion construct around such usages (and existing
Forth code using PAD certainly does not have that).

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: https://forth-standard.org/
EuroForth 2024: https://euro.theforth.net
a***@spenarnc.xs4all.nl
2024-12-21 18:05:39 UTC
Reply
Permalink
In article <***@mips.complang.tuwien.ac.at>,
Anton Ertl <***@mips.complang.tuwien.ac.at> wrote:
<SNIP>
Post by Anton Ertl
The relevance is that with cooperative multi-tasking a possible usage
pattern of PAD would be to use it between two PAUSEs, but not across
PAUSE etc. That usage would be compatible with having only one PAD.
With preemptive multi-tasking (and parallel processing) one would need
to use a mutual exclusion construct around such usages (and existing
Forth code using PAD certainly does not have that).
I have looked into that for ciforth and that is not the case.
By duplicating the dictionary the PAD is automatically changed
because task have separate set of user variables, notably HERE.

Thinking of this ...
If the parallel forth's are running in separate cores, and
compile at the same time, the buffer used by the WANT mechanism can
get conflicting uses.
So I originally used PAD and changed that to a dedicated buffer,
but it is better to change it back. This saves 4 WOC.

You cannot use PAD to collect information during compilation,
but that is an insanely bad idea.
Post by Anton Ertl
- anton
--
Temu exploits Christians: (Disclaimer, only 10 apostles)
Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
And Gifts For Friends Family And Colleagues.
josv
2024-12-21 13:28:43 UTC
Reply
Permalink
Post by Anton Ertl
Bernd Paysan have been wondering what to do about PAD in the presence
of preemptive multitasking (but not multi-user) as implemented in
Gforth.
If PAD is used only directly by the user for interactive work, only
one PAD is needed.
OTOH, if PAD is used as temporary storage in words that may be called
by any task, PAD needs to be part of the per-task (aka USER) data.
My understanding is that classical multi-tasking Forth systems
(polyForth, I guess) were also multi-user and had one dictionary per
task, so they also had one dictionary pointer and therefore one PAD
per task, but I have not worked with any of them and the descriptions
I have read have been very sketchy, so this could be wrong.
In any case, the question is how PAD is used by current programs that
might be run on Gforth.
- anton
I use upad instead:
maxcounted 1+ newuser upad

Jos

--
a***@spenarnc.xs4all.nl
2024-12-21 18:11:10 UTC
Reply
Permalink
In article <***@www.novabbs.com>,
josv <***@planet.nl> wrote:

<Discussion of the use of PAD in multi tasking>
Post by josv
maxcounted 1+ newuser upad
I understand that you allocate a pad in the user area.
That can be safe, but it must be part of the Forth itself
before compilation. Otherwise you prevent a compiled program
to allocate any user variables.
Post by josv
Jos
Groetjes Albert
--
Temu exploits Christians: (Disclaimer, only 10 apostles)
Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
And Gifts For Friends Family And Colleagues.
FFmike
2024-12-21 15:17:32 UTC
Reply
Permalink
In FlashForth I had a PAD for each task in the end of the user area.
The default size was 0 in order to not waste memory in small MCUs.
The smallest MCU had just 300 bytes of free RAM.
The idea was to ALLOT the size of PAD that you want to have before
allotting any other ram for a task.

This was confusing for most users so now there is only one global PAD.
I barely use PAD for anything, just for some interactive testing.

FlashForth's code segment is in flash, not in ram, so there is no
coordination needed between code and data allocations.

-- Mikael
Ruvim
2025-01-28 22:50:34 UTC
Reply
Permalink
Post by Anton Ertl
Bernd Paysan have been wondering what to do about PAD in the presence
of preemptive multitasking (but not multi-user) as implemented in
Gforth.
If PAD is used only directly by the user for interactive work, only
one PAD is needed.
OTOH, if PAD is used as temporary storage in words that may be called
by any task, PAD needs to be part of the per-task (aka USER) data.
[...]
Post by Anton Ertl
In any case, the question is how PAD is used by current programs that
might be run on Gforth.
I don't use PAD in multitasking/multithreaded applications, or even in
single-tasking applications. But only in interactive work, or for some
tests in the file loading time.

In SP-Forth/4, PAD is located in the user-area (per-task). But I don't
know examples of using it in different thread in parallel.


--
Ruvim

Loading...