File: GetSecs.c

package info (click to toggle)
psychtoolbox-3 3.0.14.20170103%2Bgit6-g605ff5c.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 103,044 kB
  • ctags: 69,483
  • sloc: ansic: 167,371; cpp: 11,232; objc: 4,708; sh: 1,875; python: 383; php: 344; makefile: 207; java: 113
file content (97 lines) | stat: -rw-r--r-- 3,737 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
	PsychSourceGL/Source/Common/GetSecs/GetSecs.c		
  
	PROJECTS: 
  
		GetSecs only
  
	AUTHORS:
  
		Allen.Ingling@nyu.edu				awi 
		mario.kleiner@tuebingen.mpg.de	mk
  
	PLATFORMS:	
  
		All.
    
	HISTORY:

		1/20/02		awi		Derived the GetSecs project from Screen .
		8/20/02		awi		Added "version" command borrowed from the Screen project. 
		7/07/04		awi		Cosmetic		
		4/6/05		awi		Updated header comments.
	  11/14/07		mk		Add debug diagnosis code for Windoze.
	  11/20/07		mk		Add gettimeofday() and dummy code for OS/X and Linux.

	DESCRIPTION:
   
		Return the time in seconds with high precision. On MS-Windows, it allows to
		trigger some debug operations and returns some diagnostic values that allow
		to diagnose timer problems. Not so on Linux or OS/X: They don't have such problems afaik ;-)

*/

#include "GetSecs.h"

#if PSYCH_SYSTEM != PSYCH_WINDOWS
#include <sys/time.h>
#endif

PsychError GETSECSGetSecs(void) 
{
    double 	*returnValue;  
	 double  referenceValue, realValue;
	 int		healthy, opmode;

    //check to see if the user supplied superfluous arguments
    PsychErrorExit(PsychCapNumOutputArgs(5));
    PsychErrorExit(PsychCapNumInputArgs(1));
    
    //Allocate a return matrix and load it with the depth values.  
    PsychAllocOutDoubleArg(1, FALSE, &returnValue);
    PsychGetAdjustedPrecisionTimerSeconds(returnValue);

	 // Special code for diagnosing problems with TimeGlue on systems that
	 // are broken by design(TM) aka MS-Windows:
	 #if PSYCH_SYSTEM == PSYCH_WINDOWS
		if (PsychCopyInIntegerArg(1, FALSE, &opmode) && (opmode!=0)) {
			referenceValue = PsychGetTimeGetTimeValueAtLastTimeQuery(&realValue);
			healthy = (int) PsychGetTimeBaseHealthiness();
			PsychCopyOutDoubleArg(2, FALSE, referenceValue);
			PsychCopyOutDoubleArg(3, FALSE, realValue);
			PsychCopyOutDoubleArg(4, FALSE, (double) healthy);

			// A positive opmode value allows to change the thread affinity mask of the PTB Thread.
			// The old affinity mask is returned in that case. This to check for TSC sync across cpu cores:
			if (opmode > 0) PsychCopyOutDoubleArg(5, FALSE, (double) SetThreadAffinityMask(GetCurrentThread(), (DWORD) opmode));
			// An opmode setting of smaller than -1 will try to cancel our timeBeginPeriod(1) requests, as
			// automatically done by the PsychTimeGlue: We try to reset the low-res timer to something
			// like its normal 10 or 15 msecs duty cycle. Could help to spot timers that are actually
			// broken, but do work with the new PTB due to the increased IRQ load and therefore the
			// reduced power management. Post-hoc test if timing was reliable in earlier PTB releases.
			if (opmode < -1) timeEndPeriod(1);
		}
	 #else
		// For MacOS/X and Linux, we return gettimeofday() as reference value and
		// some default "no error" healthy flag. Please note that gettimeofday() is just a
		// drift/NTP corrected version of the system timebase mach_absolute_time(), ie the
		// same value as returned as primary time, just with some offset. Therefore its not
		// possible to check for timebase malfunction, only for clock drift against some
		// external timebase, e.g., UTC as determined by NTP protocol.
		if (PsychCopyInIntegerArg(1, FALSE, &opmode) && (opmode!=0)) {
			struct timeval tv;
			gettimeofday(&tv, NULL);
			referenceValue = ((double) tv.tv_sec) + (((double) tv.tv_usec) / 1000000.0); 
			healthy = 0;
			realValue = *returnValue;
			PsychCopyOutDoubleArg(2, FALSE, referenceValue);
			PsychCopyOutDoubleArg(3, FALSE, realValue);
			PsychCopyOutDoubleArg(4, FALSE, (double) healthy);

			// Copy out a fake thread affinity mask of the PTB Thread if requested:
			if (opmode > 0) PsychCopyOutDoubleArg(5, FALSE, 0);
		}
	 #endif
	 
    return(PsychError_none);	
}