File: TimeLists.c

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (141 lines) | stat: -rw-r--r-- 3,724 bytes parent folder | download | duplicates (7)
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
	TimeLists.c	

	AUTHORS:
	
		Allen.Ingling@nyu.edu		awi 

	PLATFORMS: 
	
		Only OS X for now.


	HISTORY:
	
		1/18/05		awi		Wrote it. 

	DESCRIPTION:

		For purposes of instrumenting Screen, maintain times samples in an abstract list type.  Internally we use a 
		linked list.  To external functions reading out values, the list appears to be an array.
		
		It is easy to time  Screen subfuntions from MATLAB by surrounding them with calls to GetSecs().  

		It is easy to time OpenGL and other C calls within  Screen subfunctions by surrionding them with 
		PsychGetAdjustedPrecisionTimerSeconds().  However, in this case there is no good way to get the time values back out of 
		Screen onto MATLAB for analysis.  TimeLists are part of the solution. Indivdual Screen subfunctions may use 
		a time list to store time samples.  Those time samples may then be read back into MATLAB using Screen('GetTimeList');
		To switch a Screen subfunction into "diagnostic" mode, where it fills a time array, you should create a Screen Preference
		setting accessible from MATLAB.
		
		Another way to do the same thing would be to allocate memory within MATLAB and have Screen store values directly
		in a MATLAB array.  But that has unpleasant drawbacks.  Either 1. We let MATLAB build up the list of times by 
		appending new values  to the end.  This is bad because MATLAB reallocates memory for the entire list every time it extends
		it by one element. 2. We precallocate the list in MATLAB.  This is bad because we have to know how long the list needs
		to be before we start recording into it.      
		
		The close routine which you register with ScriptingGlue, that routine which is executed before the mex file 
		is flushed, must call ClearTimingArray() to free storage allocated by TimeLists.
	
	TO DO:
	
		No provision is made for multiple simultaneous lists of times.  However, it seems better to only maintain one list of 
		times, and to have a second, parallel list of strings labeling the events which occured at particular times. 
		
*/

#include "Psych.h"



typedef struct _timeArrayElement_{
	double							timeValue;
	struct _timeArrayElement_		*next;
} timeArrayElement;


static timeArrayElement		*timeListHead=NULL;
static timeArrayElement		*timeListTail=NULL;
static unsigned int			numElements=0;


void StoreNowTime(void)
{
	double				now;
	timeArrayElement	*newElement;
	
	PsychGetAdjustedPrecisionTimerSeconds(&now);
	newElement=(timeArrayElement *)malloc(sizeof(timeArrayElement));
	newElement->timeValue=now;
	newElement->next=NULL;
	if(timeListTail != NULL)
		timeListTail->next=newElement;
	timeListTail=newElement;
	if(timeListHead==NULL)
		timeListHead=newElement;
	++numElements;
}

void ClearTimingArray(void)
{
	timeArrayElement	*thisElement, *tempElement;
	
	
	thisElement=timeListHead;
	while(thisElement!=NULL){
		if(thisElement->next==NULL){
			//end of list.  free this element.
			free(thisElement);
			thisElement=NULL;
			timeListHead=NULL;
			timeListTail=NULL;
			numElements=0;
		}else{
			//step ahead and free the element behind
			tempElement=thisElement;
			thisElement=thisElement->next;
			free(tempElement);
		}
	}	
}

unsigned int GetNumTimeValues(void)
{
	return(numElements);
}

unsigned int GetTimeArraySizeBytes(void)
{
	return(numElements * sizeof(double));
}


void CopyTimeArray(double *destination, unsigned int numElements)
{
	timeArrayElement	*thisElement;
	unsigned int		i;

	thisElement=timeListHead;
	for(i=0;i<numElements;i++){
		if(thisElement==NULL)
			PsychErrorExitMsg(PsychError_internal, "Attempted to copy out more values than are stored in list");
		else{
			destination[i]=thisElement->timeValue;
			thisElement=thisElement->next;
		}
	}
}