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

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

unix.superglobalmegacorp.com

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