[futurebasic] Re: [FB] Threading Test Code (was Enterproc FN)

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

From: "Dr. Steven J. Stratford" <sstratford@...>
Date: Fri, 24 Sep 1999 00:52:48 -0500
Still working on my Threading problem. Staz was right, I needed an 
@LONG on the second parameter of NewThread. I've confirmed with 
macsbug that the thread now does get sent to THREADHANDLERENTRY, as 
it should. But--we're crashing now at YieldToAnyThread with a PPC 
illegal instruction, at THREADHANDLERENTRY+4. But here's a most 
interesting thing--the exact same THREADHANDLERENTRY code that can be 
successfully executed with UNIVERSALPROC gives a crash when called 
via the ThreadManager.  Shouldn't both calls do the same thing?--they 
both pass in one long parameter and don't expect anything in return. 
I don't get it, but here's my testing code with debugstr's in it to 
see for yourself, anyone who cares to muck about in macsbug. 
(disassembly command is "il -c <hex address>")

BTW, threading's not just for ACGI's. It's for situations where you 
want more than one thing "happening" at once (like video games or 
background printing)... And once you see what's going on, it's not 
all that difficult to implement.

--Steve

----------------
'this source code is for testing the Thread Manager. Use with Rntn FBII.INCL
'we get a crash after creating the NewThread and calling YieldToAnyThread
'

library "ThreadsLib"
toolbox fn NewThread(LONG, @LONG, LONG, LONG, LONG, LONG, @LONG) = 
word `0x303C,0x0E03,0xABF2
TOOLBOX FN DisposeThread(LONG, LONG, word) = word `0x303C,0x0504,0xABF2
TOOLBOX FN YieldToAnyThread = word `0x42A7,0x303C,0x0205,0xABF2
TOOLBOX FN GetCurrentThread(@LONG) = word `0x303C,0x0206,0xABF2
library

_kCooperativeThread = 1
_kPreemptiveThread = 2

_kNoCreationOptions = 0
_kNewSuspend = 1
_kUsePremadeThread = 2
_kCreateIfNeeded = 4
_kFPUNotNeeded = 8
_kExactMatchThread = 16

dim gOSErr&, gThreads&
DIM thredHndlrProc&
dim t_ThreadData&

def fn ThreadHandler(t_ThreadData&)
DEF FN SDOCHandler
end globals


'~Main Routine
fn SDOCHandler
do
until len(inkey$) or fn button()
end


'~Thread Handler
'this is the function that "is" the thread
CLEAR LOCAL
LOCAL FN ThreadHandler(ThreadData&)
DIM t_OSErr&, t_currentThreadID&,t_threadResult&,t_recycleThread%
print "we're in thread";ThreadData&
t_OSErr& = fn YieldToAnyThread'will yield to main thread
print "we're back in thread";ThreadData&
DEC(gThreads&)
print "done with thread";t_currentThreadID&
END FN'ThreadHandler

'SDOCHandler is the function that creates the thread and transfers
'control to it
clear local
local fn SDOCHandler


thredHndlrProc& = proc "THREADHANDLERENTRY"
print hex$(thredHndlrProc&)
_theProcFlags = _rtnNone + _p1Long
call debugstr("just before universalproc")
"UNIVPROC"
universalproc(thredHndlrProc&, _theProcFlags, t_ThreadData&)
call debugstr("just after universalproc")

gOSErr% = FN 
NewThread(_kCooperativeThread,thredHndlrProc&,t_ThreadData&,32000,_kCr 
eateIfNeeded,_nil,t_ThreadData&)
call debugstr("just after newthread")

print "Thread set up"

INC (gThreads&)

call debugSTR("ready to yield")
stop
gOSErr% = fn YieldToAnyThread

'loop until the thread is done (the thread will decrement gThreads& 
when it finishes)
'do
print "We're in Main proc!"
'gOSErr% = fn YieldToAnyThread
'if gOSErr% <> _noErr then gThreads& = 0
'until gThreads& = 0

Print "done"
"Goodbye SDOC"
end fn

'~Thread Handler Entry
'this is where MacOS ThreadManager sends us when transferring control to
'a new thread. It takes care of all register swapping in a jiffy

"THREADHANDLERENTRY"
ENTERPROC FN ThreadProc(tmp&)
print "here we are at ThreadHandlerEnterProc"
FN ThreadHandler(tmp&)
EXITPROC
return


--Steve

------------------------
Dr. Steven J. Stratford
Professor, Maranatha Baptist Bible College
Director of Institutional Research
745 W. Main St.
Watertown, WI  53098
920-206-2345
------------------------