Annotation of researchv10no/cmd/cfront/libC/otask/task.h, revision 1.1.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.