Annotation of researchv10no/cmd/cfront/libC/task/task.h, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.