Posted to tcl by de at Wed May 16 00:41:03 GMT 2018view pretty
#include <tcl.h> #include <time.h> static int timeObjCmd ( ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] ) { Tcl_Obj *objPtr; Tcl_Obj *objs[4]; int i, result; int count; struct timespec tp; time_t startSec; long startNano; if (objc == 2) { count = 1; } else if (objc == 3) { result = Tcl_GetIntFromObj(interp, objv[2], &count); if (result != TCL_OK) { return result; } } else { Tcl_WrongNumArgs(interp, 1, objv, "command ?count?"); return TCL_ERROR; } objPtr = objv[1]; i = count; if (clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tp) != 0) { return TCL_ERROR; } startNano = tp.tv_sec * 1000000000 + tp.tv_nsec; while (i-- > 0) { result = Tcl_EvalObjEx(interp, objPtr, 0); if (result != TCL_OK) { return result; } } if (clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tp) != 0) { return TCL_ERROR; } if (count <= 1) { objs[0] = Tcl_NewLongObj ((tp.tv_sec * 1000000000 + tp.tv_nsec - startNano) / 1000); } else { objs[0] = Tcl_NewDoubleObj ((tp.tv_sec * 1000000000.0 + tp.tv_nsec - startNano) / (count * 1000)); } /* * Construct the result as a list because many programs have always parsed * as such (extracting the first element, typically). */ objs[1] = Tcl_NewStringObj ("microseconds", -1); objs[2] = Tcl_NewStringObj ("per", -1); objs[3] = Tcl_NewStringObj ("iteration", -1); Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs)); return TCL_OK; } int Time_Init (interp) Tcl_Interp *interp; /* Interpreter to initialize. */ { Tcl_InitStubs(interp, "8", 0); Tcl_CreateObjCommand(interp, "time::time", timeObjCmd, NULL, NULL ); Tcl_PkgProvide(interp, "time", "1.0"); return TCL_OK; }