| | @@ -53,131 +53,10 @@ |
| 53 | 53 | "resultText" /*resultText*/, |
| 54 | 54 | "timestamp" /*timestamp*/ |
| 55 | 55 | }; |
| 56 | 56 | |
| 57 | 57 | |
| 58 | | -/* Timer code taken from sqlite3's shell.c, modified slightly. |
| 59 | | - FIXME: move the timer into the fossil core API so that we can |
| 60 | | - start the timer early on in the app init phase. Right now we're |
| 61 | | - just timing the json ops themselves. |
| 62 | | -*/ |
| 63 | | -#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) |
| 64 | | -#include <sys/time.h> |
| 65 | | -#include <sys/resource.h> |
| 66 | | - |
| 67 | | -/* Saved resource information for the beginning of an operation */ |
| 68 | | -static struct rusage sBegin; |
| 69 | | - |
| 70 | | -/* |
| 71 | | -** Begin timing an operation |
| 72 | | -*/ |
| 73 | | -static void beginTimer(void){ |
| 74 | | - getrusage(RUSAGE_SELF, &sBegin); |
| 75 | | -} |
| 76 | | - |
| 77 | | -/* Return the difference of two time_structs in milliseconds */ |
| 78 | | -static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ |
| 79 | | - return ((pEnd->tv_usec - pStart->tv_usec)*0.001 + |
| 80 | | - (double)((pEnd->tv_sec - pStart->tv_sec)*1000.0)); |
| 81 | | -} |
| 82 | | - |
| 83 | | -/* |
| 84 | | -** Print the timing results. |
| 85 | | -*/ |
| 86 | | -static double endTimer(void){ |
| 87 | | - struct rusage sEnd; |
| 88 | | - getrusage(RUSAGE_SELF, &sEnd); |
| 89 | | -#if 0 |
| 90 | | - printf("CPU Time: user %f sys %f\n", |
| 91 | | - timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), |
| 92 | | - timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); |
| 93 | | -#endif |
| 94 | | - return timeDiff(&sBegin.ru_utime, &sEnd.ru_utime) |
| 95 | | - + timeDiff(&sBegin.ru_stime, &sEnd.ru_stime); |
| 96 | | -} |
| 97 | | - |
| 98 | | -#define BEGIN_TIMER beginTimer() |
| 99 | | -#define END_TIMER endTimer() |
| 100 | | -#define HAS_TIMER 1 |
| 101 | | - |
| 102 | | -#elif (defined(_WIN32) || defined(WIN32)) |
| 103 | | - |
| 104 | | -#include <windows.h> |
| 105 | | - |
| 106 | | -/* Saved resource information for the beginning of an operation */ |
| 107 | | -static HANDLE hProcess; |
| 108 | | -static FILETIME ftKernelBegin; |
| 109 | | -static FILETIME ftUserBegin; |
| 110 | | -typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); |
| 111 | | -static GETPROCTIMES getProcessTimesAddr = NULL; |
| 112 | | - |
| 113 | | -/* |
| 114 | | -** Check to see if we have timer support. Return 1 if necessary |
| 115 | | -** support found (or found previously). |
| 116 | | -*/ |
| 117 | | -static int hasTimer(void){ |
| 118 | | - if( getProcessTimesAddr ){ |
| 119 | | - return 1; |
| 120 | | - } else { |
| 121 | | - /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions. |
| 122 | | - ** See if the version we are running on has it, and if it does, save off |
| 123 | | - ** a pointer to it and the current process handle. |
| 124 | | - */ |
| 125 | | - hProcess = GetCurrentProcess(); |
| 126 | | - if( hProcess ){ |
| 127 | | - HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); |
| 128 | | - if( NULL != hinstLib ){ |
| 129 | | - getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); |
| 130 | | - if( NULL != getProcessTimesAddr ){ |
| 131 | | - return 1; |
| 132 | | - } |
| 133 | | - FreeLibrary(hinstLib); |
| 134 | | - } |
| 135 | | - } |
| 136 | | - } |
| 137 | | - return 0; |
| 138 | | -} |
| 139 | | - |
| 140 | | -/* |
| 141 | | -** Begin timing an operation |
| 142 | | -*/ |
| 143 | | -static void beginTimer(void){ |
| 144 | | - if( getProcessTimesAddr ){ |
| 145 | | - FILETIME ftCreation, ftExit; |
| 146 | | - getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin); |
| 147 | | - } |
| 148 | | -} |
| 149 | | - |
| 150 | | -/* Return the difference of two FILETIME structs in milliseconds */ |
| 151 | | -static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ |
| 152 | | - sqlite_int64 i64Start = *((sqlite_int64 *) pStart); |
| 153 | | - sqlite_int64 i64End = *((sqlite_int64 *) pEnd); |
| 154 | | - return (double) ((i64End - i64Start) / 10000.0); |
| 155 | | -} |
| 156 | | - |
| 157 | | -/* |
| 158 | | -** Print the timing results. |
| 159 | | -*/ |
| 160 | | -static double endTimer(void){ |
| 161 | | - if(getProcessTimesAddr){ |
| 162 | | - FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; |
| 163 | | - getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd); |
| 164 | | - return timeDiff(&ftUserBegin, &ftUserEnd) + |
| 165 | | - timeDiff(&ftKernelBegin, &ftKernelEnd); |
| 166 | | - } |
| 167 | | - return 0.0; |
| 168 | | -} |
| 169 | | - |
| 170 | | -#define BEGIN_TIMER beginTimer() |
| 171 | | -#define END_TIMER endTimer() |
| 172 | | -#define HAS_TIMER hasTimer() |
| 173 | | - |
| 174 | | -#else |
| 175 | | -#define BEGIN_TIMER |
| 176 | | -#define END_TIMER 0.0 |
| 177 | | -#define HAS_TIMER 0 |
| 178 | | -#endif |
| 179 | 58 | |
| 180 | 59 | /* |
| 181 | 60 | ** Returns true (non-0) if fossil appears to be running in JSON mode. |
| 182 | 61 | */ |
| 183 | 62 | char fossil_has_json(){ |
| | @@ -814,10 +693,11 @@ |
| 814 | 693 | ** up. e.g. it must not use cgi_parameter() and friends because this |
| 815 | 694 | ** must be called before those data are initialized. |
| 816 | 695 | */ |
| 817 | 696 | void json_main_bootstrap(){ |
| 818 | 697 | cson_value * v; |
| 698 | + g.json.timerId = fossil_timer_start(); |
| 819 | 699 | assert( (NULL == g.json.gc.v) && "cgi_json_bootstrap() was called twice!" ); |
| 820 | 700 | |
| 821 | 701 | /* g.json.gc is our "garbage collector" - where we put JSON values |
| 822 | 702 | which need a long lifetime but don't have a logical parent to put |
| 823 | 703 | them in. |
| | @@ -1544,22 +1424,23 @@ |
| 1544 | 1424 | cson_object_set( o, "cmd.offset", tmp ); |
| 1545 | 1425 | cson_object_set( o, "isCGI", cson_value_new_bool( g.isHTTP ) ); |
| 1546 | 1426 | } |
| 1547 | 1427 | } |
| 1548 | 1428 | |
| 1549 | | - if(HAS_TIMER){ |
| 1429 | + if(fossil_has_timer()){ |
| 1550 | 1430 | /* This is, philosophically speaking, not quite the right place |
| 1551 | 1431 | for ending the timer, but this is the one function which all of |
| 1552 | 1432 | the JSON exit paths use (and they call it after processing, |
| 1553 | 1433 | just before they end). |
| 1554 | 1434 | */ |
| 1555 | | - double span; |
| 1556 | | - span = END_TIMER; |
| 1557 | | - /* I'm actually seeing sub-ms runtimes in some tests, but a time of |
| 1558 | | - 0 is "just wrong", so we'll bump that up to 1ms. |
| 1435 | + sqlite3_uint64 span = fossil_timer_fetch(g.json.timerId); |
| 1436 | + /* I'm actually seeing sub-uSec runtimes in some tests, but a time of |
| 1437 | + 0 is "just kinda wrong". |
| 1559 | 1438 | */ |
| 1560 | | - cson_object_set(o,"procTimeMs", cson_value_new_integer((cson_int_t)((span>1.0)?span:1))); |
| 1439 | + cson_object_set(o,"procTimeUs", cson_value_new_integer((cson_int_t)span)); |
| 1440 | + span /= 1000/*for milliseconds */; |
| 1441 | + cson_object_set(o,"procTimeMs", cson_value_new_integer((cson_int_t)span)); |
| 1561 | 1442 | } |
| 1562 | 1443 | if(g.json.warnings){ |
| 1563 | 1444 | tmp = cson_array_value(g.json.warnings); |
| 1564 | 1445 | SET("warnings"); |
| 1565 | 1446 | } |
| | @@ -2334,11 +2215,10 @@ |
| 2334 | 2215 | ** This function dispatches them, and is the HTTP equivalent of |
| 2335 | 2216 | ** json_cmd_top(). |
| 2336 | 2217 | */ |
| 2337 | 2218 | void json_page_top(void){ |
| 2338 | 2219 | char const * zCommand; |
| 2339 | | - BEGIN_TIMER; |
| 2340 | 2220 | json_mode_bootstrap(); |
| 2341 | 2221 | zCommand = json_command_arg(1); |
| 2342 | 2222 | if(!zCommand || !*zCommand){ |
| 2343 | 2223 | json_dispatch_missing_args_err( JsonPageDefs, |
| 2344 | 2224 | "No command (sub-path) specified." |
| | @@ -2392,11 +2272,10 @@ |
| 2392 | 2272 | ** |
| 2393 | 2273 | */ |
| 2394 | 2274 | void json_cmd_top(void){ |
| 2395 | 2275 | char const * cmd = NULL; |
| 2396 | 2276 | int rc = 0; |
| 2397 | | - BEGIN_TIMER; |
| 2398 | 2277 | memset( &g.perm, 0xff, sizeof(g.perm) ) |
| 2399 | 2278 | /* In CLI mode fossil does not use permissions |
| 2400 | 2279 | and they all default to false. We enable them |
| 2401 | 2280 | here because (A) fossil doesn't use them in local |
| 2402 | 2281 | mode but (B) having them set gives us one less |
| 2403 | 2282 | |