home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v1.zip / IBMCPP / INCLUDE / TASK.H < prev    next >
Text File  |  1993-09-17  |  20KB  |  489 lines

  1. #ifndef __task_h
  2.    #define __task_h
  3.  
  4.    #pragma info( none )
  5.    #ifndef __CHKHDR__
  6.       #pragma info( none )
  7.    #endif
  8.    #pragma info( restore )
  9.  
  10.    /********************************************************************/
  11.    /*  <task.h> header file                                            */
  12.    /*                                                                  */
  13.    /*  Licensed Materials - Property of IBM                            */
  14.    /*                                                                  */
  15.    /*  IBM C/C++ Tools Version 2.01                                    */
  16.    /*  Copyright (C) International Business Machines Corp., 1991, 1993.*/
  17.    /*  All rights reserved                                             */
  18.    /*                                                                  */
  19.    /*                                                                  */
  20.    /*                                                                  */
  21.    /*  Licensed Materials - Property of USL                            */
  22.    /*                                                                  */
  23.    /*  Standard Class Library Version 3.0                              */
  24.    /*  Copyright (C) Unix System Laboratories Inc. 1991.               */
  25.    /*  All rights reserved                                             */
  26.    /*                                                                  */
  27.    /********************************************************************/
  28.  
  29.    /**************************************************************************/
  30.    /*  C++ source for the C++ Language System, Release 3.0.  This product    */
  31.    /*  is a new release of the original cfront developed in the computer     */
  32.    /*  science research center of AT&T Bell Laboratories.                    */
  33.    /*                                                                        */
  34.    /*  Copyright (c) 1991 AT&T and UNIX System Laboratories, Inc.            */
  35.    /*  Copyright (c) 1984, 1989, 1990 AT&T.  All Rights Reserved.            */
  36.    /*                                                                        */
  37.    /*  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX System   */
  38.    /*  Laboratories, Inc.  The copyright notice above does not evidence      */
  39.    /*  any actual or intended publication of such source code.               */
  40.    /*                                                                        */
  41.    /*  UNIX is a registered trademark of UNIX System Laboratories, Inc.      */
  42.    /*                                                                        */
  43.    /*  *ident "@(#)C++env:incl-master/const-headers/task.h    1.6"           */
  44.    /**************************************************************************/
  45.  
  46.  
  47.    /*      HEADER FILE FOR THE TASK SYSTEM         */
  48.  
  49.    #include <signal.h>
  50.    #include <stdio.h>
  51.  
  52.    #pragma pack(4)
  53.  
  54.    /* Default size in integers (4 bytes) of stack allocated to a task */
  55.  
  56.    #define SIZE            1024
  57.  
  58.    class object;
  59.    class sched;    /* : public object */
  60.    class timer;    /* : public sched  */
  61.    class task;     /* : public sched  */
  62.    class qhead;    /* : public object */
  63.    class qtail;    /* : public object */
  64.    class team;
  65.  
  66.    #define DEFAULT_MODE    DEDICATED
  67.  
  68.    /* loc on stack */
  69.    #define UNTOUCHED       052525
  70.  
  71.    #define E_ERROR      7000  //  ""
  72.    #define E_OLINK      7001  //  "object::delete(): has chain"
  73.    #define E_ONEXT      7002  //  "object::delete(): on chain"
  74.    #define E_GETEMPTY   7003  //  "qhead::get(): empty")
  75.    #define E_PUTOBJ     7004  //  "qtail::put(): object on other queue"
  76.    #define E_PUTFULL    7005  //  "qtail::put(): full"
  77.    #define E_BACKOBJ    7006  //  "qhead::putback(): object on other queue"
  78.    #define E_BACKFULL   7007  //  "qhead::putback(): full"
  79.    #define E_SETCLOCK   7008  //  "sched::setclock(): clock!=0"
  80.    #define E_CLOCKIDLE  7009  //  "sched::schedule(): clock_task not idle"
  81.    #define E_RESTERM    7010  //  "sched::insert(): cannot schedule terminated sched"
  82.    #define E_RESRUN     7011  //  "sched::schedule(): running"
  83.    #define E_NEGTIME    7012  //  "sched::schedule(): clock<0"
  84.    #define E_RESOBJ     7013  //  "sched::schedule(): task or timer on other queue"
  85.    #define E_HISTO      7014  //  "histogram::histogram(): bad arguments"
  86.    #define E_STACK      7015  //  "task::restore() or task::task(): stack overflow"
  87.    #define E_STORE      7016  //  "new: free store exhausted"
  88.    #define E_TASKMODE   7017  //  "task::task(): bad mode"
  89.    #define E_TASKDEL    7018  //  "task::~task(): not terminated"
  90.    #define E_TASKPRE    7019  //  "task::preempt(): not running"
  91.    #define E_TIMERDEL   7020  //  "timer::~timer(): not terminated"
  92.    #define E_SCHTIME    7021  //  "sched::schedule(): runchain corrupted: bad time"
  93.    #define E_SCHOBJ     7022  //  "sched object used directly (not as base)"
  94.    #define E_QDEL       7023  //  "queue::~queue(): not empty"
  95.    #define E_RESULT     7024  //  "task::result(): thistask->result()"
  96.    #define E_WAIT       7025  //  "task::wait(): wait for self"
  97.    #define E_FUNCS      7026  //  "FrameLayout::FrameLayout(): function start"
  98.    #define E_FRAMES     7027  //  "FrameLayout::FrameLayout(): frame size"
  99.    #define E_REGMASK    7028  //  "task::fudge_return(): unexpected register mask"
  100.    #define E_FUDGE_SIZE 7029  //  "task::fudge_return(): frame too big"
  101.    #define E_NO_HNDLR   7030  //  "sigFunc - no handler for signal"
  102.    #define E_BADSIG     7031  //  "illegal signal number"
  103.    #define E_LOSTHNDLR  7032  //  "Interrupt_handler::~Interrupt_handler(): signal handler not on chain"
  104.    #define E_RETURN     7033  //  "task returns without calling task::resultis(int)"
  105.    #define E_BADMODE    7034  //  "illegal mode passed to qhead::qhead(), qtail::qtail(), qhead::setmode() or qtail::setmode()"
  106.    #define E_QZERO      7035  //  "Attempt to set the maximum size of a queue to a value less than or equal to 0"
  107.    #define E_URAND      7036  //  "urand::urand(int,int) bad arguments"
  108.    #define E_MAXERR     E_URAND
  109.  
  110.  
  111.    /* Exit code for an unrecoverable runtime error */
  112.    #define UNRECOVERABLE 99
  113.  
  114.    typedef int (*PFIO)(int,object*);
  115.    typedef void (*PFV)();
  116.  
  117.    /* print flags, used as arguments to class print functions */
  118.    #define CHAIN           1
  119.    #define VERBOSE         2
  120.    #define STACK           4
  121.  
  122.    /* DATA STRUCTURES */
  123.    /*
  124.            object --> olink --> olink ...
  125.               |         |         |
  126.              ...        V         V
  127.               |        task      task
  128.               V
  129.            object --> ...
  130.    */
  131.  
  132.    class olink
  133.    /*      the building block for chains of task pointers */
  134.    {
  135.    friend class object;
  136.            olink*  l_next;
  137.            task*   l_task;
  138.                    olink(task* t, olink* l) { l_task=t; l_next=l; };
  139.    };
  140.  
  141.    class object
  142.    {
  143.    friend class sched;
  144.    friend class task;
  145.    public:
  146.            enum objtype { OBJECT, TIMER, TASK, QHEAD, QTAIL, INTHANDLER };
  147.    private:
  148.            olink*  o_link;
  149.            static task*    thxstxsk;
  150.    public:
  151.            object* o_next;
  152.            virtual objtype o_type()        { return OBJECT; }
  153.  
  154.                    object()                { o_link=0; o_next=0; }
  155.            virtual ~object();
  156.  
  157.            void    remember(task*);   // save for alert
  158.            void    forget(task*);     // remove all occurrences of task from chain
  159.            void    alert();           // prepare IDLE tasks for scheduling
  160.            virtual int     pending(); // TRUE if this object should be waited for
  161.            virtual void    print(int, int =0);
  162.                                       // 1st arg VERBOSE, CHAIN, or STACK
  163.            static int      task_error(int, object*);
  164.                                       // the central error function
  165.            int     task_error(int);   // obsolete; use static version
  166.            static task*    this_task()     { return thxstxsk; }
  167.            static  PFIO    error_fct; // user-supplied error function
  168.    };
  169.  
  170.    // fake compatibility with previous version
  171.    #define thistask (object::this_task())
  172.  
  173.    void _print_error(int);
  174.  
  175.    /* Added for the IBM RS/6000 */
  176.    /* and the OS/2.             */
  177.    extern "C" {
  178.      typedef void SIG_FUNC_TYP(int);
  179.      typedef void (*SIG_PF)(int);
  180.    }
  181.  
  182.    class sched : public object {      // only instances of subclasses are used
  183.    friend class timer;
  184.    friend class task;
  185.    friend class object;
  186.    friend void _print_error(int n);
  187.    friend SIG_FUNC_TYP sigFunc;
  188.    public:
  189.            enum statetype { IDLE=1, RUNNING=2, TERMINATED=4 };
  190.    private:
  191.            static int      keep_waiting_count;
  192.            static sched*   runchain;    // list of ready-to-run scheds (by s_time)
  193.            static sched*   priority_sched; // if non-zero, sched to run next
  194.            static  long    clxck;
  195.            static int      exit_status;
  196.            long    s_time;              // time to sched; result after cancel()
  197.            statetype       s_state;     // IDLE, RUNNING, TERMINATED
  198.            void    schedule();          // sched clock_task or front of runchain
  199.            virtual void    resume();
  200.            void    insert(long,object*);// sched for long time units, t_alert=obj
  201.            void    remove();            // remove from runchain & make IDLE
  202.  
  203.    protected:
  204.                    sched() : s_time(0), s_state(IDLE) {}
  205.    public:
  206.  
  207.            static void     setclock(long);
  208.            static long     get_clock() { return clxck; }
  209.            static sched*   get_run_chain() { return runchain; }
  210.            static int      get_exit_status() { return exit_status; }
  211.            static void     set_exit_status( int i ) { exit_status = i; }
  212.            sched*  get_priority_sched() { return priority_sched; }
  213.            static  task*   clock_task;     // awoken at each clock tick
  214.            long    rdtime()        { return s_time; };
  215.            statetype       rdstate()       { return s_state; };
  216.            int     pending()       { return s_state != TERMINATED; }
  217.            int     keep_waiting()  { return keep_waiting_count++; }
  218.            int     dont_wait()     { return keep_waiting_count--; }
  219.  
  220.            void    cancel(int);
  221.            int     result();
  222.            virtual void    setwho(object* t);  // who alerted me
  223.            void    print(int, int =0);
  224.            static  PFV     exit_fct;       // user-supplied exit function
  225.    };
  226.    // for compatibility with pre-2.0 releases,
  227.    // but conflicts with time.h
  228.    //#define clock (sched::get_clock())
  229.    inline void     setclock(long i) { sched::setclock(i); }
  230.  
  231.    // for compatibility with pre-2.0 releases
  232.    #define run_chain (sched::get_run_chain())
  233.  
  234.    class timer : public sched {
  235.            void    resume();
  236.    public:
  237.                    timer(long);
  238.                    ~timer();
  239.            void    reset(long);
  240.            object::objtype o_type()        { return TIMER; }
  241.            void    setwho(object*) { }     // do nothing
  242.            void    print(int, int =0);
  243.    };
  244.  
  245.    extern _hwm;
  246.    class task : public sched {
  247.    friend class sched;
  248.    public:
  249.            enum modetype { DEDICATED=1, SHARED=2 };
  250.    private:
  251.            static task*    txsk_chxin;     // list of all tasks
  252.            static team*    team_to_delete; // delete this team after task switch
  253.            void    restore(task*, int =0); // switch to new task
  254.            int     curr_hwm();             // "high water mark"
  255.                                            //     (how high stack has risen)
  256.            int     swap_stack(int*,int*);  // initialize child stack
  257.            void    fudge_return(int*);     //used in starting new tasks
  258.            void    copy_share();           // used in starting shared tasks
  259.            void    get_size();             // ditto -- saves size of active stack
  260.            void    resume();
  261.            /* simple check for stack overflow--not used for main task */
  262.            void    settrap();
  263.            void    checktrap();
  264.            /* WARNING: t_framep, th, and t_ap are manipulated as offsets from
  265.             * task by swap(); those, and t_basep, t_size, and t_savearea are
  266.             * manipulated as offsets by sswap().
  267.             * Do not insert new data members before these.
  268.             */
  269.            int*    t_framep;       // fp for this task when suspended
  270.            void*   th;             // fudge return from swap
  271.            int*    t_ap;           // arg pointer for this task when suspended
  272.            int*    t_basep;        // addr of stack when running
  273.            int     t_size;         // size of active stack (used for SHARED)
  274.                                    //   holds hwm after cancel()
  275.            int*    t_savearea;     // addr of stack when not running (SHARED only)
  276.            int     t_trap;         // used for stack overflow check
  277.            team*   t_team;         // stack and info for sharing
  278.  
  279.            modetype        t_mode; // DEDICATED/SHARED stack
  280.            int     t_stacksize;
  281.  
  282.            object* t_alert;        // object that inserted you
  283.  
  284.            int *   p_stack ;       // Added for OS/2.
  285.            int *   p_stacklimit ;  // Added for OS/2.
  286.  
  287.    protected:
  288.                    task(char* name=0, modetype mode=DEFAULT_MODE, int stacksize=SIZE);
  289.    public:
  290.                    ~task();
  291.  
  292.            object::objtype o_type()        { return TASK; }
  293.            task*   t_next;         // insertion in "task_chain"
  294.            char*   t_name;
  295.  
  296.            static task*    get_task_chain() { return txsk_chxin; }
  297.            int     waitvec(object**);
  298.            int     waitlist(object* ...);
  299.            void    wait(object* ob);
  300.  
  301.            void    delay(long);
  302.            long    preempt();
  303.            void    sleep(object* t =0);    // t is remembered
  304.            void    resultis(int);
  305.            void    cancel(int);
  306.            void    setwho(object* t)       { t_alert = t; }
  307.            void    print(int, int =0);
  308.            object* who_alerted_me()        { return t_alert; }
  309.    public:
  310.            // Added to support Exception handling on the IBM RS/6000
  311.            // and the OS/2.
  312.            void *__currentException;
  313.    };
  314.    // for compatibility
  315.    #define task_chain (task::get_task_chain())
  316.  
  317.    // an Interrupt_handler supplies an interrupt routine that runs when the
  318.    // interrupt occurs (real time).  Also the Interrupt_handler can be waited for.
  319.    class Interrupt_handler : public object {
  320.    friend  class Interrupt_alerter;
  321.    friend SIG_FUNC_TYP sigFunc;
  322.            int     id;             // signal or interrupt number
  323.            int     got_interrupt;  // an interrupt has been received
  324.                                    // but not alerted
  325.            Interrupt_handler       *old;   // previous handler for this signal
  326.            virtual void    interrupt();    // runs at real time
  327.    public:
  328.                    Interrupt_handler(int sig_num);
  329.                    ~Interrupt_handler();
  330.            object::objtype o_type()        { return INTHANDLER; }
  331.            int     pending();      // FALSE once after interrupt
  332.            void    print(int, int =0);    // VERBOSE or 0
  333.    };
  334.  
  335.  
  336.    /* QUEUE MANIPULATION (see queue.c) */
  337.    /*
  338.            qhead <--> oqueue <--> qtail   (qhead, qtail independent)
  339.            oqueue ->> circular queue of objects
  340.    */
  341.  
  342.    /* qh_modes */
  343.    enum qmodetype { EMODE, WMODE, ZMODE };
  344.  
  345.    class oqueue
  346.    {
  347.    friend class qhead;
  348.    friend class qtail;
  349.            int     q_max;
  350.            int     q_count;
  351.            object* q_ptr;
  352.            qhead*  q_head;
  353.            qtail*  q_tail;
  354.  
  355.                    oqueue(int m)   { q_max=m; q_count=0; q_head=0; q_tail=0; };
  356.                    ~oqueue()       { (q_count)?object::task_error(E_QDEL,0):0; };
  357.  
  358.            void    print(int);
  359.    };
  360.  
  361.    class qhead : public object
  362.    {
  363.    friend class qtail;
  364.            qmodetype       qh_mode;        /* EMODE,WMODE,ZMODE */
  365.            oqueue*         qh_queue;
  366.    public:
  367.                            qhead(qmodetype = WMODE, int = 10000);
  368.                            ~qhead();
  369.  
  370.            object::objtype         o_type()        { return QHEAD; }
  371.            object*         get();
  372.            int             putback(object*);
  373.  
  374.            int             rdcount()       { return qh_queue->q_count; }
  375.            int             rdmax()         { return qh_queue->q_max; }
  376.            qmodetype       rdmode()        { return qh_mode; }
  377.            qtail*          tail();
  378.  
  379.            qhead*          cut();
  380.            void            splice(qtail*);
  381.  
  382.            void            setmode(qmodetype m);
  383.            void            setmax(int m);
  384.            int             pending()       { return rdcount() == 0; }
  385.            void            print(int, int =0);
  386.    };
  387.  
  388.    class qtail : public object
  389.    {
  390.    friend class qhead;
  391.            qmodetype       qt_mode;
  392.            oqueue*         qt_queue;
  393.    public:
  394.                            qtail(qmodetype = WMODE, int = 10000);
  395.                            ~qtail();
  396.  
  397.            object::objtype         o_type()        { return QTAIL; }
  398.            int             put(object*);
  399.  
  400.            int             rdspace()
  401.                            { return qt_queue->q_max - qt_queue->q_count; };
  402.            int             rdmax()         { return qt_queue->q_max; };
  403.            qmodetype       rdmode()        { return qt_mode; };
  404.  
  405.            qtail*          cut();
  406.            void            splice(qhead*);
  407.  
  408.            qhead*          head();
  409.  
  410.            void            setmode(qmodetype m);
  411.            void            setmax(int m);
  412.            int             pending()       { return rdspace() <= 0; }
  413.  
  414.            void            print(int, int =0);
  415.    };
  416.  
  417.  
  418.    struct histogram
  419.    /*
  420.            "nbin" bins covering the range [l:r] uniformly
  421.            nbin*binsize == r-l
  422.    */
  423.    {
  424.            int     l, r;
  425.            int     binsize;
  426.            int     nbin;
  427.            int*    h;
  428.            long    sum;
  429.            long    sqsum;
  430.                    histogram(int=16, int=0, int=16);
  431.  
  432.            void    add(int);
  433.            void    print();
  434.    };
  435.  
  436.    /*      the result of randint() is always >= 0  */
  437.  
  438.    #define DRAW (randx = randx*1103515245 + 12345)
  439.    #define ABS(x)  (x&0x7fffffff)
  440.    #define MASK(x) ABS(x)
  441.  
  442.    class randint
  443.    /*      uniform distribution in the interval [0,MAXINT_AS_FLOAT] */
  444.    {
  445.            long    randx;
  446.    public:
  447.                    randint(long s = 0)     { randx=s; }
  448.            void    seed(long s)    { randx=s; }
  449.            int     draw()          { return MASK(DRAW); }
  450.            float   fdraw();
  451.    };
  452.  
  453.    class urand : public randint
  454.    /*      uniform distribution in the interval [low,high] */
  455.    {
  456.    public:
  457.            int     low, high;
  458.                    urand(int l, int h);
  459.            int     draw();
  460.    };
  461.  
  462.    class erand : public randint
  463.    /*      exponential distribution random number generator */
  464.    {
  465.    public:
  466.            int     mean;
  467.                    erand(int m) { mean=m; };
  468.            int     draw();
  469.    };
  470.  
  471.    // This task will alert Interrupt_handler objects.
  472.    class Interrupt_alerter : public task {
  473.    public:
  474.                    Interrupt_alerter();
  475.                    ~Interrupt_alerter();
  476.    };
  477.  
  478.    extern Interrupt_alerter        interrupt_alerter;
  479.  
  480.    #pragma pack()
  481.  
  482.    #pragma info( none )
  483.    #ifndef __CHKHDR__
  484.       #pragma info( restore )
  485.    #endif
  486.    #pragma info( restore )
  487.  
  488. #endif
  489.