/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* bos72Q src/bos/kernel/sys/timer.h 1.33.1.2 */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* COPYRIGHT International Business Machines Corp. 1988,2019 */ /* All Rights Reserved */ /* */ /* US Government Users Restricted Rights - Use, duplication or */ /* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /* */ /* IBM_PROLOG_END_TAG */ /* @(#)83 1.33.1.2 src/bos/kernel/sys/timer.h, sysproc, bos72Q, q2019_13A4 2/6/19 00:40:37 */ /* * COMPONENT_NAME: SYSPROC * * FUNCTIONS: TIMERID_ISBSD * TIMERID_NOTVALID * * * ORIGINS: 27,83 * * * (C) COPYRIGHT International Business Machines Corp. 1988,1995 * All Rights Reserved * Licensed Materials - Property of IBM * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ #ifndef _H_TIMER #define _H_TIMER /* * TIMER MANAGEMENT DESIGN: * * Each process may make use of up to m timers where m is equal to 1 * timer for the alarm() functionality (AT&T and POSIX alarm(), BSD * ITIMER_REAL) plus 1 Berkeley user virtual timer (BSD ITIMER_VIRTUAL) * plus 1 Berkeley user and system virtual timer (BSD ITIMER_PROF) * plus n POSIX 1003.4 realtime timer(s) (POSIX TIMEOFDAY). The * u-block contains an array of pointers to timers, one for each of * the m timers a process may have. The pointer corresponding to each * timer remains NULL until allocation of that timer (via a call to * gettimerid()) causes the corresponding pointer to be initialized. * * Indices into a process's array of timers are hard-coded. This * means that for all processes, the first element in the process's * timer array, for example, will serve as the timer slot for, say, * that process's ITIMER_REAL type timer. * * The system maintains a system-wide list of active timer requests. * This is an ordered, doubly-linked, null-terminated list of timer * requests (trb structures) which have been submitted by all * processes, device drivers, etc. and have not yet expired. Any * per-process timer which is active will be on this system-wide * active list until that timer expires. * * When a timeout request expires, it is processed on the timer inter- * rupt level. For this reason, all per-process timers must be pinned. * * At each clock interrupt, the clock timeout routine determines if * there are ITIMER_VIRTUAL and/or ITIMER_PROF timers active for the * current process. If so, those timers are updated appropriately. * Since this occurs on the timer interrupt level, these trb's must * also be pinned. * * * u.u_timer___________________ *________>| |___> \ * | struct trb | . \ per process timers (pinned) * | *trb[NTIMERS] | . / * |___________________|\_____ / * | * | * | * _________________________________| * | * | * | * | struct trb * | _____________________ * |______>| | * | struct trb | \ * | *knext | \ * |_____________________| \ threads through the system active trb * | | / list (doubly linked, null terminated) * | struct trb | / * | *kprev | / * |_____________________| * | | process which owns the trb (valid for * | pid_t | process timer services, not valid for * | pid | device driver trb's) * |_____________________| * | | * | ulong | state of the trb * | flags | * |_____________________| * | | * | ulong | user's timer id number * | timerid | * |_____________________| * | | * | int | * | eventlist | * |_____________________| * | | .it_interval timestruc_t * | |_______________ time between timeouts * | struct itimerstruc_t| for priodic timers * | timeout | * | | .it_value timestruc_t * | |_______________ absolute time value of * |_____________________| next timeout * | | * | | * | void | * | (*func)() | timeout function to be called * |_____________________| * | | * | {ulong, | * | int, | * | caddr_t} | * | func_data | parameter to the timeout function * |_____________________| * | | * | int | interrupt priority level on which to * | ipri | call timeout function * |_____________________| * | | * | void * | timeout function * | tof() | * |_____________________| * * */ #include #include #include #ifdef __cplusplus extern "C" { #endif #define T_TIMEOUT 0xABABABAB /* timeout/untimeout trb */ /* * Flags for the timer request block (trb) */ #define T_PENDING 0x001 /* timer is on the system list */ #define T_ACTIVE 0x002 /* timer is in use */ #define T_ABSOLUTE 0x004 /* timeout is an absolute value */ #define T_INCINTERVAL 0x010 /* timer is an incinterval one */ #define T_COMPLETE 0x020 /* timeout occurred and trb has */ /* been taken off active list */ #define T_MPSAFE 0x040 /* used from mp safe driver */ #define T_LOWRES 0x080 /* timer can be rounded to next */ /* clock tick */ #define T_PAUSED 0x100 /* timer temporarily paused */ /* (for checkpoint or restart) */ #define T_MOVE_OK 0x200 /* timer can move cpus */ #define T_LATE_OK 0x400 /* timer can be late */ struct trb { struct trb *to_next; /* for the timeout() routines */ struct trb *knext; /* next timer in kernel chain */ struct trb *kprev; /* previous timer in kern. chain*/ ulong id; /* owner process, dev drvrs = -1*/ volatile cpu_t cpunum; /* owning processor */ unsigned short flags; /* operation flags */ ulong timerid; /* timer identifier */ tid_t eventlist; /* anchor for awaited event */ struct itimerstruc_t timeout; /* timer request */ void (*func)(); /* completion handler */ union parmunion { /* data for completion handler */ ulong data; /* handler unsigned data */ int sdata; /* handler signed data */ caddr_t addr; /* handler address */ } t_union; int ipri; /* int. priority for func() */ void (*tof)(); /* timeout function */ }; #ifndef _LINUX_SOURCE_COMPAT #define func_data t_union.data #endif #define t_func_data t_union.data #define t_func_sdata t_union.sdata #define t_func_addr t_union.addr #define TIMERID_ISBSD(timerid) \ (((timerid) == ITIMER_VIRTUAL) || \ ((timerid) == ITIMER_VIRT) || \ ((timerid) == ITIMER_PROF)) #ifdef _KERNEL #define TIMERID_PROC(timerid) \ (((int)(timerid) >= 0) && \ ((int)(timerid) < NTIMERS) && \ (U.U_timer[timerid] != NULL)) #define TIMERID_THREAD(timerid) \ (((int)(timerid) >= TIMERID_REAL1) && \ ((int)(timerid) < TIMERID_REAL1 + NTIMERS_THREAD) && \ (u.u_th_timer[timerid - TIMERID_REAL1] != NULL)) #define TIMERID_NOTVALID(timerid) \ (!(TIMERID_PROC((timerid)) || TIMERID_THREAD((timerid)))) /* * Function prototypes for 64bit kernel only */ #if defined(__64BIT_KERNEL) || defined(__FULL_PROTO) extern struct trb *talloc(void); extern void tfree(struct trb *); extern void tstart(struct trb *); extern int tstop(struct trb *); extern int delay(int ticks); extern int resched(void); #else extern struct trb * talloc(); extern void tstart(); extern int tstop(); extern void tfree(); extern int delay(); #endif /* !(__64BIT_KERNEL || __FULL_PROTO) */ #endif /* _KERNEL */ /* * Structures used for POSIX Realtime timers. */ /* * Each process may make use of up to _POSIX_TIMER_MAX POSIX timers. * Each created timers is based on one of the POSIX clocks : * CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID or * CLOCK_THREAD_CPUTIME_ID. * * Characteristics of the timers are stored in posix_tmr structures. * * The proc struct contains an array of pointers to posix_tmr, one for each of * the _POSIX_TIMER_MAX timers a process may have. The pointer corresponding * to each timer remains NULL until allocation of that timer (via a call to * timer_create()) causes the corresponding pointer to be initialized. * * Indices into a process's array of timers represent the timer ID returned * by timer_create() and then used in the subsequent timer_*() calls. * * Active timer requests are handle differently depending on their clock. * * For timers based on realtime and monotonic clocks : * - The trb mechanism is used (see sys/timer.h) * - Timers based on monotonic clock are enqueued as relative * realtime timers. Thus, the trb mechanism can be used "as is" * to handle them. Setting the realtime clock has no effect on them * since they are relative timers. * * For timers based on process or thread cpu-time clocks : * - Structures representing cpu-time clocks are added to proc and thread * structures : struct cputime_clock. They accumulate the cpu ticks * consumed by the process (or thread) and keep track of their active * cpu-time timers in an ordered, doubly-linked, null-terminated list * of posix_tmr. * * - Some additional fields are added to posix_tmr to store data * needed to handle queueing, updates and expirations of active * cpu-time timers. They are grouped in a structure similar to a * compressed trb : struct cputime_tmr. * - When a cpu-time timer is armed, its posix_tmr struct is inserted in * the list of active timers of its reference clock. * * - At each sys-timer event, the sys_timer() routine : * - Increments the tick value of : * - the cpu-time clock of the current process * - the cpu-time clock of the current thread * - Determines if there are active cpu-time timers for these clocks. * If so, those timers are updated appropriately. * * When a timeout request expires, it is processed on the timer interrupt * level. For this reason, all posix_tmr structures must be pinned. */ /* * Structure used to store data related to active cpu-time timers. * (note: for realtime and monotonic timers, a trb is used). */ struct cputime_tmr { struct posix_tmr *next; /* next active timer in chain */ struct posix_tmr *prev; /* previous active timer in chain */ ulong id; /* owner */ timer_t timerid; /* timer identifier */ unsigned short flags; /* to mark if timer is absolute */ unsigned int value; /* expiration tick value */ unsigned int interval; /* repetitive interval tick value */ void (*func)(); /* completion handler */ caddr_t data; /* data for completion handler */ }; /* * Structure representing POSIX timers. */ struct posix_tmr { clockid_t tmr_clockid; /* clock used for the timer */ short tmr_active_overrun; /* active overrun count */ short tmr_prev_overrun; /* previous overrun count */ int tmr_notify; /* requested notification type */ union { /* one of: */ tid_t tid; /* . tid of the permanent thread that handles */ /* the user-specified notification */ void *sip; /* . address of the ksiginfo_t structure used */ /* in signal notification */ } tmr_notifunion; union { struct trb *trb; /* timer based on realtime or */ /* monotonic clock */ struct cputime_tmr cpu_tmr; /* timer based on process or */ /* thread cpu-time clock */ } tmr_union; }; #define tmr_tid tmr_notifunion.tid #define tmr_sip tmr_notifunion.sip #define tmr_trb tmr_union.trb #define tmr_cpu_tmr tmr_union.cpu_tmr /* * Structure representing a POSIX cpu-time clock. */ struct cputime_clock { uint_t rt_ticks; /* count the clock execution time */ /* units = ticks */ struct posix_tmr *active_tmrs; /* list of active cpu-time timers */ /* attached to that cpu-time clock*/ }; #define CPUTIME_GET 0 #define CPUTIME_SET 1 #define CPUTIME_RES 2 /* * Macros for clock IDs */ /* Returns type of the clock stored in the lower-order word of clockid_t */ #define CLOCKID_TYPE(_clockid) ((long long)(_clockid) & 0xFFFFFFFFLL) /* Returns instance of the clock stored in the high-order word of clockid_t */ #define CLOCKID_INSTANCE(_clockid) ((long long)(_clockid) >> 32LL) #ifdef __cplusplus } #endif #endif /* _H_TIMER */