GetTickCount für Linux?



  • Neku schrieb:

    ... und ich fand: man: clock_gettime 🙂

    Hallo,

    versuche das gerade unter FreeBSD anzuwenden, aber irgendwie will's nicht so recht... Jemand ne Idee wo der Fehler liegt?

    #ifndef CLOCK_MONOTONIC
     #define CLOCK_MONOTONIC _SC_MONOTONIC_CLOCK
    #endif
    
    //# define GET_TIME(x) x = GetTickCount()
    # define GET_TIME(x) { struct timespec abc; \
    clock_gettime(CLOCK_MONOTONIC, &abc); \
    printf("++++++++sec: %ld usec: %ld\n", abc.tv_sec, abc.tv_nsec); \
    x = (int)(abc.tv_sec * 1000 + abc.tv_nsec * 0.000001); }
    

    Der fprint ist natürlich nur zum Test drin und zeigt beim ersten Aufruf von GET_TIME(x) "sec: 671415874 usec: 0" und danach immer für beide 0... Könnte natürlich gut sein, dass meine Definition von CLOCK_MONOTONIC falsch ist, gcc meinte sie wär undeclared und den Schnipsel von ganz oben habe ich dann beim googlen gefunden.
    CLOCK_MONOTONIC hat dann den Wert 74...



  • Bei meiner bits/time.h ist CLOCK_MONOTONIC als 1 definiert.

    Unter Linux sieht das bei mir so aus:

    uint32 timeGetTime()
    {
    	timespec tp;
    	::clock_gettime (CLOCK_MONOTONIC, &tp);
    
    	return (tp.tv_sec * 1000 + tp.tv_nsec / 1000000);
    }
    

    LordJaxom schrieb:

    Ist richtig, negative (also hohe) Prios sind root vorbehalten.

    Ich weiß nicht wieso, aber bei meinem Linux ist das plötzlich anders und mein Prozess läuft als normaler User mit einem Nice-Wert von -10.

    Ich suche im übrigen noch immer ein präziseres Äquivalent zu Sleep von Windows. sleep, usleep und nanosleep schlafen alle länger als sie sollen und das passt mir nicht 😉

    Vorübergehende, CPU-fressende Lösung:

    void Sleep
    	(uint32 uMilliseconds)
    {
    	if (!uMilliseconds)
    		return;
    
    	timespec tp;
    
    	::clock_gettime (CLOCK_MONOTONIC, &tp);
    	uint32 uStart = tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
    
    	uint32 uMicroseconds = uMilliseconds * 1000;
    	tp.tv_sec = 0;
    
    	if (uMicroseconds > 1000)
    	{
    		tp.tv_nsec = uMicroseconds * 1000 - 1500000;
    		::nanosleep (&tp, 0);
    	}
    
    	do
    	{
    		::clock_gettime (CLOCK_MONOTONIC, &tp);
    	}
    	while (tp.tv_sec * 1000000 + tp.tv_nsec / 1000 - uStart < uMicroseconds);
    }
    

    Passt idR auf die Millisekunde genau bei einer CPU-Auslastung von ca. 4%.



  • Diese Diskussion hat mir sehr geholfen, ich war auf der Suche nach einem Ersatz für GetTickCount auf Solaris.

    Leider verwenden wir ein etwas ältliches Solaris und daher war clock_gettime keine Alternative (kennt weder CLOCK_MONOTONIC noch CLOCK_UPTIME).

    Aber irgendwie bin ich über clock_gettime auf gethrtime gestossen. Das gibt es auch in RTLinux.

    Und falls Neku es noch lesen sollte:
    Es würde mich interessieren, was Neku sicher macht, dass die sleeps auf WIN exakter funktionieren.
    Wenn es mit GetTickCount gemessen wurde, ist es kein Wunder dass WIN exakter erscheint. GetTickCount liefert zwar eine Zeit in Millisekunden, wird aber üblicherweise nur alle 10-16ms um 10-16 erhöht. Also die 2ms, die Linux laut Neku "idR" zu lange braucht, gehen auf WIN in der Messgenauigkeit unter (so mit GetTickCount gemessen wurde).


Log in to reply