Jump to content
  • Advertisement
Benjamin Shefte

C++ Convert functions to linux (gcc)

Recommended Posts

Hey there,  I have this old code im trying to compile using GCC and am running into a few issues..

im trying to figure out how to convert these functions to gcc

static __int64 MyQueryPerformanceFrequency()
{
	static __int64 aFreq = 0;
	if(aFreq!=0)
		return aFreq;

	LARGE_INTEGER s1, e1, f1;
	__int64 s2, e2, f2;
	QueryPerformanceCounter(&s1);
	s2 = MyQueryPerformanceCounter();
	Sleep(50);
	e2 = MyQueryPerformanceCounter();
	QueryPerformanceCounter(&e1);
	QueryPerformanceFrequency(&f1);
	double aTime = (double)(e1.QuadPart - s1.QuadPart)/f1.QuadPart;
	f2 = (e2 - s2)/aTime;
	aFreq = f2;

	return aFreq;
}

void PerfTimer::GlobalStart(const char *theName)
{
	gPerfTimerStarted = true;
	gPerfTotalTime = 0;
	gPerfTimerStartCount = 0;
	gPerfElapsedTime = 0;

	LARGE_INTEGER anInt; QueryPerformanceCounter(&anInt);
	gPerfResetTick = anInt.QuadPart;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void PerfTimer::GlobalStop(const char *theName)
{
	LARGE_INTEGER anInt; QueryPerformanceCounter(&anInt);
	LARGE_INTEGER aFreq; QueryPerformanceFrequency(&aFreq);
	gPerfElapsedTime = (double)(anInt.QuadPart - gPerfResetTick)/aFreq.QuadPart*1000.0;
	gPerfTimerStarted = false;
}

 

I also tried converting this function (original function is the first function below and my converted for gcc function is under that) is this correct?:

#if defined(WIN32)
static __int64 MyQueryPerformanceCounter()
{
//	LARGE_INTEGER anInt;
//	QueryPerformanceCounter(&anInt);
//	return anInt.QuadPart;
#if defined(WIN32)
	unsigned long x,y;
	_asm
	{
		rdtsc
		mov x, eax
		mov y, edx
	}

	__int64 result = y;
	result<<=32;
	result|=x;
	return result;

}
#else

static __int64 MyQueryPerformanceCounter()
{
	
	struct timeval t1, t2;
	double elapsedTime;
	
	// start timer
	gettimeofday(&t1, NULL);
	
	Sleep(50);
	
	// stop timer
	gettimeofday(&t2, NULL);
	
	// compute and print the elapsed time in millisec
	elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;      // sec to ms
	elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;   // us to ms
	
	return elapsedTime;
	
}
#endif

Any help would be appreciated, Thank you!

Share this post


Link to post
Share on other sites
Advertisement

QueryPerformanceCounter is a Windows specific function for a high resolution timer. Equivalent functions on Linux should be google-able with that term :-)

Share this post


Link to post
Share on other sites

this is what i have now:

static __int64 MyQueryPerformanceCounter()
{
//	LARGE_INTEGER anInt;
//	QueryPerformanceCounter(&anInt);
//	return anInt.QuadPart;
	unsigned long x,y;

#if defined(WIN32)
	_asm
	{
		rdtsc
		mov x, eax
		mov y, edx
	}
#else

    __asm__ __volatile__ ("rdtsc" : "=a" (x), "=d" (y));

	// OR THIS CODE? Code to read Time Stamp Counter 
	/*
	asm(
		"	rdtsc\n"
		"	mov %%eax, %0\n"
		"	mov %%edx, %1\n"
		:
		"=a" (x),
		"=d" (y)
		);
	*/
#endif

	__int64 result = y;
	result<<=32;
	result|=x;
	return result;
}

static __int64 MyQueryPerformanceFrequency()
{
	timeval t1, t2;
	__int64 s2, e2;
	double elapsedTime;

	// start timer
	gettimeofday(&t1, NULL);
	s2 = MyQueryPerformanceCounter();
	Sleep(50);
	e2 = MyQueryPerformanceCounter();
	// stop timer
	gettimeofday(&t2, NULL);

	// compute and print the elapsed time in millisec
	elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;      // sec to ms
	elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;   // us to ms
//	cout << elapsedTime << " ms.\n";

	return (__int64)((e2 - s2)/elapsedTime);

}

does that look acceptable?

Share this post


Link to post
Share on other sites

gettimeofday is quite normal for measuring time. There is also std::clock http://en.cppreference.com/w/cpp/chrono/c/clock which is more portable. Don't know its precision, likely it varies between platforms.

For more extensive measuring, it might be useful to first convert timeval to a single 64 bit number, eg in nanoseconds for instance, and then compute time differences, and accumulating time.

 

Instead of the __int64, use std::int64_t standard types, which are more portable.

Share this post


Link to post
Share on other sites

There's clock_gettime in Linux. It gives you the time with nano-second resolution (but lower precision, usually), but clock_getres can be used to find the actual precision.

You may want to use the clock named CLOCK_MONOTONIC_RAW to get the actual real time that has passed.

Share this post


Link to post
Share on other sites

For unix based systems

Header

#ifndef TimerH
#define TimerH

//#include "const_vars.h"
#ifndef WINDOWS_CMP
#include "stdint.h"

