#ifndef __MINITHREAD_PUBLIC_H_ #define __MINITHREAD_PUBLIC_H_ #include "minithread_md.h" /* * minithread_public: * The routines defined in this file are provided * for you to use as you see fit. Except where indicated, there * is no requirement that you use anything here, although you may * find it useful to do so. At the very least, you should look * in the implementation file: minithread_public.c to see how * these routines are implemented in case you decide to roll your * own. * * If you do decide to implement your own version of this * interface, you are required to use the same naming conventions * as this file does. */ /* * Atomic memory operations */ typedef int tas_lock_t; /* test-and-set locks. */ typedef int (*proc_t)(); typedef int *arg_t; /* * * minithread_allocate_stack(stack_pointer_t *stackbase, stack_pointer_t *stacktop) * Allocate a fresh stack. Stacks are said to grow "down". * The bottom of the stack is returned in *stackbase; the top of * the stack is returned in *stacktop. * * ------------------------- * | stacktop | <- next word pushed here * | | * | | * | stackbase | <- bottom of stack. * ------------------------ */ extern void minithread_allocate_stack(stack_pointer_t *stackbase, stack_pointer_t *stacktop); /* * minithread_free_stack(stack_pointer_t stackbase) * Frees the stack at stackbase. If the caller is running on the stack * referenced by stackbase, * then care must be taken to ensure that no other thread uses the same * stack until the caller terminates. */ extern void minithread_free_stack(stack_pointer_t stackbase); /* * minithread_initialize_stack(stack_pointer_t *stacktop, * proc_t initial_proc, * arg_t initial_arg, * proc_t body_proc, * arg_t body_arg, * proc_t final_proc, * arg_t final_arg); * * Initialize the stackframe pointed to by *stacktop so that * the thread running off of *stacktop will invoke: * initial_proc(initial_arg); * body_proc(body_arg); * final_proc(final_arg); * * The call to initial_proc can be used so that a thread can set * up some housekeeping state before calling the forked procedure, which * should be specified as body_proc. * The call to final_proc should be used for cleanup, since it is called * when body_proc returns. final_proc should not return; doing so will * likely cause your program to crash. * * Of the three procedures, only initial_proc may be NULL. * * This procedure changes the value of *stacktop. * */ extern void minithread_initialize_stack(stack_pointer_t *stacktop, proc_t initial_proc, arg_t initial_arg, proc_t body_proc, arg_t body_arg, proc_t final_proc, arg_t final_arg); /* * minithread_switch(stack_pointer_t *old_thread_sp, stack_pointer_t *new_thread_sp); * Context switch code. * Save caller's state on old_thread's stack. * Resume new_thread's stack and continue executing where * new_thread left off. */ extern void minithread_switch(stack_pointer_t *old_thread_sp, stack_pointer_t *new_thread_sp); /* * Use the following routines for the preemptive version of the * threads package a la part 3. */ /* * atomic_test_and_set(tas_lock_t *l) * atomically test and set the value at l. Return old value. Set to 1. * YOU MUST USE THIS IMPLEMENTATION. The actual code for this is in * sys.s. */ extern int atomic_test_and_set(tas_lock_t *l); /* * atomic_clear(tas_lock_t *l) * atomically set the value at l to zero. * YOU MUST USE THIS IMPLEMENTATION. */ extern void atomic_clear(tas_lock_t *l); #endif __MINITHREAD_PUBLIC_H_