'' '' $Id: SimpleTask.bas,v 1.2 1994/03/16 15:07:24 alex Rel $ '' '' Task creation and co-ordination from BASIC '' '' Derived from RKM example (c) Copyright 1992 Commodore-Amiga, Inc. '' DEFINT A-Z ' multi-threaded code runs in several contexts, so the normal checks may ' crash correct programs - lets turn everything off REM $NOAUTODIM REM $NOARRAY REM $NOBREAK REM $NOOVERFLOW REM $NOEVENT REM $NOSTACK 'REM $INCLUDE Exec.bh 'REM $INCLUDE Utility.bc REM $INCLUDE BLib/ExecSupport.bas REM $INCLUDE BLib/HookEntryTask.bas LIBRARY OPEN "exec.library", LIBRARY_MINIMUM& CONST STACK_SIZE& = 1000 DIM SHARED sharedvar&, junk& ' ' The sub-task, the range of things this can do are pretty limited: it absolutely ' must not-ever call DOS (since you must be a process to do that), this means that ' many BASIC commands are out. It must not do anything which may cause non-reentrant ' BASIC runtimes to be reentered (e.g. string handling, dynamic array usage). ' ' Basically you can call the OS do simple BASIC stuff and little else. ' SUB simpletask SHARED parent&, sigf_quitchild& STATIC sigb_quitchild sigf_quitchild& = -1 ' so the parent knows we had a problem sigb_quitchild = AllocSignal&(-1) IF sigb_quitchild <> -1 THEN sigf_quitchild& = 1& << sigb_quitchild Signal parent&, SIGF_SINGLE& ' signal our parent we're initialised DO WHILE sharedvar& < &h7fffffff INCR sharedvar& IF SetSignal&(0, sigf_quitchild&) AND sigf_quitchild& THEN EXIT LOOP LOOP FreeSignal sigb_quitchild END IF Forbid ' forcibly run us to completion Signal parent&, SIGF_SINGLE& ' signal our parent we're about to quit END SUB SUB main SHARED parent&, sigf_quitchild& STATIC task& sharedvar& = 0 parent& = FindTask&(NULL&) ' so the child nows who its parent was task& = CreateHookEntryTask&(SADD("SimpleTask" + CHR$(0)), 0, _ VARPTRS(simpletask), STACK_SIZE&) IF task& <> NULL& THEN junk& = SetSignal&(0, SIGF_SINGLE&) ' ensure signal is clear junk& = xWait&(SIGF_SINGLE&) ' wait until task has started IF sigf_quitchild& <> -1 THEN PRINT "This program initialised a variable to zero, then started a" PRINT "separate task which is incrementing that variable right now," PRINT "while this program waits for an event." PRINT "Cause an event now (click in the window!)" SLEEP PRINT "The shared variable now equals"; sharedvar& ' Tasks created via CreateHookEntryTask must not be DeleteTask'd or ' RemTask'd (since not all of the memory is attached to the MemLists) ' So we first ask the child to terminate by giving it a signal which ' it allocated, then borrow the SIGF_SINGLE signal to co-ordinate our ' actions with our child task Signal task&, sigf_quitchild& ' ask the child to terminate ' Whilst the RKMs say say you can't use any of the systems signal bits ' SIGF_SINGLE can be legitimately used in this way; you clear the signal, ' then immediately wait on it junk& = SetSignal&(0, SIGF_SINGLE&) ' ensure signal is clear junk& = xWait&(SIGF_SINGLE&) ' and wait until it does quit ELSE PRINT "Child couldn't allocate a termination signal" END IF ELSE PRINT "Can't create task" END IF END SUB main END