- /* Initialize the counters */
- *Time100nsPtr = 0;
- *IdleCountPtr = 0;
- /* We should only have one object, but write general code just in case. */
- PerfObj = FirstObject( cygwin_load.PerfData );
- for( i = 0; i < cygwin_load.PerfData->NumObjectTypes; i++ ) {
- /* We are only interested in the processor object */
- if ( PerfObj->ObjectNameTitleIndex == PROCESSOR_OBJECT_INDEX) {
- /* Possibly verify it is really the Processor object. */
- if ((cygwin_load.NamesArray != NULL) &&
- (strcmp(cygwin_load.NamesArray[PerfObj->ObjectNameTitleIndex],
- PROCESSOR_OBJECT_NAME))) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "Incorrect Perf object name %s",
- cygwin_load.NamesArray[PerfObj->ObjectNameTitleIndex]);
- return FALSE;
- }
- /* Get the first counter */
- PerfCntr = FirstCounter( PerfObj );
- /* See if the object has instances.
- It should, but write general code. */
- if( PerfObj->NumInstances != PERF_NO_INSTANCES ) {
- PerfInst = FirstInstance( PerfObj );
- for( k = 0; k < PerfObj->NumInstances; k++ ) {
- /* There can be several processors.
- Accumulate both the Time100ns and the idle counter.
- On Win 2000 I have seen an instance named "_Total".
- Do not use it. We only use instances with a single
- character in the name.
- If we examine the object names, we also look at the instance
- names and their lengths and issue reports */
- if ( cygwin_load.NamesArray != NULL) {
- CHAR ascii[30]; /* The name is in unicode */
- wsprintf(ascii,"%.29lS",
- (char *)((PBYTE)PerfInst + PerfInst->NameOffset));
- log_write(0, LOG_MAIN,
- "Perf: Found processor instance \"%s\", length %d",
- ascii, PerfInst->NameLength);
- if ((PerfInst->NameLength != 4) &&
- (strcmp(ascii, "_Total") != 0)) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "Perf: WARNING: Unexpected processor instance name");
- return FALSE;
- }
- }
- if (PerfInst->NameLength == 4) {
- *Time100nsPtr += cygwin_load.PerfData->PerfTime100nSec.QuadPart;
- PtrToCntr = InstanceCounterBlock(PerfInst);
- if (! ReadTimeCtr(PerfObj, PerfCntr, PtrToCntr, IdleCountPtr)) {
- return FALSE;
- }
- }
- PerfInst = NextInstance( PerfInst );
- }
- return (*Time100nsPtr != 0); /* Something was read */
- }
- else { /* No instance, just the counter data */
- *Time100nsPtr = cygwin_load.PerfData->PerfTime100nSec.QuadPart;
- PtrToCntr = ObjectCounterBlock(PerfObj);
- return ReadTimeCtr(PerfObj, PerfCntr, PtrToCntr, IdleCountPtr);
- }
+ else if (!(spt = (PSYSTEM_PROCESSOR_TIMES) alloca(sizeof(spt[0]) * sbi.NumberProcessors))) {
+ DEBUG(D_load)
+ debug_printf("Perf: alloca: errno %d (%s)\n", errno, strerror(errno));
+ }
+ else if ((ret = NtQuerySystemInformation(SystemProcessorTimes, (PVOID) spt,
+ sizeof spt[0] * sbi.NumberProcessors, NULL))
+ != STATUS_SUCCESS) {
+ DEBUG(D_load)
+ debug_printf("Perf: NtQuerySystemInformation: %u (Windows)\n",
+ RtlNtStatusToDosError(ret));
+ }
+ else {
+ int i;
+ for (i = 0; i < sbi.NumberProcessors; i++) {
+ *Time100nsPtr += spt[i].KernelTime.QuadPart;;
+ *Time100nsPtr += spt[i].UserTime.QuadPart;
+ *IdleCountPtr += spt[i].IdleTime.QuadPart;