home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cset21v1.zip
/
IBMCPP
/
INCLUDE
/
TASK.H
< prev
next >
Wrap
Text File
|
1993-09-17
|
20KB
|
489 lines
#ifndef __task_h
#define __task_h
#pragma info( none )
#ifndef __CHKHDR__
#pragma info( none )
#endif
#pragma info( restore )
/********************************************************************/
/* <task.h> header file */
/* */
/* Licensed Materials - Property of IBM */
/* */
/* IBM C/C++ Tools Version 2.01 */
/* Copyright (C) International Business Machines Corp., 1991, 1993.*/
/* All rights reserved */
/* */
/* */
/* */
/* Licensed Materials - Property of USL */
/* */
/* Standard Class Library Version 3.0 */
/* Copyright (C) Unix System Laboratories Inc. 1991. */
/* All rights reserved */
/* */
/********************************************************************/
/**************************************************************************/
/* C++ source for the C++ Language System, Release 3.0. This product */
/* is a new release of the original cfront developed in the computer */
/* science research center of AT&T Bell Laboratories. */
/* */
/* Copyright (c) 1991 AT&T and UNIX System Laboratories, Inc. */
/* Copyright (c) 1984, 1989, 1990 AT&T. All Rights Reserved. */
/* */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX System */
/* Laboratories, Inc. The copyright notice above does not evidence */
/* any actual or intended publication of such source code. */
/* */
/* UNIX is a registered trademark of UNIX System Laboratories, Inc. */
/* */
/* *ident "@(#)C++env:incl-master/const-headers/task.h 1.6" */
/**************************************************************************/
/* HEADER FILE FOR THE TASK SYSTEM */
#include <signal.h>
#include <stdio.h>
#pragma pack(4)
/* Default size in integers (4 bytes) of stack allocated to a task */
#define SIZE 1024
class object;
class sched; /* : public object */
class timer; /* : public sched */
class task; /* : public sched */
class qhead; /* : public object */
class qtail; /* : public object */
class team;
#define DEFAULT_MODE DEDICATED
/* loc on stack */
#define UNTOUCHED 052525
#define E_ERROR 7000 // ""
#define E_OLINK 7001 // "object::delete(): has chain"
#define E_ONEXT 7002 // "object::delete(): on chain"
#define E_GETEMPTY 7003 // "qhead::get(): empty")
#define E_PUTOBJ 7004 // "qtail::put(): object on other queue"
#define E_PUTFULL 7005 // "qtail::put(): full"
#define E_BACKOBJ 7006 // "qhead::putback(): object on other queue"
#define E_BACKFULL 7007 // "qhead::putback(): full"
#define E_SETCLOCK 7008 // "sched::setclock(): clock!=0"
#define E_CLOCKIDLE 7009 // "sched::schedule(): clock_task not idle"
#define E_RESTERM 7010 // "sched::insert(): cannot schedule terminated sched"
#define E_RESRUN 7011 // "sched::schedule(): running"
#define E_NEGTIME 7012 // "sched::schedule(): clock<0"
#define E_RESOBJ 7013 // "sched::schedule(): task or timer on other queue"
#define E_HISTO 7014 // "histogram::histogram(): bad arguments"
#define E_STACK 7015 // "task::restore() or task::task(): stack overflow"
#define E_STORE 7016 // "new: free store exhausted"
#define E_TASKMODE 7017 // "task::task(): bad mode"
#define E_TASKDEL 7018 // "task::~task(): not terminated"
#define E_TASKPRE 7019 // "task::preempt(): not running"
#define E_TIMERDEL 7020 // "timer::~timer(): not terminated"
#define E_SCHTIME 7021 // "sched::schedule(): runchain corrupted: bad time"
#define E_SCHOBJ 7022 // "sched object used directly (not as base)"
#define E_QDEL 7023 // "queue::~queue(): not empty"
#define E_RESULT 7024 // "task::result(): thistask->result()"
#define E_WAIT 7025 // "task::wait(): wait for self"
#define E_FUNCS 7026 // "FrameLayout::FrameLayout(): function start"
#define E_FRAMES 7027 // "FrameLayout::FrameLayout(): frame size"
#define E_REGMASK 7028 // "task::fudge_return(): unexpected register mask"
#define E_FUDGE_SIZE 7029 // "task::fudge_return(): frame too big"
#define E_NO_HNDLR 7030 // "sigFunc - no handler for signal"
#define E_BADSIG 7031 // "illegal signal number"
#define E_LOSTHNDLR 7032 // "Interrupt_handler::~Interrupt_handler(): signal handler not on chain"
#define E_RETURN 7033 // "task returns without calling task::resultis(int)"
#define E_BADMODE 7034 // "illegal mode passed to qhead::qhead(), qtail::qtail(), qhead::setmode() or qtail::setmode()"
#define E_QZERO 7035 // "Attempt to set the maximum size of a queue to a value less than or equal to 0"
#define E_URAND 7036 // "urand::urand(int,int) bad arguments"
#define E_MAXERR E_URAND
/* Exit code for an unrecoverable runtime error */
#define UNRECOVERABLE 99
typedef int (*PFIO)(int,object*);
typedef void (*PFV)();
/* print flags, used as arguments to class print functions */
#define CHAIN 1
#define VERBOSE 2
#define STACK 4
/* DATA STRUCTURES */
/*
object --> olink --> olink ...
| | |
... V V
| task task
V
object --> ...
*/
class olink
/* the building block for chains of task pointers */
{
friend class object;
olink* l_next;
task* l_task;
olink(task* t, olink* l) { l_task=t; l_next=l; };
};
class object
{
friend class sched;
friend class task;
public:
enum objtype { OBJECT, TIMER, TASK, QHEAD, QTAIL, INTHANDLER };
private:
olink* o_link;
static task* thxstxsk;
public:
object* o_next;
virtual objtype o_type() { return OBJECT; }
object() { o_link=0; o_next=0; }
virtual ~object();
void remember(task*); // save for alert
void forget(task*); // remove all occurrences of task from chain
void alert(); // prepare IDLE tasks for scheduling
virtual int pending(); // TRUE if this object should be waited for
virtual void print(int, int =0);
// 1st arg VERBOSE, CHAIN, or STACK
static int task_error(int, object*);
// the central error function
int task_error(int); // obsolete; use static version
static task* this_task() { return thxstxsk; }
static PFIO error_fct; // user-supplied error function
};
// fake compatibility with previous version
#define thistask (object::this_task())
void _print_error(int);
/* Added for the IBM RS/6000 */
/* and the OS/2. */
extern "C" {
typedef void SIG_FUNC_TYP(int);
typedef void (*SIG_PF)(int);
}
class sched : public object { // only instances of subclasses are used
friend class timer;
friend class task;
friend class object;
friend void _print_error(int n);
friend SIG_FUNC_TYP sigFunc;
public:
enum statetype { IDLE=1, RUNNING=2, TERMINATED=4 };
private:
static int keep_waiting_count;
static sched* runchain; // list of ready-to-run scheds (by s_time)
static sched* priority_sched; // if non-zero, sched to run next
static long clxck;
static int exit_status;
long s_time; // time to sched; result after cancel()
statetype s_state; // IDLE, RUNNING, TERMINATED
void schedule(); // sched clock_task or front of runchain
virtual void resume();
void insert(long,object*);// sched for long time units, t_alert=obj
void remove(); // remove from runchain & make IDLE
protected:
sched() : s_time(0), s_state(IDLE) {}
public:
static void setclock(long);
static long get_clock() { return clxck; }
static sched* get_run_chain() { return runchain; }
static int get_exit_status() { return exit_status; }
static void set_exit_status( int i ) { exit_status = i; }
sched* get_priority_sched() { return priority_sched; }
static task* clock_task; // awoken at each clock tick
long rdtime() { return s_time; };
statetype rdstate() { return s_state; };
int pending() { return s_state != TERMINATED; }
int keep_waiting() { return keep_waiting_count++; }
int dont_wait() { return keep_waiting_count--; }
void cancel(int);
int result();
virtual void setwho(object* t); // who alerted me
void print(int, int =0);
static PFV exit_fct; // user-supplied exit function
};
// for compatibility with pre-2.0 releases,
// but conflicts with time.h
//#define clock (sched::get_clock())
inline void setclock(long i) { sched::setclock(i); }
// for compatibility with pre-2.0 releases
#define run_chain (sched::get_run_chain())
class timer : public sched {
void resume();
public:
timer(long);
~timer();
void reset(long);
object::objtype o_type() { return TIMER; }
void setwho(object*) { } // do nothing
void print(int, int =0);
};
extern _hwm;
class task : public sched {
friend class sched;
public:
enum modetype { DEDICATED=1, SHARED=2 };
private:
static task* txsk_chxin; // list of all tasks
static team* team_to_delete; // delete this team after task switch
void restore(task*, int =0); // switch to new task
int curr_hwm(); // "high water mark"
// (how high stack has risen)
int swap_stack(int*,int*); // initialize child stack
void fudge_return(int*); //used in starting new tasks
void copy_share(); // used in starting shared tasks
void get_size(); // ditto -- saves size of active stack
void resume();
/* simple check for stack overflow--not used for main task */
void settrap();
void checktrap();
/* WARNING: t_framep, th, and t_ap are manipulated as offsets from
* task by swap(); those, and t_basep, t_size, and t_savearea are
* manipulated as offsets by sswap().
* Do not insert new data members before these.
*/
int* t_framep; // fp for this task when suspended
void* th; // fudge return from swap
int* t_ap; // arg pointer for this task when suspended
int* t_basep; // addr of stack when running
int t_size; // size of active stack (used for SHARED)
// holds hwm after cancel()
int* t_savearea; // addr of stack when not running (SHARED only)
int t_trap; // used for stack overflow check
team* t_team; // stack and info for sharing
modetype t_mode; // DEDICATED/SHARED stack
int t_stacksize;
object* t_alert; // object that inserted you
int * p_stack ; // Added for OS/2.
int * p_stacklimit ; // Added for OS/2.
protected:
task(char* name=0, modetype mode=DEFAULT_MODE, int stacksize=SIZE);
public:
~task();
object::objtype o_type() { return TASK; }
task* t_next; // insertion in "task_chain"
char* t_name;
static task* get_task_chain() { return txsk_chxin; }
int waitvec(object**);
int waitlist(object* ...);
void wait(object* ob);
void delay(long);
long preempt();
void sleep(object* t =0); // t is remembered
void resultis(int);
void cancel(int);
void setwho(object* t) { t_alert = t; }
void print(int, int =0);
object* who_alerted_me() { return t_alert; }
public:
// Added to support Exception handling on the IBM RS/6000
// and the OS/2.
void *__currentException;
};
// for compatibility
#define task_chain (task::get_task_chain())
// an Interrupt_handler supplies an interrupt routine that runs when the
// interrupt occurs (real time). Also the Interrupt_handler can be waited for.
class Interrupt_handler : public object {
friend class Interrupt_alerter;
friend SIG_FUNC_TYP sigFunc;
int id; // signal or interrupt number
int got_interrupt; // an interrupt has been received
// but not alerted
Interrupt_handler *old; // previous handler for this signal
virtual void interrupt(); // runs at real time
public:
Interrupt_handler(int sig_num);
~Interrupt_handler();
object::objtype o_type() { return INTHANDLER; }
int pending(); // FALSE once after interrupt
void print(int, int =0); // VERBOSE or 0
};
/* QUEUE MANIPULATION (see queue.c) */
/*
qhead <--> oqueue <--> qtail (qhead, qtail independent)
oqueue ->> circular queue of objects
*/
/* qh_modes */
enum qmodetype { EMODE, WMODE, ZMODE };
class oqueue
{
friend class qhead;
friend class qtail;
int q_max;
int q_count;
object* q_ptr;
qhead* q_head;
qtail* q_tail;
oqueue(int m) { q_max=m; q_count=0; q_head=0; q_tail=0; };
~oqueue() { (q_count)?object::task_error(E_QDEL,0):0; };
void print(int);
};
class qhead : public object
{
friend class qtail;
qmodetype qh_mode; /* EMODE,WMODE,ZMODE */
oqueue* qh_queue;
public:
qhead(qmodetype = WMODE, int = 10000);
~qhead();
object::objtype o_type() { return QHEAD; }
object* get();
int putback(object*);
int rdcount() { return qh_queue->q_count; }
int rdmax() { return qh_queue->q_max; }
qmodetype rdmode() { return qh_mode; }
qtail* tail();
qhead* cut();
void splice(qtail*);
void setmode(qmodetype m);
void setmax(int m);
int pending() { return rdcount() == 0; }
void print(int, int =0);
};
class qtail : public object
{
friend class qhead;
qmodetype qt_mode;
oqueue* qt_queue;
public:
qtail(qmodetype = WMODE, int = 10000);
~qtail();
object::objtype o_type() { return QTAIL; }
int put(object*);
int rdspace()
{ return qt_queue->q_max - qt_queue->q_count; };
int rdmax() { return qt_queue->q_max; };
qmodetype rdmode() { return qt_mode; };
qtail* cut();
void splice(qhead*);
qhead* head();
void setmode(qmodetype m);
void setmax(int m);
int pending() { return rdspace() <= 0; }
void print(int, int =0);
};
struct histogram
/*
"nbin" bins covering the range [l:r] uniformly
nbin*binsize == r-l
*/
{
int l, r;
int binsize;
int nbin;
int* h;
long sum;
long sqsum;
histogram(int=16, int=0, int=16);
void add(int);
void print();
};
/* the result of randint() is always >= 0 */
#define DRAW (randx = randx*1103515245 + 12345)
#define ABS(x) (x&0x7fffffff)
#define MASK(x) ABS(x)
class randint
/* uniform distribution in the interval [0,MAXINT_AS_FLOAT] */
{
long randx;
public:
randint(long s = 0) { randx=s; }
void seed(long s) { randx=s; }
int draw() { return MASK(DRAW); }
float fdraw();
};
class urand : public randint
/* uniform distribution in the interval [low,high] */
{
public:
int low, high;
urand(int l, int h);
int draw();
};
class erand : public randint
/* exponential distribution random number generator */
{
public:
int mean;
erand(int m) { mean=m; };
int draw();
};
// This task will alert Interrupt_handler objects.
class Interrupt_alerter : public task {
public:
Interrupt_alerter();
~Interrupt_alerter();
};
extern Interrupt_alerter interrupt_alerter;
#pragma pack()
#pragma info( none )
#ifndef __CHKHDR__
#pragma info( restore )
#endif
#pragma info( restore )
#endif