/* ptlinux.c -- portable timer implementation for linux */ #include "porttime.h" #include "sys/time.h" #include "sys/timeb.h" #include "pthread.h" #define TRUE 1 #define FALSE 0 static int time_started_flag = FALSE; static struct timeb time_offset = {0, 0, 0, 0}; static pthread_t pt_thread_pid; /* note that this is static data -- we only need one copy */ typedef struct { int id; int resolution; PtCallback *callback; void *userData; } pt_callback_parameters; static int pt_callback_proc_id = 0; static void *Pt_CallbackProc(void *p) { pt_callback_parameters *parameters = (pt_callback_parameters *) p; int mytime = 1; /* to kill a process, just increment the pt_callback_proc_id */ printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id); while (pt_callback_proc_id == parameters->id) { /* wait for a multiple of resolution ms */ struct timeval timeout; int delay = mytime++ * parameters->resolution - Pt_Time(); if (delay < 0) delay = 0; timeout.tv_sec = 0; timeout.tv_usec = delay * 1000; select(0, NULL, NULL, NULL, &timeout); (*(parameters->callback))(Pt_Time(), parameters->userData); } printf("Pt_CallbackProc exiting\n"); // free(parameters); return NULL; } PtError Pt_Start(int resolution, PtCallback *callback, void *userData) { if (time_started_flag) return ptNoError; ftime(&time_offset); /* need this set before process runs */ if (callback) { int res; pt_callback_parameters *parms = (pt_callback_parameters *) malloc(sizeof(pt_callback_parameters)); if (!parms) return ptInsufficientMemory; parms->id = pt_callback_proc_id; parms->resolution = resolution; parms->callback = callback; parms->userData = userData; res = pthread_create(&pt_thread_pid, NULL, Pt_CallbackProc, parms); if (res != 0) return ptHostError; } time_started_flag = TRUE; return ptNoError; } PtError Pt_Stop() { printf("Pt_Stop called\n"); pt_callback_proc_id++; time_started_flag = FALSE; return ptNoError; } int Pt_Started() { return time_started_flag; } PtTimestamp Pt_Time() { long seconds, milliseconds; struct timeb now; ftime(&now); seconds = now.time - time_offset.time; milliseconds = now.millitm - time_offset.millitm; return seconds * 1000 + milliseconds; }