Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

367 lines
13 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. rt.h
  5. Abstract:
  6. This is the public include file for realtime executive (rt.sys) clients.
  7. Author:
  8. Joseph Ballantyne
  9. Environment:
  10. Kernel Mode
  11. Revision History:
  12. --*/
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. // The following values can be ORed together and the result passed as the Flags argument
  17. // to the RtCreateThread and RtAdjustCpuLoad routines.
  18. #define CPUCYCLES 0x10000
  19. #define INSTRUCTIONS 0x20000
  20. #define USESFLOAT 0x00001
  21. #define USESMMX 0x00002
  22. // These should be used when calculating the desired period and duration to be
  23. // passed to RtCreateThread and RtAdjustCpuLoad.
  24. #define WEEK 604800000000000000I64
  25. #define DAY 86400000000000000I64
  26. #define HOUR 3600000000000000I64
  27. #define MIN 60000000000000I64
  28. #define SEC 1000000000000I64
  29. #define MSEC 1000000000I64
  30. #define USEC 1000000I64
  31. #define NSEC 1000I64
  32. #define PSEC 1I64
  33. #define X86 1
  34. #define INTEL 1
  35. #define AMD 2
  36. typedef struct {
  37. ULONG ProcessorCount; // Number of CPUs in the system.
  38. ULONG CpuArchitecture; // Architecture of CPU, currently always X86==1
  39. ULONG CpuManufacturer; // Manufacturer ID, Intel==1, AMD==2
  40. ULONG CpuFamily; // CPU Family as reported by cpuid instruction. 0x0-0xf
  41. ULONG CpuModel; // CPU Model as reported by cpuid instruction. 0x0-0xf
  42. ULONG CpuStepping; // CPU Stepping as reported by cpuid instruction. 0x0-0xf
  43. ULONGLONG CpuFeatures; // CPU features as reported by cpuid instruction.
  44. ULONGLONG CpuExtendedFeatures; // AMD extended features. (Not implemented.) Always 0.
  45. ULONGLONG ProcessorID[2]; // Processor Unique ID. If enabled.
  46. ULONG CpuCyclesPerMsec; // Number of cpu cycles per MSEC.
  47. ULONG SystemBusCyclesPerMsec; // Number of system bus cycles per MSEC.
  48. ULONG ReservedCpuPerMsec; // Total cpu time reserved per ms by existing rt threads. (in picoseconds)
  49. ULONG UsedCpuPerMsec; // Estimate of cpu time used per ms by existing rt threads. (in picoseconds)
  50. ULONG AvailableCpuPerMsec; // Cpu time available per ms for allocation to new rt threads. (in picoseconds)
  51. } SystemInfo;
  52. // The following realtime thread statistics are updated just before control is
  53. // passed by the realtime executive to the realtime thread. Everytime a realtime
  54. // thread is being switched in, these statistics are updated before control is transfered.
  55. // This means the statistics will change over time, but not while a realtime
  56. // thread is running between thread switches.
  57. #pragma pack(push,2)
  58. typedef struct threadstats {
  59. ULONGLONG Period; // Period as passed to RtCreateThread or latest RtAdjustCpuLoad call.
  60. ULONGLONG Duration; // Duration from RtCreateThread or latest RtAdjustCpuLoad call.
  61. ULONG Flags; // Flags from RtCreateThread or latest RtAdjustCpuLoad call.
  62. ULONG StackSize; // StackSize from RtCreateThread call.
  63. ULONGLONG PeriodIndex; // Number of periods since start of thread.
  64. ULONGLONG TimesliceIndex; // Number of times thread has been switched to.
  65. ULONGLONG TimesliceIndexThisPeriod; // Number of times thread switch to this period.
  66. ULONGLONG ThisPeriodStartTime; // Starting time for current period.
  67. ULONGLONG ThisTimesliceStartTime; // Starting time for current timeslice.
  68. ULONGLONG DurationRunThisPeriod; // Total time run so far this period.
  69. ULONGLONG DurationRunLastPeriod; // Total time run in the last period.
  70. } ThreadStats;
  71. #pragma pack(pop)
  72. typedef VOID (*RTTHREADPROC)(PVOID Context, ThreadStats *Statistics);
  73. NTSTATUS
  74. RtVersion (
  75. OUT PULONG Version
  76. );
  77. // RtVersion will return the version number of the currently running
  78. // realtime executive.
  79. // If the realtime executive is running, this function returns
  80. // STATUS_SUCCESS. If for some reason the realtime executive
  81. // cannot run on the current machine then STATUS_NOT_SUPPORTED
  82. // is returned.
  83. // Currently the realtime executive will only run on PII class or newer
  84. // machines.
  85. // If the pointer to the version number is non NULL, then the
  86. // version information for the currently loaded realtime executive
  87. // is returned. The version information will be returned regardless
  88. // of the NTSTATUS code returned by the function.
  89. // The version number returned is in the format xx.xx.xx.xx where each
  90. // xx is 1 byte of the ULONG and the ordering left to right is high
  91. // order byte - > low order byte. ie: 0x01020304 is version 1.2.3.4
  92. // It IS acceptable to pass in a NULL version pointer. In that case
  93. // no version information is returned.
  94. // If this function is called from a real time thread, then the version
  95. // pointer MUST either be NULL, or it MUST point to a local variable on
  96. // that real time thread's stack. Otherwise this function will return
  97. // STATUS_INVALID_PARAMETER.
  98. // If this function is called from Windows, then the pointer must be
  99. // valid for writing. Otherwise it will return STATUS_INVALID_PARAMETER.
  100. // This function may be called from any thread. Windows or realtime.
  101. BOOLEAN
  102. RtThread (
  103. VOID
  104. );
  105. // RtThread returns TRUE if called from within a realtime thread. Otherwise
  106. // it returns FALSE.
  107. NTSTATUS
  108. RtSystemInfo (
  109. ULONG Processor,
  110. SystemInfo *pSystemInfo
  111. );
  112. // RtSystemInfo copies the pertinant processor and system information into the memory
  113. // pointed to by pSystemInfo. If pSystemInfo is null or invalid, then RtSystemInfo
  114. // returns STATUS_INVALID_PARAMETER_2. Otherwise RtSystemInfo will return STATUS_SUCCESS.
  115. // For uniprocessor systems, the Processor number should be zero. For N processor
  116. // systems, the processor numbers range from 0 to N-1. An invalid processor number
  117. // will cause a STATUS_INVALID_PARAMETER_1 to be returned.
  118. NTSTATUS
  119. RtCreateThread (
  120. ULONGLONG Period,
  121. ULONGLONG Duration,
  122. ULONG Flags,
  123. ULONG StackSize,
  124. RTTHREADPROC RtThread,
  125. IN PVOID pRtThreadContext,
  126. OUT PHANDLE pRtThreadHandle
  127. );
  128. // RtCreateThread is used to create a realtime thread.
  129. // Period is the used to determine the frequency at which the realtime thread must be
  130. // run. The current minimum period that can be specified is 1ms.
  131. // Duration is the amount of time within the period that the realtime thread will
  132. // need to run. Percentage CPU load can be calculated as 100*(Duration/Period) as long
  133. // as Duration and Period are both specified in units of time.
  134. // Flags
  135. // This parameter is used to indicate specific requirements of the realtime thread
  136. // being created. Currently supported values for Flags are USESFLOAT and USESMMX.
  137. // A realtime thread that can use floating point instructions must specify the
  138. // USESFLOAT flag. A realtime thread that can use MMX instructions must specify the
  139. // USESMMX flag.
  140. // StackSize is the size of the stack required by the realtime thread in 4k blocks.
  141. // Currently StackSize must be between 1 and 8 inclusive. RtCreateThread will fail
  142. // with STATUS_UNSUCCESSFUL for any other values of StackSize.
  143. // pRtThreadContext is a pointer to the context that should be passed to the thread.
  144. // It may be NULL. It is passed to the realtime thread as the Context parameter.
  145. // pRtThreadHandle is a pointer to an RtThreadHandle that can be output from
  146. // RtCreateThread. pRtThreadHandle can be NULL, in which case no RtThreadHandle is
  147. // returned. Storage for the HANDLE RtThreadHandle must be allocated by the code
  148. // that calls RtCreateThread.
  149. // RtCreateThread may only be called from within a standard windows thread. It MUST NOT
  150. // be called from within a realtime thread.
  151. NTSTATUS
  152. RtDestroyThread (
  153. HANDLE RtThreadHandle
  154. );
  155. // RtDestroyThread removes the realtime thread identified by RtThreadHandle from the
  156. // list of running realtime threads, and releases all resources that were allocated when
  157. // the thread was created. RtThreadHandle must be a handle returned from RtCreateThread.
  158. // RtDestroyThread may only be called from within a standard windows thread. It MUST NOT
  159. // be called from within a realtime thread.
  160. NTSTATUS
  161. RtAdjustCpuLoad (
  162. ULONGLONG Period,
  163. ULONGLONG Duration,
  164. ULONGLONG Phase,
  165. ULONG Flags
  166. );
  167. // This function allows a realtime thread to adjust the amount of CPU that is allocated
  168. // to it. The Flags parameter must currently match that passed in at thread creation
  169. // time, however, the Period and Duration may be different from the Period and Duration
  170. // passed at thread create time. If there is sufficient CPU to meet the new request,
  171. // the function will return STATUS_SUCCESS and the Period and Duration in the thread's
  172. // statistics will be updated to match the values passed in to this function. If
  173. // there is not enough CPU available to meet the request, this function will leave
  174. // the Period and Duration recorded in Statistics unchanged and will return
  175. // STATUS_INSUFFICIENT_RESOURCES.
  176. // This function MUST be called from within a realtime thread. A realtime thread can
  177. // only change its OWN allocation. It cannot change the allocation of any other
  178. // realtime thread.
  179. VOID
  180. RtYield (
  181. ULONGLONG Mark,
  182. ULONGLONG Delta
  183. );
  184. // RtYield will yield execution to other realtime threads in the system.
  185. // It should be called whenever a realtime thread does not require further CPU resources.
  186. // Parameters:
  187. // Mark
  188. // This is the reference time which will be subtracted from the current
  189. // realtime executive scheduler time. Note that this time is ALWAYS
  190. // considered by the scheduler to be in the past. Do NOT pass a time
  191. // which occurs in the future to this parameter.
  192. // Delta
  193. // This is the time that will be compared to the difference between the current
  194. // scheduler time and the mark. The thread will yield execution until
  195. // the difference between the current scheduler time and the mark is greater
  196. // than delta.
  197. // After a thread has called RtYield it will only be run when the following
  198. // code evaluates TRUE. ( (RtTime() - Mark) >= Delta ) Until that occurs
  199. // the thread will NOT run. Unless it is holding a spinlock required by
  200. // some other realtime thread - in which case it will run until it releases
  201. // the spinlock at which point it will again yield.
  202. PVOID
  203. RtAddLogEntry (
  204. ULONG Size
  205. );
  206. // RtAddLogEntry reserves space for a new entry in the realtime logging buffer.
  207. // It returns a pointer to the reserved space. Note that if an unsupported Size
  208. // is specified, or if there is no realtime logging buffer available on the
  209. // system, this routine will return NULL.
  210. // Parameters:
  211. // Size
  212. // This is the size in bytes of the chunk to reserve in the log. It MUST be
  213. // an integral multiple of 16.
  214. // The following standard WDM functions are also safe to call from within a real time
  215. // thread: KeAcquireSpinLock and KeReleaseSpinLock.
  216. // They have been modified to support realtime threads in the following ways:
  217. // KeAcquireSpinLock
  218. // KeAcquireSpinLock will now always attempt to take the spinlock regardless of whether it
  219. // is running on a multiproc or uniproc machine. If the spinlock is already acquired,
  220. // then KeAcquireSpinLock will spin in a loop that calls RtYield(THISTIMESLICE) until
  221. // the spinlock is released.
  222. // It will then claim the spinlock. This means that realtime threads that attempt to
  223. // acquire a held spinlock will BLOCK until the spinlock is free. If you don't HAVE to use
  224. // spinlocks in your realtime threads, DON'T.
  225. // Note that other realtime threads will continue to run as scheduled, but the thread
  226. // waiting for the spinlock will continue yielding all its timeslices until the spinlock
  227. // is released.
  228. // If KeAcquireSpinLock is called from a realtime thread, then it will NOT attempt to
  229. // change any irql levels. This is important, since the current Windows IRQL level may
  230. // be at higher than DISPATCH_LEVEL when this function is called. Furthermore, the OldIrql
  231. // returned by this function when it is called from a realtime thread is always 0xff -
  232. // which is an INVALID irql level.
  233. // If you call KeAcquireSpinLock from a realtime thread you MUST call KeReleaseSpinLock
  234. // for that spinlock from a realtime thread.
  235. // Evenutally, KeAcquireSpinLock will be modified to do an RtDirectedYield to the realtime
  236. // thread that is holding the spinlock.
  237. // KeAcquireSpinLock may be called from within any thread. Realtime or windows.
  238. // KeReleaseSpinLock
  239. // KeReleaseSpinLock now always attempts to release a held spinlock regardless of whether
  240. // it is running on a multiproc or uniproc machine.
  241. // If KeReleaseSpinLock is called from a realtime thread, then it will NOT change any irql
  242. // levels. It will also validate that it has been called with a new irql level of 0xff
  243. // as would have been returned by the KeAcquireSpinLock call in the realtime thread to
  244. // acquire the spinlock.
  245. // At some point KeReleaseSpinLock may do an RtDirectedYield back to the realtime thread
  246. // that yielded when it attempted to acquire the spinlock.
  247. // KeReleaseSpinLock may be called from within any thread. Realtime or windows.
  248. #ifdef __cplusplus
  249. }
  250. #endif