Beispiel #1
0
int main(int argc,char *argv[],char *envp[]) {
	rdtsc_t start,measure,ticks_per_sec;
    unsigned char force = 0;
	double t;
	int c;

    {
        int i = 1;
        char *a;

        while (i < argc) {
            a = argv[i++];

            if (*a == '-') {
                do { a++; } while (*a == '-');

                if (!strcmp(a,"f") || !strcmp(a,"force"))
                    force = 1;
                else
                    return 1;
            }
            else {
                return 1;
            }
        }
    }

	cpu_probe();
	printf("Your CPU is basically a %s or higher\n",cpu_basic_level_to_string(cpu_basic_level));
	if (cpu_v86_active)
		printf(" - Your CPU is currently running me in virtual 8086 mode\n");

    if (force) {
        printf(" - You're forcing me to use RDTSC. I may crash if your CPU doesn't\n");
        printf("   support it or the environment doesn't enable it.\n");
        printf("   OK! Here we go....!\n");
    }
    else {
        if (!(cpu_flags & CPU_FLAG_CPUID)) {
            printf(" - Your CPU doesn't support CPUID, how can it support RDTSC?\n");
            return 1;
        }

        if (!(cpu_cpuid_features.a.raw[2] & 0x10)) {
            printf(" - Your CPU does not support RDTSC\n");
            return 1;
        }

        if (cpu_flags & CPU_FLAG_DONT_USE_RDTSC) {
            printf(" - Your CPU does support RDTSC but it's not recommended in this environment.\n");
            printf("   This is usually due to running a 16-bit build in pure DOS under EMM386.EXE.\n");
            return 1;
        }
    }

#if defined(TARGET_OS2)
# if TARGET_MSDOS == 32
	/* OS/2 32-bit: We can use DosQuerySysInfo() */
	printf("Measuring CPU speed, using DosQuerySysInfo(), over 3 seconds\n");
	{
		ULONG startTick,tmp;
		start = cpu_rdtsc();
		startTick = GetMsCount();
		do { tmp = GetMsCount();
		} while ((tmp - startTick) < 3000); /* NTS: <- I know this rolls over in 49 days,
		the math though should overflow the 32-bit integer and produce correct results anyway */
		measure = cpu_rdtsc();

		/* use the precise tick count to better compute ticks_per_sec */
		ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
		printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
		printf("             From 0x%llX to 0x%llX\n",start,measure);
	}
# else
	/* OS/2 16-bit: There is no API (that I know of) to get tick count. Use system clock. */
	printf("Measuring CPU speed, using system clock with 1-second resolution, across 3 seconds\n");
	{
		time_t startTick,tmp;

		/* wait for the immediate start of a one-second tick, then record RDTSC and count until 3 seconds */
		startTick = time(NULL);
		do { tmp = time(NULL); } while (tmp == startTick);
		start = cpu_rdtsc(); startTick = tmp;

		/* NOW! Count 3 seconds and measure CPU ticks */
		do { tmp = time(NULL);
		} while ((tmp - startTick) < 3);
		measure = cpu_rdtsc();

		/* use the precise tick count to better compute ticks_per_sec */
		ticks_per_sec = ((measure - start) * 1ULL) / ((rdtsc_t)(tmp - startTick));
		printf("Measurement: %lu seconds = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
		printf("             From 0x%llX to 0x%llX\n",start,measure);
	}
# endif
#elif defined(TARGET_WINDOWS)
# if TARGET_MSDOS == 16
	/* Windows 2.x/3.0/3.1: Use GetTickCount() or
	 * Windows 3.1: Use TOOLHELP.DLL TimerCount() which is more accurate (really?) */
	if (ToolHelpInit()) {
		TIMERINFO ti;

		ti.dwSize = sizeof(ti);
		printf("Measuring CPU speed, using TOOLHELP TimerCount() over 1 second\n");
		{
			DWORD startTick,tmp;
			start = cpu_rdtsc();
			if (!__TimerCount(&ti)) {
				printf("TimerCount() failed\n");
				return 1;
			}
			startTick = ti.dwmsSinceStart;
			do {
#  if defined(WIN_STDOUT_CONSOLE)
				_win_pump(); /* <- you MUST call this. The message pump must run, or else the timer won't advance and this loop will run forever.
			                           The fact that GetTickCount() depends on a working message pump under Windows 3.1 seems to be a rather serious
						   oversight on Microsoft's part. Note that the problem described here does not apply to Windows 9x/ME. Also note
						   the Toolhelp function TimerCount() relies on GetTickCount() as a basic for time (though Toolhelp uses VxD services
						   or direct I/O port hackery to refine the timer count) */
#  endif

				if (!__TimerCount(&ti)) {
					printf("TimerCount() failed\n");
					return 1;
				}

				tmp = ti.dwmsSinceStart;
			} while ((tmp - startTick) < 1000); /* NTS: <- I know this rolls over in 49 days,
			the math though should overflow the 32-bit integer and produce correct results anyway */
			measure = cpu_rdtsc();

			/* use the precise tick count to better compute ticks_per_sec */
			ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
			printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
			printf("             From 0x%llX to 0x%llX\n",start,measure);
		}
	}
	else {
# else
	{
# endif
		printf("Measuring CPU speed, using GetTickCount() over 3 second\n");
		{
			DWORD startTick,tmp;
			start = cpu_rdtsc();
			startTick = GetTickCount();
			/* NTS: Dunno yet about Windows 3.1, but Windows 95 seems to require we Yield(). If we don't, the GetTickCount() return
			 *      value never updates and we're forever stuck in a loop. */
			do {
#  if defined(WIN_STDOUT_CONSOLE)
				_win_pump(); /* <- you MUST call this. The message pump must run, or else the timer won't advance and this loop will run forever.
			                           The fact that GetTickCount() depends on a working message pump under Windows 3.1 seems to be a rather serious
						   oversight on Microsoft's part. Note that the problem described here does not apply to Windows 9x/ME */
#  endif
				tmp = GetTickCount();
			} while ((tmp - startTick) < 3000); /* NTS: <- I know this rolls over in 49 days,
			the math though should overflow the 32-bit integer and produce correct results anyway */
			measure = cpu_rdtsc();

			/* use the precise tick count to better compute ticks_per_sec */
			ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
			printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
			printf("             From 0x%llX to 0x%llX\n",start,measure);
		}
	}
#else
	/* MS-DOS: Init the 8254 timer library for precise measurement */
	if (!probe_8254()) {
		printf("Cannot init 8254 timer\n");
		return 1;
	}

    /* DOSBox-X and most motherboards leave the PIT in a mode that counts down by 2.
     * Our code sets the counter and puts it in a mode that counts down by 1.
     * We have to do this or our wait functions exit in half the time (which explains
     * why testing this code in DOSBox-X often comes up with RDTSC running at 2x
     * normal speed. */
    write_8254_system_timer(0); /* 18.2 tick/sec on our terms (proper PIT mode) */

	printf("Measuring CPU speed (relative to 8254 timer)\n");

	_cli();
	start = cpu_rdtsc();
	t8254_wait(t8254_us2ticks(1000000));
	measure = cpu_rdtsc();
	_sti();

	printf("Measurement: 1 sec = %lld ticks\n",(int64_t)(measure - start));
	printf("             From 0x%llX to 0x%llX\n",start,measure);
	ticks_per_sec = (measure - start);
#endif

	if ((int64_t)ticks_per_sec < 0) {
		printf("Cannot determine CPU cycle count\n");
		ticks_per_sec = 100000ULL;
	}

	while (1) {
		measure = cpu_rdtsc();
		t = (double)((int64_t)(measure - start));
		t /= ticks_per_sec;

		printf("\x0D" "0x%llX = %.3f   ",measure,t);
#if !defined(WINFCON_STOCK_WIN_MAIN)
		fflush(stdout); /* FIXME: The fake console code should intercept fflush() too */
#endif

		if (kbhit()) {
			c = getch();
			if (c == 0) c = getch() << 8;

			if (c == 27)
				break;
			else if (c == 'r' || c == 'R') {
				if (c == 'r' || (cpu_flags & CPU_FLAG_DONT_WRITE_RDTSC)) {
					printf("\nI am not able to write the TSC register within this environment\nYou can force me by typing SHIFT+R, don't blame me when I crash...\n");
				}
				else {
					printf("\nUsing MSR to reset TSC to 0\n");
					/* demonstrating WRMSR to write the TSC (yes, you can!) */
					cpu_rdtsc_write(start = 0ULL);
					printf("Result: 0x%llX\n",cpu_rdtsc());
				}
			}
			else if (c == 's') {
				if (c == 's' && (cpu_flags & CPU_FLAG_DONT_WRITE_RDTSC)) {
					printf("\nI am not able to write the TSC register within this environment\nYou can force me by typing SHIFT+S, don't blame me when I crash...\n");
				}
				else {
					printf("\nUsing MSR to reset TSC to 0x123456789ABCDEF\n");
					/* demonstrating WRMSR to write the TSC (yes, you can!) */
					cpu_rdtsc_write(start = 0x123456789ABCDEFULL);
					printf("Result: 0x%llX\n",cpu_rdtsc());
				}
			}
		}
	}
	printf("\n");

	return 0;
}
Beispiel #2
0
int main(int argc, char **argv)
{
    long val;
    long long val2;
    int ret;
    
    if (argc < 2)
    {
        printf("Usage: %s str [base]\n", argv[0]);
        return -1;
    }
    
    printf("GetCycleCount: %lld, GetMsCount: %lld, GetSecCount: %lld\n", GetCycleCount(), GetMsCount(), GetSecCount());
    printf("GetCycleCount: %lld, GetMsCount: %lld, GetSecCount: %lld\n", GetCycleCount(), GetMsCount(), GetSecCount());

    ret = StrToLong(argv[1], &val, (argc < 3) ? 0 : atoi(argv[2]));
    if (ret < 0)
    {
        printf("StrToLong failed. [ret: %d]\n", ret);
    }
    else
    {
        printf("%ld\n", val);
    }

    ret = StrToLongLong(argv[1], &val2, (argc < 3) ? 0 : atoi(argv[2]));
    if (ret < 0)
    {
        printf("StrToLongLong failed. [ret: %d]\n", ret);
    }
    else
    {
        printf("%lld\n", val2);
    }
    
    usleep(1000 * 1000);

    printf("GetCycleCount: %lld, GetMsCount: %lld, GetSecCount: %lld\n", GetCycleCount(), GetMsCount(), GetSecCount());
    printf("GetCycleCount: %lld, GetMsCount: %lld, GetSecCount: %lld\n", GetCycleCount(), GetMsCount(), GetSecCount());
    
    return 0;
        
}