Stack Considerations

When you start a thread, it begins with the SI stack of the calling function and sees all of the local variables defined in all the functions down the stack. However, unless the calling function specifically waits for the new thread to terminate (see Language Reference: Wait for Threads to Terminate), the calling functions will (bit by bit, in their turn) continue to execute. The new thread's view of its calling environment may then change. Consider the following example:

Suppose that you had the following functions: RUN[3] calls INIT which in turn calls GETDATA but as 3 separate threads with 3 different arguments:

      RUN;A;B
[1]    A1
[2]    B'Hello World'
[3]    INIT
[4]    CALC
[5]    REPORT
     
      INIT;C;D
[1]    CD0
[2]    GETDATA&'Sales'
[3]    GETDATA&'Costs'
[4]    GETDATA&'Expenses'
     

When each GETDATA thread starts, it immediately sees (via ⎕SI) that it was called by INIT which was in turn called by RUN, and it sees local variables A, B, C and D. However, once INIT[4] has been executed, INIT terminates, and execution of the root thread continues by calling CALC. From then on, each GETDATA thread no longer sees INIT (it thinks that it was called directly from RUN) nor can it see the local variables C and D that INIT had defined. However, it does continue to see the locals A and B defined by RUN, until RUN itself terminates.

Note that if CALC were also to define locals A and B, the GETDATA threads would still see the values defined by RUN and not those defined by CALC. However, if CALC were to modify A and B (as globals) without localising them, the GETDATA threads would see the modified values of these variables, whatever they happened to be at the time.