const int64_t nsec_per_sec = 1000000000;
const double ns_2_s = 1000000000.0;

typedef struct {
     int64_t start;
     int64_t stop;
 } stopWatch;

 class CStopWatch {

     stopWatch timer;

 public:
     CStopWatch() ;
     void startTimer();
     void stopTimer();
     double getElapsedTime();
     double getElapsedTimeFromStart();
     double getTime();
 };
#endif






#ifdef WINDOWS_CMP
//---------------------------------------------------------------------------

#include "windows.h"
#include <ctime>
//---------------------------------------------------------------------------

typedef struct {
     LARGE_INTEGER start;
     LARGE_INTEGER stop;
 } stopWatch;
 
 class CStopWatch {
 
 private:
 double PCFreq;// = 0.0;
     stopWatch timer;
     LARGE_INTEGER frequency;
     double LIToSecs( LARGE_INTEGER & L) ;
 public:
     CStopWatch() ;
     void startTimer();
     void stopTimer();
     double getElapsedTime();
     double getElapsedTimeFromStart();
     double getTime();
 };
#endif

#endif

Cpp

//---------------------------------------------------------------------------
#include "Timer.h"
#ifndef WINDOWS_CMP
#include "Time.h"
#include "logme.h"
//---------------------------------------------------------------------------

//returns time in miliseconds
int64_t QueryPerformanceCounter()
{
	int64_t nsec_count, nsec_per_tick;
    /*
     * clock_gettime() returns the number of secs. We translate that to number of nanosecs.
     * clock_getres() returns number of seconds per tick. We translate that to number of nanosecs per tick.
     * Number of nanosecs divided by number of nanosecs per tick - will give the number of ticks.
     */
     struct timespec ts1, ts2;

     if (clock_gettime(CLOCK_MONOTONIC, &ts1) != 0) {
    	 ALOG("FAILED TO GET TIME");
         return -1;
     }



     nsec_count = ts1.tv_nsec + ts1.tv_sec * nsec_per_sec;

     return double(nsec_count) / 1000000.0;
}




 CStopWatch::CStopWatch(){

 }

 void CStopWatch::startTimer() {
	 timer.start = QueryPerformanceCounter();
 }

 void CStopWatch::stopTimer() {
	 timer.stop = QueryPerformanceCounter();
 }

 double CStopWatch::getElapsedTime() {
	 stopTimer();
	 int64_t time = timer.stop - timer.start;
	 startTimer();

	return double(time);

 }


 double CStopWatch::getTime() {

	 int64_t time = QueryPerformanceCounter();

	return double(time);

 }

 double CStopWatch::getElapsedTimeFromStart() {
	 stopTimer();
	 int64_t time = timer.stop - timer.start;

	return double(time);

 }
#endif


#ifdef WINDOWS_CMP
      //---------------------------------------------------------------------------


#pragma hdrstop

#include "Timer.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)



 
 double CStopWatch::LIToSecs( LARGE_INTEGER & L)
 {
     return ((double)L.QuadPart / PCFreq);
 }

 CStopWatch::CStopWatch(){
     PCFreq = 0.0;
     timer.start.QuadPart=0;
	 timer.stop.QuadPart=0;
	 QueryPerformanceFrequency( &frequency ) ;
	  PCFreq = double(frequency.QuadPart);
 }
 
 void CStopWatch::startTimer( ) {
     QueryPerformanceCounter(&timer.start) ;
 }
 
 void CStopWatch::stopTimer( ) {
     QueryPerformanceCounter(&timer.stop) ;
 }
 
 double CStopWatch::getElapsedTime() {
     stopTimer();
	 LARGE_INTEGER time;
	 time.QuadPart = timer.stop.QuadPart - timer.start.QuadPart;
	 startTimer();
     return LIToSecs( time ) ;
 }

  double CStopWatch::getTime() {
      stopTimer();
	 int64_t time = timer.stop.QuadPart ();

	return LIToSecs( time ) ;

 }
  double CStopWatch::getElapsedTimeFromStart() {
	 stopTimer();
	 int64_t time = timer.stop.QuadPart - timer.start.QuadPart;

	return LIToSecs( time ) ;

 }

#endif

 

Share this post


Link to post
Share on other sites

I think you may want to use CLOCK_MONOTONIC_RAW instead of CLOCK_MONOTONIC. It doesn't make a huge difference, and mostlikely never causes any notiveable problems, but CLOCK_MONOTONIC may run slower or faster than "real" time, when the clock gets adjusted.

Basically, a correctly implemented tool to set system time on a UNIX system will not just set the new time, but rather slow down or speed up the system clock to gradually go to the new time. This is so that there are no jumps in the system time, which will throw off a bunch of things on a UNIX system.

CLOCK_MONOTONIC is subject to these adjustments, so you might experience a time where your game does not actually measure one second of realtime as one second, but rather as 1.1s or something like that. CLOCK_MONOTONIC_RAW is never sped up or slowed down.

Share this post


Link to post
Share on other sites

For sleep(50), you will need to use usleep(50000) (or, for sleep(x), use usleep(x*1000)); be careful not to use "sleep(50)", as this is denominated in seconds, rather than milliseconds. usleep() is denominated in microseconds.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!