/*static char *SCCSID = "@(#)timapi.h	6.2 91/06/05";*/
/***  TIMAPI.H
 *
 * SCCSID = @(#)timapi.h	6.2 91/06/05
 *
 * IBM/Microsoft Confidential
 *
 * Copyright (c) IBM Corporation 1987, 1989
 * Copyright (c) Microsoft Corporation 1987, 1989
 *
 * All Rights Reserved
 *
 * Title:
 *
 * Timer Dos APIs defines
 *
 */

/*** Timer Handle Defines  ***/

typedef USHORT HTIMER;      // Timer Handle
typedef HTIMER *PHTIMER;       // Pointer to timer handle

/*** Time out elemrnts typedefs ***/

typedef toe_t  TOE;
typedef TOE *PTOE;


/*** Timer Structure
 *
 *   This structure is used for arming a timer with TOM. At the time
 *   the user program makes a timer request such a structure is allocated
 *   and initialized. On arming this structure is placed on a list in the
 *   PTDA to keep track of all the active timers in a process. The following
 *   structrure is defined in TKEXPORT.H as PTDA also requires a reference
 *   to it. Here is what this structure looks like.
 *
 *   struct dostimer_s {
   toe_t       tmr_tom; // Time out manager's space
   ulong_t     *tmr_hsem;  // Semaphore handle passed to APIs
   ulong_t     tmr_mstime; // timer interval in millisecond
   struct ptda_s     *tmr_pptda; // owner PTDA
   ushort_t    tmr_htimer; // timer handle
   char        tmr_pad[2]; // dword align
   ulong_t     tmr_fl;  // Timer attributes (see fltype defines)
   struct dostimer_s  *tmr_prev; // prev timer on list (NULL if first)
   struct dostimer_s  *tmr_next; // next timer on list (NULL if last)
   struct dostimer_s  *tmr_fired;   // next element on fired list
 *   };
 *

/***  Timer flag defines
 *
 * TMR_EXPIRED/SLEEPING requires some explanation. TOM calls the timer
 * service routine TIMTomClear at interrupt time when a timer
 * expires. TIMTomClear hooks a context hook to delay semaphore
 * clearing process till thread's task time. This delay is required
 * because 32 bit semaphores can not be cleared at interrupt time.
 * Due to this delay it is possible that another thread (same pid)
 * issues a DOSTimerStop. This will lead to undesired result when
 * context hook comes to clear the semaphore. To avoid this
 * TIMTomClear marks a flag saying that the timer is expired. There
 * is no race condition possible as this is being done at interrupt
 * time. Now the other thread which wanted to issue DosTimerStop
 * will find that timer is already fired so it will go to sleep with
 * marking the flag as TMR_SLEEPING. The context hokk will clear
 * the semaphore later and wakeup this sleeping thread.
 */

#define TMR_ONESHOT  0x01      // Timer is to be armed for once
#define TMR_OLDSEM   0x02      // Semaphore passes with timer is old v1.*
#define TMR_EXPIRED  0x04      // expiration notification
#define TMR_UNLINKING   0x08      // Timer has been unlinked by a stop call
#define TMR_HIRES 0x10         // Indicates a hi resolution timer.  Needed
                               // when resetting periodic timer


#define TMR_MINDEFAULT  10     // minimum timers in the system

#define TMR_GET   0
#define TMR_FREE  1
/*** Timer assertions    ***/

#ifdef   MISCSTRICT
#define TIMASSERT(e) _assert(e)
#else
#define TIMASSERT(e)
#endif

/*** function prototypes */

extern ulong_t TIMInit         (void);
extern void    TIMtomTomClear  (PTOE);
extern ulong_t pascal near TIMSEMHANDLE    (ulong_t *,ulong_t);
extern void    pascal near TIMSEMCLEAR    (ulong_t *);
extern ulong_t pascal near TIMGSETHTIMER   (ulong_t,ulong_t);
extern void    TimProcTerminate(PPTDA);

int _cdecl      VR32StartTimer  (THUNKSEF,ulong_t,ulong_t *,PHTIMER);
int _cdecl      VR32StopTimer   (THUNKSEF,HTIMER);
int _cdecl      VR32AsyncTimer  (THUNKSEF,ulong_t,ulong_t *,PHTIMER);
int _cdecl      VR32IStartTimer (THUNKSEF,ulong_t,ulong_t *,PHTIMER);
int _cdecl      VR32IAsyncTimer (THUNKSEF,ulong_t,ulong_t *,PHTIMER);
ulong_t        timArmTimer     (ulong_t,ulong_t *,PHTIMER,ulong_t);
ulong_t        timDisarmTimer  (HTIMER);
void         timLinkTimer    (dostimer_t *);
ulong_t        timQueryTimer   (HTIMER,PPTDA,dostimer_t **);
void         timUnlinkTimer  (dostimer_t *);
void pascal near
          timContextHook  (void *, void *);
