)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"69cef6aeedcbe83e4cb570de5f9c48ad909a53b2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"4eee5e7e_626494f3","updated":"2026-06-15 13:28:53.000000000","message":"I\u0027m reading more carefully the Win code ...","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1002286,"name":"Grant Ramsay","email":"grant.ramsay@hotmail.com","username":"gramsay0"},"change_message_id":"2682045abd30aa6d3f770e504b027d1c2dd092e6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"9e4d24a5_fc4e9aec","updated":"2026-06-14 22:49:34.000000000","message":"This is a start at replacing `gettimeofday`, there are still many references elsewhere in the code.\nSome other references appear to want higher than millisecond resolution, possibly implementing `timeval_us` and replacing `timeval_ms` with `{ return timeval_us() / 1000; }` would be enough to replace the remaining references.\n\nWindows can be made to use `clock_gettime` by linking `winpthread`: `AC_SEARCH_LIBS([clock_gettime], [winpthread])`.\nI thought it was simpler to just use its native `QueryPerformanceCounter` instead.\n\nI tested this on Linux (Ubuntu) by disabling NTP and changing the wall clock. The timestamps in the log messages are unaffected after applying this patch:\n```\nsudo timedatectl set-ntp false\nsudo date -s \"+10 seconds\"\n```","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1002286,"name":"Grant Ramsay","email":"grant.ramsay@hotmail.com","username":"gramsay0"},"change_message_id":"57abae84aceabe905be7f51da5bfc4b4cddb368d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"bfffa118_099f44c5","in_reply_to":"148e83f0_d586a63f","updated":"2026-06-15 23:24:02.000000000","message":"Excellent patches, the time usage is very simple and consistent with those applied. I only noticed the `timeval_ms` prototype comment needs updating. Looking closer at the changes I agree us accuracy is unnecessary","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"cd324477ef400a4dd07e379f1eddbaaa0efb6819","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"148e83f0_d586a63f","in_reply_to":"774522e2_e7c0566d","updated":"2026-06-15 22:21:20.000000000","message":"I\u0027m sending out a series on top of this patch.\nFor me we don\u0027t need the us accuracy. Please have a look at it.","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"97cee80e6f9ea1eae10891573ef03f8006e44e14","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"b31231f1_b6400e9a","in_reply_to":"9e4d24a5_fc4e9aec","updated":"2026-06-15 13:11:11.000000000","message":"Thanks, I forgot there are other instances of gettimeofday in the code.\nIn this patch you prefer CLOCK_MONOTONIC_RAW to CLOCK_MONOTONIC, and this is really welcome for coarse timing, like the GDB keep-alive.\nBut if some code requires more accurate timings, then CLOCK_MONOTONIC_RAW is not accurate enough! `timeval_us()` could not work with CLOCK_MONOTONIC_RAW.\nYour proposal of having a generic `timeval_us()` and implementing\n`timeval_ms() { return timeval_us() / 1000; }`\nwould always use the accurate timing required by `timeval_us()`, which is not optimal.\nIt\u0027s better having more implementations, like `timeval_us()`, `timeval_ms()` and a coarse `timeval_raw_ms()`.","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1002286,"name":"Grant Ramsay","email":"grant.ramsay@hotmail.com","username":"gramsay0"},"change_message_id":"e83482b4afe52984b0add08017209612b0ac4d23","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"774522e2_e7c0566d","in_reply_to":"b31231f1_b6400e9a","updated":"2026-06-15 20:51:43.000000000","message":"My understanding is `CLOCK_MONOTONIC`/`CLOCK_MONOTONIC_RAW` are accurate, and `CLOCK_MONOTONIC_COARSE` is the low accuracy, high speed version?\nIt would be really simple to have just one version for us and ms","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"}],"src/helper/time_support_common.c":[{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"69cef6aeedcbe83e4cb570de5f9c48ad909a53b2","unresolved":true,"context_lines":[{"line_number":34,"context_line":"int64_t timeval_ms(void)"},{"line_number":35,"context_line":"{"},{"line_number":36,"context_line":"#ifdef _WIN32"},{"line_number":37,"context_line":"\tstatic LARGE_INTEGER frequency;"},{"line_number":38,"context_line":"\tLARGE_INTEGER now;"},{"line_number":39,"context_line":"\tif (frequency.QuadPart \u003d\u003d 0 \u0026\u0026 !QueryPerformanceFrequency(\u0026frequency))"},{"line_number":40,"context_line":"\t\treturn -1;"}],"source_content_type":"text/x-csrc","patch_set":1,"id":"54adce4b_ffc727ff","line":37,"updated":"2026-06-15 13:28:53.000000000","message":"Why static?","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"3ad7b34ba89f109640287540e1244876a2421b08","unresolved":false,"context_lines":[{"line_number":34,"context_line":"int64_t timeval_ms(void)"},{"line_number":35,"context_line":"{"},{"line_number":36,"context_line":"#ifdef _WIN32"},{"line_number":37,"context_line":"\tstatic LARGE_INTEGER frequency;"},{"line_number":38,"context_line":"\tLARGE_INTEGER now;"},{"line_number":39,"context_line":"\tif (frequency.QuadPart \u003d\u003d 0 \u0026\u0026 !QueryPerformanceFrequency(\u0026frequency))"},{"line_number":40,"context_line":"\t\treturn -1;"}],"source_content_type":"text/x-csrc","patch_set":1,"id":"5a7a548a_b9d3b78c","line":37,"in_reply_to":"54adce4b_ffc727ff","updated":"2026-06-15 16:13:05.000000000","message":"I see, to reduce the overhead of reading it multiple times. It\u0027s not supposed to change during the execution, otherwise we cannot compare two reads of the counter.","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1002286,"name":"Grant Ramsay","email":"grant.ramsay@hotmail.com","username":"gramsay0"},"change_message_id":"e83482b4afe52984b0add08017209612b0ac4d23","unresolved":false,"context_lines":[{"line_number":34,"context_line":"int64_t timeval_ms(void)"},{"line_number":35,"context_line":"{"},{"line_number":36,"context_line":"#ifdef _WIN32"},{"line_number":37,"context_line":"\tstatic LARGE_INTEGER frequency;"},{"line_number":38,"context_line":"\tLARGE_INTEGER now;"},{"line_number":39,"context_line":"\tif (frequency.QuadPart \u003d\u003d 0 \u0026\u0026 !QueryPerformanceFrequency(\u0026frequency))"},{"line_number":40,"context_line":"\t\treturn -1;"}],"source_content_type":"text/x-csrc","patch_set":1,"id":"6e5e086a_02e8f233","line":37,"in_reply_to":"5a7a548a_b9d3b78c","updated":"2026-06-15 20:51:43.000000000","message":"I will add a comment as it is not obvious, and also remove an unintended newline from configure.ac","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"cd324477ef400a4dd07e379f1eddbaaa0efb6819","unresolved":false,"context_lines":[{"line_number":34,"context_line":"int64_t timeval_ms(void)"},{"line_number":35,"context_line":"{"},{"line_number":36,"context_line":"#ifdef _WIN32"},{"line_number":37,"context_line":"\tstatic LARGE_INTEGER frequency;"},{"line_number":38,"context_line":"\tLARGE_INTEGER now;"},{"line_number":39,"context_line":"\tif (frequency.QuadPart \u003d\u003d 0 \u0026\u0026 !QueryPerformanceFrequency(\u0026frequency))"},{"line_number":40,"context_line":"\t\treturn -1;"}],"source_content_type":"text/x-csrc","patch_set":1,"id":"e13c9704_21e05510","line":37,"in_reply_to":"6e5e086a_02e8f233","updated":"2026-06-15 22:21:20.000000000","message":"It was already ok without the comment, it\u0027s just me that looked at it too fast.","commit_id":"c0f1290020261c8a3e8bb1ddeb033ad05017199f"},{"author":{"_account_id":1000687,"name":"Tomas Vanek","display_name":"Tomas Vanek","email":"vanekt@fbl.cz","username":"vanekt"},"change_message_id":"a0707e157bd8ad8f94f6aa93bcb76c9f60414a23","unresolved":true,"context_lines":[{"line_number":41,"context_line":"\t\treturn -1;"},{"line_number":42,"context_line":"\tif (!QueryPerformanceCounter(\u0026now))"},{"line_number":43,"context_line":"\t\treturn -1;"},{"line_number":44,"context_line":"\treturn (now.QuadPart * 1000) / frequency.QuadPart;"},{"line_number":45,"context_line":"#elif defined(HAVE_CLOCK_GETTIME)"},{"line_number":46,"context_line":"#ifdef CLOCK_MONOTONIC_RAW"},{"line_number":47,"context_line":"\tclockid_t clk_id \u003d CLOCK_MONOTONIC_RAW;"}],"source_content_type":"text/x-csrc","patch_set":2,"id":"d764f2a8_53f8395c","line":44,"range":{"start_line":44,"start_character":9,"end_line":44,"end_character":28},"updated":"2026-06-23 05:46:04.000000000","message":"Hopefully the performance counter frequency is not much higher on some hosts than usual 10 MHz. With 10 MHz freq we\u0027ll get overflow after 27 years of uninterrupted system run, seems me safe to neglect. Otherwise we should simplify the fraction by Greatest Common Divisor.","commit_id":"206024f0dbc8030f03edca1cf03b7e5b2d94dabe"},{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"fce0f9ea12a60b778401b547226a27d1405baed2","unresolved":true,"context_lines":[{"line_number":41,"context_line":"\t\treturn -1;"},{"line_number":42,"context_line":"\tif (!QueryPerformanceCounter(\u0026now))"},{"line_number":43,"context_line":"\t\treturn -1;"},{"line_number":44,"context_line":"\treturn (now.QuadPart * 1000) / frequency.QuadPart;"},{"line_number":45,"context_line":"#elif defined(HAVE_CLOCK_GETTIME)"},{"line_number":46,"context_line":"#ifdef CLOCK_MONOTONIC_RAW"},{"line_number":47,"context_line":"\tclockid_t clk_id \u003d CLOCK_MONOTONIC_RAW;"}],"source_content_type":"text/x-csrc","patch_set":2,"id":"4d67f527_0819df0d","line":44,"range":{"start_line":44,"start_character":9,"end_line":44,"end_character":28},"in_reply_to":"43fb3554_43bee3d7","updated":"2026-06-23 15:31:33.000000000","message":"Or with a tradeoff\n`return (now.QuadPart * 100) / (frequency.QuadPart / 10);`\nthat overflows after 292 years (already more than enough)\nor better simpler and faster computation\n`return (now.QuadPart * 125) / (frequency.QuadPart / 8);`\nthat overflows after 234 years","commit_id":"206024f0dbc8030f03edca1cf03b7e5b2d94dabe"},{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"4461cc6361910f6dcf6bc248d076812d65223298","unresolved":true,"context_lines":[{"line_number":41,"context_line":"\t\treturn -1;"},{"line_number":42,"context_line":"\tif (!QueryPerformanceCounter(\u0026now))"},{"line_number":43,"context_line":"\t\treturn -1;"},{"line_number":44,"context_line":"\treturn (now.QuadPart * 1000) / frequency.QuadPart;"},{"line_number":45,"context_line":"#elif defined(HAVE_CLOCK_GETTIME)"},{"line_number":46,"context_line":"#ifdef CLOCK_MONOTONIC_RAW"},{"line_number":47,"context_line":"\tclockid_t clk_id \u003d CLOCK_MONOTONIC_RAW;"}],"source_content_type":"text/x-csrc","patch_set":2,"id":"c8dc3506_e9c8f91e","line":44,"range":{"start_line":44,"start_character":9,"end_line":44,"end_character":28},"in_reply_to":"4d67f527_0819df0d","updated":"2026-06-23 15:34:03.000000000","message":"If we go for such cryptic computations, a comment above it should report the initial formula and explains why we tortured it.","commit_id":"206024f0dbc8030f03edca1cf03b7e5b2d94dabe"},{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"fd135592954e86a3116fcbada042a77c8e7d8073","unresolved":true,"context_lines":[{"line_number":41,"context_line":"\t\treturn -1;"},{"line_number":42,"context_line":"\tif (!QueryPerformanceCounter(\u0026now))"},{"line_number":43,"context_line":"\t\treturn -1;"},{"line_number":44,"context_line":"\treturn (now.QuadPart * 1000) / frequency.QuadPart;"},{"line_number":45,"context_line":"#elif defined(HAVE_CLOCK_GETTIME)"},{"line_number":46,"context_line":"#ifdef CLOCK_MONOTONIC_RAW"},{"line_number":47,"context_line":"\tclockid_t clk_id \u003d CLOCK_MONOTONIC_RAW;"}],"source_content_type":"text/x-csrc","patch_set":2,"id":"a42ccc80_1a13a743","line":44,"range":{"start_line":44,"start_character":9,"end_line":44,"end_character":28},"in_reply_to":"7188a86d_cb55afa2","updated":"2026-06-24 08:32:25.000000000","message":"Yes, but that would use two divisions and one module. This function is called very often and the overhead could be significant.\nSince `frequency` does not change, I was even looking for a way to store `N/frequency` to drop the divisions at runtime.\n```\nuint64_t period \u003d (1000 \u003c\u003c N) / frequency.QuadPart;\n...\n// computation in 64 bits thanks to \u0027period\u0027 being uint64_t\n#if N \u003c 32\nreturn (now.HighPart * period) \u003c\u003c (32 - N) + (now.LowPart * period) \u003e\u003e N;\n#else\nreturn (now.HighPart * period) \u003e\u003e (N - 32) + (now.LowPart * period) \u003e\u003e N;\n#endif\n```\nAt 10 MHz:\n- The high part multiplication (HighPart is 32 bit signed, but positive) will overflow for `N \u003d 62.9999`.\n- The low part multiplication (LowPart is 32 bit unsigned) will overflow for `N \u003d 61.9999`.\n\nSo `N \u003c\u003d 61`  is key.\nBut the returned value in ms is the sum of two truncated shifts, so accuracy is bad.\nTo improve accuracy and to simplify the computation, I use below `N \u003d 48 \u003d (32 + 16)` and I split the shift in two steps of 32 and 16:\n`return (now.HighPart * period + (now.LowPart * period) \u003e\u003e 32) \u003e\u003e 16;`","commit_id":"206024f0dbc8030f03edca1cf03b7e5b2d94dabe"},{"author":{"_account_id":1002286,"name":"Grant Ramsay","email":"grant.ramsay@hotmail.com","username":"gramsay0"},"change_message_id":"2dae1555d335032dcaa3e151c4ab1a2513fbfdb0","unresolved":true,"context_lines":[{"line_number":41,"context_line":"\t\treturn -1;"},{"line_number":42,"context_line":"\tif (!QueryPerformanceCounter(\u0026now))"},{"line_number":43,"context_line":"\t\treturn -1;"},{"line_number":44,"context_line":"\treturn (now.QuadPart * 1000) / frequency.QuadPart;"},{"line_number":45,"context_line":"#elif defined(HAVE_CLOCK_GETTIME)"},{"line_number":46,"context_line":"#ifdef CLOCK_MONOTONIC_RAW"},{"line_number":47,"context_line":"\tclockid_t clk_id \u003d CLOCK_MONOTONIC_RAW;"}],"source_content_type":"text/x-csrc","patch_set":2,"id":"93a00f2f_085f78b9","line":44,"range":{"start_line":44,"start_character":9,"end_line":44,"end_character":28},"in_reply_to":"a42ccc80_1a13a743","updated":"2026-06-24 23:24:26.000000000","message":"The divide/modulo method I suggested is also used in other projects:\n\nLLVM/Clang for C++ `std::chrono::steady_clock`: https://github.com/llvm/llvm-project/blob/6cc609bb250b21b47fc7d394b4019101e9983597/libcxx/src/chrono.cpp#L205\n\ncURL for timeouts/delays: https://github.com/curl/curl/blob/bf29c3e17544ff13c67e94157e6440662317355b/lib/curlx/timeval.c#L45\n\nMinGW for `clock_gettime(CLOCK_MONOTONIC, ...)`: https://github.com/mirror/mingw-w64/blob/master/mingw-w64-libraries/winpthreads/src/clock.c#L154\n\nI agree that fixed-point math would improve performance if this is a bottleneck","commit_id":"206024f0dbc8030f03edca1cf03b7e5b2d94dabe"},{"author":{"_account_id":1002286,"name":"Grant Ramsay","email":"grant.ramsay@hotmail.com","username":"gramsay0"},"change_message_id":"a84b4bc7d6a20c2fa4b113a83f4cdb8aa199043e","unresolved":true,"context_lines":[{"line_number":41,"context_line":"\t\treturn -1;"},{"line_number":42,"context_line":"\tif (!QueryPerformanceCounter(\u0026now))"},{"line_number":43,"context_line":"\t\treturn -1;"},{"line_number":44,"context_line":"\treturn (now.QuadPart * 1000) / frequency.QuadPart;"},{"line_number":45,"context_line":"#elif defined(HAVE_CLOCK_GETTIME)"},{"line_number":46,"context_line":"#ifdef CLOCK_MONOTONIC_RAW"},{"line_number":47,"context_line":"\tclockid_t clk_id \u003d CLOCK_MONOTONIC_RAW;"}],"source_content_type":"text/x-csrc","patch_set":2,"id":"7188a86d_cb55afa2","line":44,"range":{"start_line":44,"start_character":9,"end_line":44,"end_character":28},"in_reply_to":"c8dc3506_e9c8f91e","updated":"2026-06-23 21:32:22.000000000","message":"Maybe it could split into seconds and remainder before scaling up to milliseconds:\n```\nint64_t seconds \u003d now.QuadPart / frequency.QuadPart;\nint64_t remainder \u003d now.QuadPart % frequency.QuadPart;\nreturn (seconds * 1000) + (remainder * 1000 / frequency.QuadPart);\n```","commit_id":"206024f0dbc8030f03edca1cf03b7e5b2d94dabe"},{"author":{"_account_id":1000021,"name":"Antonio Borneo","email":"borneo.antonio@gmail.com","username":"borneoa"},"change_message_id":"1cc6f841826bf2baceeb4f2a45542a62f3045a56","unresolved":true,"context_lines":[{"line_number":41,"context_line":"\t\treturn -1;"},{"line_number":42,"context_line":"\tif (!QueryPerformanceCounter(\u0026now))"},{"line_number":43,"context_line":"\t\treturn -1;"},{"line_number":44,"context_line":"\treturn (now.QuadPart * 1000) / frequency.QuadPart;"},{"line_number":45,"context_line":"#elif defined(HAVE_CLOCK_GETTIME)"},{"line_number":46,"context_line":"#ifdef CLOCK_MONOTONIC_RAW"},{"line_number":47,"context_line":"\tclockid_t clk_id \u003d CLOCK_MONOTONIC_RAW;"}],"source_content_type":"text/x-csrc","patch_set":2,"id":"43fb3554_43bee3d7","line":44,"range":{"start_line":44,"start_character":9,"end_line":44,"end_character":28},"in_reply_to":"d764f2a8_53f8395c","updated":"2026-06-23 15:26:04.000000000","message":"With a less accurate computation\n`return now.QuadPart / (frequency.QuadPart / 1000);`\nit will overflow after 29247 years.\n(BTW, I compute 29.247 years with current code, not 27 !)","commit_id":"206024f0dbc8030f03edca1cf03b7e5b2d94dabe"}]}
