[futurebasic] Re: [FB] FB^3 Threading Puzzle (continuing saga)

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : September 1999 : Group Archive : Group : All Groups

From: Robert Purves <robert.purves@...>
Date: Wed, 29 Sep 1999 21:30:37 +1200
The story so far
---------------
Steven is deep in doo-doo. He is trying to get his program to co-operate
with the MacOS (specifically the Thread Manager). He makes a call to the OS
to provide it with various information, most importantly the whereabouts of
an FB function named FN ThProc(tmp&). He wants the OS later to make
repeated calls back to this function. He believes that everything is right,
except that the call-back crashes as soon as it gets to the FB function.

Now, some clever Apple engineers addressed a problem here. Parts of the OS
are 68K and parts are PPC native. A user's program may be either 68K or
PPC. To solve the difficulties of switching from one mode to the other, the
MixedModeBoys wrote a clever Manager that does the mode-switch (if
required) automatically, provided everybody agrees _not_ to call each
others' code directly, but via a special data structure known as a UPP.
FB^3 knows these rules, and can make a UPP. That sounds great, and 99% of
OS call-backs will be handled correctly by the rules.

Robert, meanwhile, having a superficial knowledge of the Mixed Mode Manager
and the internal structure of a UPP, made several confident assertions on
the nature of the problem, immediately exposed as "veridically challenged",
if not outright fabrications. The most recent of these, relating to what FB
statement creates a UPP, was:-

>Clarification 2: It's not ENTERPROC. ENTERPROC/EXITPROC serves merely as a
>wrapper around an FB FN, to allow the FN to receive and return Pascal-type
>parameters (as used by most OS Managers), instead of whatever wickedly
>clever but non-standard scheme Staz'n'Andy are using in FB^3.

This is doubly wrong, I now see. In a PPC compile with FB^3, ENTERPROC
_does_ preface the FB function with a UPP. And Staz'n'Andy's "wickedly
clever scheme" is actually a standard Pascal-type (even in 68K, the
parameter handling for LOCAL FNs is quite different from the old FB2
method. That _was_ nonstandard).

Back to Steven, whose problem we now believe to be this:
The ThreadManagerBoys work over the corridor from the MixedMode place, and
don't talk to those guys. So the Thread Manager call-back doesn't follow
the rules. It doesn't want the FB function to be prefaced by a UPP; it
wants plain unwrapped executable code. Steven thus has the strange, and we
hope rare, task of (a) persuading FB not make a UPP, and (b) still being
able to pass the correct address of the FN to the OS.

Task (a) is immediately solved: don't use ENTERPROC/EXITPROC.

For Task (b) there are (at least) 3 ways in FB^3 to get the address of some
code. The most obvious is PROC.

From some tests with PROC (and no ENTERPROC/EXITPROC) I can report a Bad
Experience. One of the things PROC does is to modify the contents of the
UPP.  But if there's no UPP, it ends up trampling on code instead. No go.

Another obvious one is LINE.
The FB^3 documentation isn't very encouraging on this. But remember that we
are working in a domain of ignorance far beyond that even of Release 0 of
the FB^3 Reference! And Stephen's recent Bad Experience with LINE and
ENTERPROC/EXITPROC isn't relevant either, because he's going to remove
ENTERPROC/EXITPROC. My tests with LINE look hopeful, except for one teeny
glitch: LINE "THREADENTRY" returns a pointer to the line _before_ the
function. I've fixed that up in the test program below.

Lastly there's @FN, which I haven't looked into. Let's hope that LINE will
cut the mustard (idiom for "not crash so severely as to require a reboot")
when Steven tries the suggestions below in his  thread program.

Robert

'-----------------------------------
dim gSillyTestProc&
end globals

clear local
local fn StartThread
' of course here we don;t attempt to StartThread; we are just testing
dim thredEntryProc&
thredEntryProc& = line "THREADENTRY"' whoops, gets pointer wrong
#if cpuPPC
thredEntryProc&=thredEntryProc&+4' fix pointer to executable code
#else
thredEntryProc&=thredEntryProc&+6' fix pointer to executable code
#endif
' here's the use that Steven will make of thredEntryProc&
//
//gOSErr%=FN NewThread(0,thredEntryProc&,t_ThreadData&,0,0,_nil,t_ThreadData&)
//
'we'll save a copy for testing this address, and drop into MacsBug for fun
gSillyTestProc&=thredEntryProc&
'------------
DIM db$
db$ = "thredEntryProc& " + HEX$(thredEntryProc&) + " points to first real
code of FN ThProc ;il"
CALL DEBUGSTR(db$)
'-------------
end fn

'~Thread Handler Entry
"THREADENTRY"
local FN ThProc(tmp&)'this is what the OS is supposed to call
print "Hello from ThProc" tmp&
end fn

def fn SillyTestThProc(param&) using gSillyTestProc& ' just for testing

window 1
fn StartThread' set up gSillyTestProc&
fn SillyTestThProc(1234)' a test call based on gSillyTestProc&
do
until fn button
end
'-----------------------------------