Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

file 142 lines (121 sloc) 3.597 kb
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 142
/*
* File: cTimer.c
* Author: Russ Porosky
*
* Created on May 3 2012
*/

#include "Python.h"

#if PY_MAJOR_VERSION >= 3
#define MOD_ERROR_VAL NULL
#define MOD_SUCCESS_VAL(val) val
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(ob, name, doc, methods) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
ob = PyModule_Create(&moduledef);
#else
#define MOD_ERROR_VAL
#define MOD_SUCCESS_VAL(val)
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(ob, name, doc, methods) \
ob = Py_InitModule3(name, methods, doc);
#endif


#include <time.h>

#ifdef __APPLE__ // OSX-only
#include "osxGetTime.h"
#endif

static double *times = NULL;
static int num_elements = 0;
static int num_allocated = 0;

int addToArray(double item) {
if (num_elements >= num_allocated) {
if (num_allocated == 0) {
num_allocated = 20;
} else {
num_allocated = num_allocated + 20;
}
void *_tmp = realloc(times, (num_allocated * sizeof(double)));
if (!_tmp) {
fprintf(stderr, "ERROR: Couldn't realloc memory!\n");
return(-1);
}
times = (double*)_tmp;
}
times[num_elements] = (double)item;
num_elements++;
return num_elements - 1;
}

double convertTsToDouble(struct timespec thetime) {
return ((double)thetime.tv_nsec / (double)1000000000) + (double)thetime.tv_sec;
}

double diff(double start, double end) {
double tmp = end - start;
if (tmp < 0) {
tmp = tmp * -1;
}
return (double)tmp;
}

struct timespec gettime(void) {
struct timespec temp;
#ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &temp);
#elif CLOCK_MONOTONIC
clock_gettime(CLOCK_MONOTONIC, &temp);
#elif CLOCK_REALTIME
clock_gettime(CLOCK_REALTIME, &temp);
#endif
return temp;
}

static PyObject *
timer_start(PyObject *self, PyObject *args)
{
return Py_BuildValue("i", addToArray(convertTsToDouble(gettime())));
};

static PyObject *
timer_checkpoint(PyObject *self, PyObject *args)
{
return Py_BuildValue("i", addToArray(convertTsToDouble(gettime())));
};

static PyObject *
timer_stop(PyObject *self, PyObject *args)
{
return Py_BuildValue("i", addToArray(convertTsToDouble(gettime())));
};

static PyObject *
timer_diff(PyObject *self, PyObject *args)
{
int time1;
int time2;
if (!PyArg_ParseTuple(args, "ii", &time1, &time2)) {
return NULL;
}
if (time1 >= num_elements || time2 >= num_elements || time1 < 0 || time2 < 0) {
PyErr_SetString(PyExc_IndexError, "Invalid timer ID.");
return NULL;
}
return Py_BuildValue("d", (double)diff(times[time1], times[time2]));
};

static PyObject *
timer_get(PyObject *self, PyObject *args)
{
return Py_BuildValue("d", diff(times[0], convertTsToDouble(gettime())));
};

static PyMethodDef TimerMethods[] = {
{"get", timer_get, METH_NOARGS, "Get a relative timestamp as a float."},
{"start", timer_start, METH_NOARGS, "Get timer ID for a start point."},
{"checkpoint", timer_checkpoint, METH_NOARGS, "Get timer ID for a checkpoint."},
{"stop", timer_stop, METH_NOARGS, "Get timer ID for a stop point."},
{"diff", timer_diff, METH_VARARGS, "Get the difference in seconds between two checkpoint IDs as a double."},
{NULL, NULL, 0, NULL} /* Sentinel */
};


MOD_INIT(cTimer)
{
addToArray(convertTsToDouble(gettime()));
PyObject *m;

    MOD_DEF(m, "cTimer", "A high precision timer.",
            TimerMethods)
            
    if (m == NULL)
        return MOD_ERROR_VAL;
    
    return MOD_SUCCESS_VAL(m);
//(void) Py_InitModule3("cTimer", TimerMethods, "A high precision timer.");
}
Something went wrong with that request. Please try again.