MC logo

A Multiple-Stack Computation

^  Dr. Bennet

Tswitch

Main Page
F06 Assignment
Download Library
CCSC '07 Paper

Clients for Tswitch

Save And Restore
Restack
Multiple Stacks

Clients for the F06 Assignment

Simple
Thread Demolition Derby
Graph Search
This beast just prints 309148, which is:
45 + 125 + 35 + 95
The terms are computed with multiplies repeated by the loop in the function raise. The program creates four stacks, one for each of the terms. It then interleaves the term computations by iteration, performing in turn one multiply from each. When all have performed five multiplies, the individual products are returned and totaled.

<<Restack With Save And Restore tstest4.cc
/*
 * This program demonstrates the use of regsave(), regrest() and restack().
 * It is a demonstration program, and does nothing particularly useful.  What
 * it does do is compute
 *
 *     5     5    5    5
 *    4  + 12  + 3  + 9  = 309148
 *
 * In the strangest possible way.
 *
 */
#include <iostream>
#include <stdlib.h>
#include <tswitch.h>
using namespace std;

/* This keeps track of my four computers (threads really) other than the
   main one.  Each one has some space to hold the stack and a register
   save area. */

/* Size of each stack area.  */
#define STSIZE 600
struct tstate {
        regbuf_t regs;          // Register save area.
        unsigned stack[STSIZE]; // Stack space.
} states[4];

/* Register save area for the main thread. */
regbuf_t mstate;

// We create four copies of this beast in separate threads.  We start each one,
// then use regrest in the main to step each one through five iterations,
// then exit.
int raise(int i, int p)
{
        int pwr = 1;

        // Get a new stack, save a state using the new stack, then
        // restore the mstate, which will bring us back to the main loop.
        // Whenever the main loop restores us again, we'll proceed from the
        // regsave() below.
        restack(states[i-1].stack, STSIZE, 2, 3);
        if(regsave(states[i-1].regs) == 0) regrest(mstate, i);

        // This goes until the boss has us end.
        while(1) {
                // One step in raising p to some power.
                pwr *= p;

                // Save our state, and switch back to main.  If we are
                // restated with 2, we leave the loop and return.
                int n = regsave(states[i-1].regs);
                if(n == 0) regrest(mstate, i);
                if(n == 2) break;
        }

        return pwr;
}

int main() 
{
        // This will fire up four copies of raise(), each with its own stack.  
        // To create each one, we save our state in the global mstate and call 
        // the raise function.  The function creates a new stack, then restores
        // mstate.  This returns control our regsave call, which then does the 
        // next one.  Each raise restores mstate with its n value, so we'll 
        // know when we've done the last one.  Once each is started, we go on
        // to the for loop below.  None of the raise() calls return until 
        // released by that loop, so we won'd to the second half of this if 
        // until then.
        int base[] = { 4, 12, 3, 9 };
        volatile int n = 0;  // The volatile should keep from using a register.
        int tot = 0;         // Total returns here.
        int *totptr = &tot;  // Point to tot in main stk from other stacks.
        if(regsave(mstate) < 4) {
                // Start a copy of raise on its own stack, then transfer back
                // to the regsave().
                ++n;
                int pwr = raise(n, base[n-1]);

                //cout << "tot = " << tot << endl;

                // The raise() function doesn't return until we restore its
                // state with return code 2, which is done in the next loop.
                // When that happens, add into the sum, then resume the loop
                // below.
                *totptr += pwr;
                regrest(mstate, n);
        }

        // We now have four raise()s running on four stacks.  Run each five 
        // times to perform multiplies, then once more to exit and return.
        // The state then goes back to the start loop, were we use rerest()
        // to bring it back here.
        for(int ct = 1; ct <= 6; ct++) {
                // Runs each thread for one iteration.
                n = 0;
                if(regsave(mstate) < 4)
                        regrest(states[n++].regs, ct == 6 ? 2 : 1);
        }

        cout << "Total is: " << tot << endl;
}
<<Restack With Save And Restore