home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 2
/
AUCD2.iso
/
program
/
vista.arc
/
!Vista
/
h
/
thread
< prev
next >
Wrap
Text File
|
1996-01-25
|
9KB
|
254 lines
// **************************************************************************
// Copyright 1996 David Allison
//
// VV VV IIIIII SSSSS TTTTTT AA
// VV VV II SS TT AA AA
// VV VV II SSSS TT AA AA
// VV VV II SS TT AAAAAAAA
// VV IIIIII SSSS TT AA AA
//
// MULTI-THREADED C++ WIMP CLASS LIBRARY
// for RISC OS
// **************************************************************************
//
// P U B L I C D O M A I N L I C E N C E
// -------------------------------------------
//
// This library is copyright. You may not sell the library for
// profit, but you may sell products which use it providing
// those products are presented as executable code and are not
// libraries themselves. The library is supplied without any
// warranty and the copyright owner cannot be held responsible for
// damage resulting from failure of any part of this library.
//
// See the User Manual for details of the licence.
//
// *************************************************************************
//
// threads
//
#ifndef __thread_h
#define __thread_h
#include "Vista:defs.h"
#include "Vista:tasm.h"
#ifdef __EASY_C
#include <throw.h> // exception stuff
#endif
#ifndef __delete_h
#include "Vista:delete.h"
#endif
#include <kernel.h>
#ifndef __EXCEPTION_STATE_SIZE
#define __EXCEPTION_STATE_SIZE 16
#endif
class ThreadManager ;
extern void dprintf (char*...) ;
//
// general thread resource class
//
class ThreadResource
{
public:
ThreadResource() ;
int available ;
} ;
//
// thread timer resource
//
class ThreadTimer : public ThreadResource
{
public:
ThreadTimer (ThreadManager *m, int delay) ;
~ThreadTimer() ;
void check_time (int time) ;
ThreadTimer *next, *prev ;
ThreadManager *manager ;
private:
int time_set ;
} ;
//
// thread pipe resource for comms
//
class ThreadPipe : public ThreadResource
{
public:
ThreadPipe () ;
~ThreadPipe() ;
void write (char *buffer, int nbytes) ;
void read (char *buffer, int max, int &nbytes) ;
private:
char *data ; // data buffer
int size ; // size of data in buffer
int max ; // max size of buffer
} ;
class ThreadSemaphore : public ThreadResource
{
public:
void set() { available = 1 ;}
void clear() { available = 0 ; }
int check() { return available ; }
} ;
const int THREAD_BASE_PRIORITY = 60 ;
const int THREAD_STARTUP_PRIORITY = 60 ;
// The base priority is the starting priority for a thread. The neutral value
// is 60. Any priority lower than this is consider higher priority and
// will get more cpu cycles than lower priority threads. A higher priority
// value will get less cpu cycles. This is equivalent to the UNIX 'nice'
// value.
class Thread : public ThreadResource, virtual public DeferredDelete
{
public:
enum State
{
IDLE, // not on any queues
READY, // on the run queue and ready
RUNNING, // running
SLEEPING, // on the sleep queue
STOPPED, // not on any queue, but can be restarted
DEAD // not on any queue and is dead
} ;
public:
Thread(char *name, int priority = THREAD_BASE_PRIORITY, int newstack = 1) ;
virtual ~Thread() ;
void start() ; // start the thread running asynchronously
void start2() ; // internal start routine - DO NOT CALL
virtual void run() = 0 ; // pure virtual user supplied run function
virtual void stop() ; // stop the thread until resumed
virtual void resume() ; // resume a stopped thread running
virtual void kill() ; // kill a thread off - cannot be rerun
virtual void sleep (int time) ; // sleep for a number of centiseconds
virtual void sleep (ThreadResource *, int pri = THREAD_BASE_PRIORITY) ; // sleep waiting for a resource
virtual void wakeup () ; // wake up the thread
virtual void write (ThreadPipe *pipe, char *buffer, int nbytes) ; // write to a pipe
virtual void read (ThreadPipe *pipe, char *buffer, int max, int &nbytes) ; // read from a pipe
void setpriority (int pri) ; // set the base priority
virtual int resource_available() ; // is the resource availble while sleeping
virtual void exit (int status = 0) ;
virtual void yield() ; // yield control to another thread
public:
Thread *next, *prev ; // links to main thread list
Thread *nextq, *prevq ; // queue pointers
char save_area[16 * 4 + 12 * 8 + 4] ; // register save area
#ifdef __EASY_C
char exception_state [__EXCEPTION_STATE_SIZE] ; // exception handler state
#endif
_kernel_stack_chunk *stack ; // private stack
ThreadManager *manager ; // my manager
State state ; // current state
ThreadResource *resource ; // resource I am waiting for
int priority ; // current priority
int base_priority ; // base priority
int cputime ; // current CPU usage in centiseconds
int accumulated_cputime ; // accumulated CPU centiseconds
char *name ; // thread name
int exit_status ; // exit status
int time ; // time thread gained CPU
} ;
//
// This is the main thread. It is the overall controller thread. When it returns all threads
// are suspended
//
class MainThread : public Thread
{
public:
MainThread() ;
~MainThread() ;
void run() ;
void set_limit (int quanta) ;
private:
int quantum_limit ;
} ;
//
// This thread is responsible for the management of timers and resources
//
class ResourceThread : public Thread
{
public:
ResourceThread() ;
void run() ;
} ;
//
// The thread manager. This manages a set of running threads.
//
const int THREAD_STACK_BLOCK = 5 ;
const int THREAD_STACK_SIZE = 4096 ;
class ThreadManager
{
friend class MainThread ;
friend class Thread ;
friend class ResourceThread ;
public:
ThreadManager() ;
~ThreadManager() ;
void run (int quanta) ; // run for a specified number of quanta
void context_switch() ; // switch to next thread
void run_thread (Thread *) ; // place a thread on the run queue
void stop_thread (Thread *) ; // remove a thread from the run queue
void sleep_thread (Thread *) ; // place a thread on the sleep queue
void wakeup_thread (Thread *) ; // remove a thread from the sleep queue
void insert_thread (Thread *) ; // insert a new thread
void delete_thread (Thread *) ; // delete a thread
void next_thread() ; // start the highest priority thread running
void insert_timer(ThreadTimer *) ; // start a new timer
void delete_timer (ThreadTimer*) ; // remove a timer
_kernel_stack_chunk *new_stack() ; // allocate a new stack
void delete_stack(_kernel_stack_chunk *stack) ;
void exit() ; // exit the thread manager
void sleep (int time) ;
void sleep (ThreadResource *, int pri = THREAD_BASE_PRIORITY) ;
void yield() ;
void show_threads() ;
void stop_threads() ;
void resume_threads() ;
int num_running_threads ; // number of threads currenly running
int num_threads ; // number of threads including system ones
private:
Thread *threads, *last_thread ; // list of current threads
Thread *runqueue, *end_runqueue ; // the run queue - threads ready to run
Thread *sleepqueue, *end_sleepqueue ;// the sleep queue - threads waiting for a resource
ThreadTimer *timers, *last_timer ; // list of current timers
Thread *running ; // thread currently running
MainThread *main_thread ; // main thread
ResourceThread *resource_thread ; // resource thread
public:
static ThreadManager *current_manager ; // me
private:
int quantum_count ; // number of quanta counter
_kernel_stack_chunk *stack_pool ; // pool of stacks
} ;
#endif