[*] Improved high resolution timing on Windows 7, Windows 10 < RS4, and Windows10 >= RS4/Win11

Win7 test:
[2024-09-10 07:09:31] [Debug]  | Waiting 750 overshoot: 103600 NS
[2024-09-10 07:09:31] [Debug]  | bret: true
[2024-09-10 07:09:31] [Debug]  | Waiting 750 overshoot: 145200 NS
[2024-09-10 07:09:32] [Debug]  | bret: true
[2024-09-10 07:09:32] [Debug]  | Waiting 750 overshoot: 100000 NS
[2024-09-10 07:09:33] [Debug]  | bret: true
[2024-09-10 07:09:33] [Debug]  | Waiting 750 overshoot: 88000 NS
[2024-09-10 07:09:34] [Debug]  | bret: true
[2024-09-10 07:09:34] [Debug]  | Waiting 750 overshoot: 114500 NS
[2024-09-10 07:09:34] [Debug]  | bret: true
[2024-09-10 07:09:34] [Debug]  | Waiting 750 overshoot: 85000 NS
[2024-09-10 07:09:35] [Debug]  | bret: true
[2024-09-10 07:09:35] [Debug]  | Waiting 750 overshoot: 133500 NS
[2024-09-10 07:09:36] [Debug]  | bret: true
[2024-09-10 07:09:36] [Debug]  | Waiting 750 overshoot: 137600 NS
[2024-09-10 07:09:36] [Debug]  | bret: true
[2024-09-10 07:09:36] [Debug]  | Waiting 750 overshoot: 111800 NS
[2024-09-10 07:09:37] [Debug]  | bret: true
[2024-09-10 07:09:37] [Debug]  | Waiting 750 overshoot: 103100 NS
[2024-09-10 07:09:38] [Debug]  | bret: true
[2024-09-10 07:09:38] [Debug]  | Waiting 750 overshoot: 132100 NS
[2024-09-10 07:09:39] [Debug]  | bret: true
[2024-09-10 07:09:39] [Debug]  | Waiting 750 overshoot: 87900 NS
[2024-09-10 07:09:39] [Debug]  | bret: true
[2024-09-10 07:09:39] [Debug]  | Waiting 750 overshoot: 105000 NS
[2024-09-10 07:09:40] [Debug]  | Waiting 250 overshoot: 59100 NS
[2024-09-10 07:09:40] [Debug]  | Waiting 250 overshoot: 95000 NS
[2024-09-10 07:09:40] [Debug]  | Waiting 250 overshoot: 116100 NS
[2024-09-10 07:09:40] [Debug]  | Waiting 250 overshoot: 111600 NS
[2024-09-10 07:09:41] [Debug]  | Waiting 250 overshoot: 46600 NS
[2024-09-10 07:09:41] [Debug]  | Waiting 250 overshoot: 82300 NS
[2024-09-10 07:09:41] [Debug]  | Waiting 250 overshoot: 84700 NS
[2024-09-10 07:09:41] [Debug]  | Waiting 250 overshoot: 77400 NS
[2024-09-10 07:09:42] [Debug]  | Waiting 250 overshoot: 56500 NS
[2024-09-10 07:09:42] [Debug]  | Waiting 250 overshoot: 88500 NS
[2024-09-10 07:09:42] [Debug]  | Waiting 250 overshoot: 67100 NS
[2024-09-10 07:09:42] [Debug]  | Waiting 250 overshoot: 69200 NS
[2024-09-10 07:09:43] [Debug]  | Waiting 250 overshoot: 52500 NS
[2024-09-10 07:09:43] [Debug]  | Waiting 250 overshoot: 87300 NS
[2024-09-10 07:09:43] [Debug]  | Waiting 250 overshoot: 66600 NS
[2024-09-10 07:09:43] [Debug]  | Waiting 250 overshoot: 83700 NS
[2024-09-10 07:09:44] [Debug]  | Waiting 250 overshoot: 79700 NS
[2024-09-10 07:09:44] [Debug]  | Waiting 250 overshoot: 60300 NS
[2024-09-10 07:09:44] [Debug]  | Waiting 250 overshoot: 116800 NS
[2024-09-10 07:09:44] [Debug]  | Waiting 250 overshoot: 80500 NS
[2024-09-10 07:09:46] [Debug]  | Waiting 1250 overshoot: 75800 NS
[2024-09-10 07:09:47] [Debug]  | Waiting 1250 overshoot: 87500 NS
[2024-09-10 07:09:48] [Debug]  | Waiting 1250 overshoot: 5367700 NS
[2024-09-10 07:09:49] [Debug]  | Waiting 1250 overshoot: 103200 NS
[2024-09-10 07:09:51] [Debug]  | Waiting 1250 overshoot: 7424400 NS
[2024-09-10 07:09:52] [Debug]  | Waiting 1250 overshoot: 5281800 NS
[2024-09-10 07:09:53] [Debug]  | Waiting 1250 overshoot: 5673100 NS
[2024-09-10 07:09:54] [Debug]  | Waiting 1250 overshoot: 10185700 NS
[2024-09-10 07:09:55] [Debug]  | Waiting 1250 overshoot: 12369200 NS
[2024-09-10 07:09:57] [Debug]  | Waiting 1250 overshoot: 75800 NS
[2024-09-10 07:09:58] [Debug]  | Waiting 1250 overshoot: 96900 NS
[2024-09-10 07:09:59] [Debug]  | Waiting 1250 overshoot: 3663000 NS
[2024-09-10 07:10:00] [Debug]  | Waiting 1250 overshoot: 11713900 NS
[2024-09-10 07:10:02] [Debug]  | Waiting 1250 overshoot: 138500 NS
[2024-09-10 07:10:03] [Debug]  | Waiting 1250 overshoot: 9764800 NS
[2024-09-10 07:10:04] [Debug]  | Waiting 1250 overshoot: 8398700 NS
[2024-09-10 07:10:05] [Debug]  | Waiting 1250 overshoot: 8862000 NS
[2024-09-10 07:10:07] [Debug]  | Waiting 1250 overshoot: 3616900 NS
[2024-09-10 07:10:08] [Debug]  | Waiting 1250 overshoot: 6343400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1250 overshoot: 9492100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 111900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 115700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 137100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 135000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 219300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 127700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 87900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 862200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 107200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 80000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 69800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 230000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 72400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 67100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 89000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 80400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 73200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 58100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 64100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 5 overshoot: 55700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 75100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 59900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 56100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 57300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 141700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 1089800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 183100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 328500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 80200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 72200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 74800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 67900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 74000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 65400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 83400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 85500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 74600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 73200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 79300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 10 overshoot: 74100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 77800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 93200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 71000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 71300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 80700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 90700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 95200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 81500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 79300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 90600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 104000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 99400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 89600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 106500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 107800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 104300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 105300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 103900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 72900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 1 overshoot: 112300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 109600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 112800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 75700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 103900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 104800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 109600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 126700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 110700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 108500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 96900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 111200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 118800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 115800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 137200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 65200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 233800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 106300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 126500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 105100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting 2 overshoot: 104600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 106300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 107200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 107000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 102300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 97600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 95800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 104800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 115900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 104900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 114200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 108900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 117400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 106400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 118400 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 348300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 113300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 125600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 111800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 106300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .6 overshoot: 106700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 108000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 82100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 116500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 96500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 99100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 78000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 87500 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 103100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 99100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 114000 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 87800 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 101600 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 89300 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 76100 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 75700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 75900 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 90200 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 94700 NS
[2024-09-10 07:10:09] [Debug]  | Waiting .3 overshoot: 88000 NS
-----------------------------------------------------------------
[2024-09-10 07:16:32] [Debug]  | bret: true
[2024-09-10 07:16:32] [Debug]  | Waiting 750 overshoot: 65200 NS
[2024-09-10 07:16:33] [Debug]  | bret: true
[2024-09-10 07:16:33] [Debug]  | Waiting 750 overshoot: 73900 NS
[2024-09-10 07:16:34] [Debug]  | bret: true
[2024-09-10 07:16:34] [Debug]  | Waiting 750 overshoot: 66800 NS
[2024-09-10 07:16:34] [Debug]  | bret: true
[2024-09-10 07:16:34] [Debug]  | Waiting 750 overshoot: 63800 NS
[2024-09-10 07:16:35] [Debug]  | bret: true
[2024-09-10 07:16:35] [Debug]  | Waiting 750 overshoot: 84200 NS
[2024-09-10 07:16:36] [Debug]  | bret: true
[2024-09-10 07:16:36] [Debug]  | Waiting 750 overshoot: 138500 NS
[2024-09-10 07:16:37] [Debug]  | bret: true
[2024-09-10 07:16:37] [Debug]  | Waiting 750 overshoot: 85000 NS
[2024-09-10 07:16:37] [Debug]  | bret: true
[2024-09-10 07:16:37] [Debug]  | Waiting 750 overshoot: 71900 NS
[2024-09-10 07:16:38] [Debug]  | bret: true
[2024-09-10 07:16:38] [Debug]  | Waiting 750 overshoot: 81400 NS
[2024-09-10 07:16:39] [Debug]  | bret: true
[2024-09-10 07:16:39] [Debug]  | Waiting 750 overshoot: 65600 NS
[2024-09-10 07:16:40] [Debug]  | bret: true
[2024-09-10 07:16:40] [Debug]  | Waiting 750 overshoot: 60400 NS
[2024-09-10 07:16:40] [Debug]  | bret: true
[2024-09-10 07:16:40] [Debug]  | Waiting 750 overshoot: 77400 NS
[2024-09-10 07:16:41] [Debug]  | bret: true
[2024-09-10 07:16:41] [Debug]  | Waiting 750 overshoot: 81500 NS
[2024-09-10 07:16:42] [Debug]  | bret: true
[2024-09-10 07:16:42] [Debug]  | Waiting 750 overshoot: 91600 NS
[2024-09-10 07:16:43] [Debug]  | bret: true
[2024-09-10 07:16:43] [Debug]  | Waiting 750 overshoot: 148500 NS
[2024-09-10 07:16:43] [Debug]  | bret: true
[2024-09-10 07:16:43] [Debug]  | Waiting 750 overshoot: 75600 NS
[2024-09-10 07:16:44] [Debug]  | bret: true
[2024-09-10 07:16:44] [Debug]  | Waiting 750 overshoot: 112200 NS
[2024-09-10 07:16:45] [Debug]  | bret: true
[2024-09-10 07:16:45] [Debug]  | Waiting 750 overshoot: 102700 NS
[2024-09-10 07:16:46] [Debug]  | bret: true
[2024-09-10 07:16:46] [Debug]  | Waiting 750 overshoot: 103700 NS
[2024-09-10 07:16:46] [Debug]  | Waiting 250 overshoot: 96700 NS
[2024-09-10 07:16:46] [Debug]  | Waiting 250 overshoot: 101500 NS
[2024-09-10 07:16:46] [Debug]  | Waiting 250 overshoot: 59100 NS
[2024-09-10 07:16:47] [Debug]  | Waiting 250 overshoot: 73500 NS
[2024-09-10 07:16:47] [Debug]  | Waiting 250 overshoot: 89700 NS
[2024-09-10 07:16:47] [Debug]  | Waiting 250 overshoot: 65900 NS
[2024-09-10 07:16:47] [Debug]  | Waiting 250 overshoot: 53600 NS
[2024-09-10 07:16:48] [Debug]  | Waiting 250 overshoot: 117200 NS
[2024-09-10 07:16:48] [Debug]  | Waiting 250 overshoot: 133600 NS
[2024-09-10 07:16:48] [Debug]  | Waiting 250 overshoot: 65700 NS
[2024-09-10 07:16:48] [Debug]  | Waiting 250 overshoot: 60900 NS
[2024-09-10 07:16:49] [Debug]  | Waiting 250 overshoot: 76400 NS
[2024-09-10 07:16:49] [Debug]  | Waiting 250 overshoot: 77000 NS
[2024-09-10 07:16:49] [Debug]  | Waiting 250 overshoot: 115700 NS
[2024-09-10 07:16:49] [Debug]  | Waiting 250 overshoot: 45000 NS
[2024-09-10 07:16:50] [Debug]  | Waiting 250 overshoot: 73000 NS
[2024-09-10 07:16:50] [Debug]  | Waiting 250 overshoot: 75400 NS
[2024-09-10 07:16:50] [Debug]  | Waiting 250 overshoot: 95300 NS
[2024-09-10 07:16:50] [Debug]  | Waiting 250 overshoot: 164200 NS
[2024-09-10 07:16:51] [Debug]  | Waiting 250 overshoot: 97600 NS
[2024-09-10 07:16:52] [Debug]  | Waiting 1250 overshoot: 274900 NS
[2024-09-10 07:16:53] [Debug]  | Waiting 1250 overshoot: 121300 NS
[2024-09-10 07:16:54] [Debug]  | Waiting 1250 overshoot: 61100 NS
[2024-09-10 07:16:55] [Debug]  | Waiting 1250 overshoot: 172200 NS
[2024-09-10 07:16:57] [Debug]  | Waiting 1250 overshoot: 75700 NS
[2024-09-10 07:16:58] [Debug]  | Waiting 1250 overshoot: 218500 NS
[2024-09-10 07:16:59] [Debug]  | Waiting 1250 overshoot: 172700 NS
[2024-09-10 07:17:00] [Debug]  | Waiting 1250 overshoot: 87200 NS
[2024-09-10 07:17:02] [Debug]  | Waiting 1250 overshoot: 197300 NS
[2024-09-10 07:17:03] [Debug]  | Waiting 1250 overshoot: 213600 NS
[2024-09-10 07:17:04] [Debug]  | Waiting 1250 overshoot: 388600 NS
[2024-09-10 07:17:05] [Debug]  | Waiting 1250 overshoot: 85200 NS
[2024-09-10 07:17:07] [Debug]  | Waiting 1250 overshoot: 91900 NS
[2024-09-10 07:17:08] [Debug]  | Waiting 1250 overshoot: 176100 NS
[2024-09-10 07:17:09] [Debug]  | Waiting 1250 overshoot: 7844400 NS
[2024-09-10 07:17:10] [Debug]  | Waiting 1250 overshoot: 145600 NS
[2024-09-10 07:17:11] [Debug]  | Waiting 1250 overshoot: 61100 NS
[2024-09-10 07:17:13] [Debug]  | Waiting 1250 overshoot: 94400 NS
[2024-09-10 07:17:14] [Debug]  | Waiting 1250 overshoot: 94400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1250 overshoot: 101800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 81100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 96800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 97500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 43600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 60000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 62400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 74500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 96600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 93800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 74500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 87900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 102600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 61600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 55200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 57200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 83600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 53300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 56000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 58900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 5 overshoot: 91000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 96500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 51900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 322800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 82600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 140300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 334400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 317200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 110800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 318200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 102800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 141000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 84000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 190100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 69100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 104300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 84500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 123400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 77500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 57300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 10 overshoot: 59000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 41000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 31900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 86100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 54100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 201000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 43800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 47300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 62900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 56000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 58700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 40900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 55800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 57500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 33900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 39100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 40500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 40100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 65400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 77500 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 1 overshoot: 27000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 57700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 50100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 63100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 62400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 74200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 59000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 39000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 56700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 67200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 445400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 60900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 46600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 48800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 39400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 35000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 52400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 41100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 38000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 36000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting 2 overshoot: 41400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 36800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 36900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 30400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 61000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 36800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 48700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 30000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 31400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 41100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 25700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 37900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 36700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 31300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 30700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 27600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 29200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 28600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 28800 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 47200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .6 overshoot: 28300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 28900 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 29700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 28700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 28000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 27400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 28100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 26100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 28100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 28000 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 29200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 29700 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 29300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 27100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 26600 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 28100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 28200 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 27300 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 27400 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 30100 NS
[2024-09-10 07:17:15] [Debug]  | Waiting .3 overshoot: 35100 NS
This commit is contained in:
Reece Wilson 2024-09-10 08:14:54 +01:00
parent ffb1cbb09b
commit 6852fbddf1
7 changed files with 268 additions and 41 deletions

View File

@ -40,6 +40,8 @@ namespace Aurora::Async
static AuUInt64 uNextSysTickGuessed {}; static AuUInt64 uNextSysTickGuessed {};
static AuUInt64 uNextWakeuptimeRateLimit {}; static AuUInt64 uNextWakeuptimeRateLimit {};
static AuBST<AuUInt64, SchedEntry> gOrderedEntries; static AuBST<AuUInt64, SchedEntry> gOrderedEntries;
static AuUInt32 uScheduledHighPerfTimers {};
// prevents stupid tick issues // prevents stupid tick issues
static bool gLockedPump = false; static bool gLockedPump = false;
@ -146,16 +148,70 @@ namespace Aurora::Async
uNextSysTickGuessed = 0; uNextSysTickGuessed = 0;
#if !defined(SCHEDULER_USE_NO_SPIN) #if !defined(SCHEDULER_USE_NO_SPIN)
gSchedCondvar->WaitForSignalNS(uNextTick - uNow);
auto uNS = uNextTick - uNow;
#if defined(AURORA_IS_MODERNNT_DERIVED)
bool bExpensivePath = AuAtomicLoad(&uScheduledHighPerfTimers);
bool bWin10sABinch {};
if (!AuSwInfo::IsWindows8Point1OrGreater())
{
if (gRuntimeConfig.threadingConfig.bEnableAggressiveScheduling)
{
if (uNS <= AuMSToNS<AuUInt64>(3))
{
bExpensivePath = true;
}
else if (uNS < AuMSToNS<AuUInt64>(1'000) &&
uNS > AuMSToNS<AuUInt64>(100) &&
!bExpensivePath)
{
// Windows 7 coalescing doesnt batch very well.
// We overshoot by ~6MS or 8MS, if we're above ~20MS
uNS -= AuMSToNS<AuUInt64>(10);
}
}
}
else
{
// Windows 10-11 will coalesce us less, but our precision is an order of mangitude worse than what I can get out of Windows 7
if (bExpensivePath)
{
bWin10sABinch = true;
bExpensivePath = false;
}
}
if (bExpensivePath)
{
// With any luck, we'll be scheduled within 0.02MS of error with some spikes to .3MS.
gSchedLock->Unlock();
AuThreading::SleepNs(uNS);
gSchedLock->Lock();
}
else if (bWin10sABinch)
{
// With any luck, we'll be scheduled within 0.3MS of error, maybe a little bit lower for some fraction of a MS requests.
Win32DropSchedulerResolutionForced();
gSchedCondvar->WaitForSignalNS(uNS);
Win32DropSchedulerResolutionForcedUndo();
}
else
#endif
{
gSchedCondvar->WaitForSignalNS(uNS);
}
#else #else
gSchedCondvar.WaitForSignalNsEx(&AuStaticCast<AuThreadPrimitives::ConditionMutexImpl>(gSchedLock.AsPointer())->mutex, uNextTick - uNow, false); gSchedCondvar.WaitForSignalNsEx(&AuStaticCast<AuThreadPrimitives::ConditionMutexImpl>(gSchedLock.AsPointer())->mutex, uNextTick - uNow, false);
#endif #endif
} }
else if (uNow >= uNextTick) else if (uNow >= uNextTick && uNextSysTickGuessed != 0)
{ {
uNextSysTickGuessed = 0; uNextSysTickGuessed = 0;
} }
else if (uNextSysTickGuessed == 0) else if (uNextSysTickGuessed == 0 && gOrderedEntries.empty())
{ {
#if !defined(SCHEDULER_USE_NO_SPIN) #if !defined(SCHEDULER_USE_NO_SPIN)
gSchedCondvar->WaitForSignalNS(gRuntimeConfig.async.bEnableLegacyTicks ? gSchedCondvar->WaitForSignalNS(gRuntimeConfig.async.bEnableLegacyTicks ?
@ -190,6 +246,7 @@ namespace Aurora::Async
{ {
// IO timer hack! // IO timer hack!
entry.runnable->RunAsync(); entry.runnable->RunAsync();
AuAtomicSub(&uScheduledHighPerfTimers, 1u);
} }
} }
catch (...) catch (...)
@ -293,6 +350,10 @@ namespace Aurora::Async
{ {
AuAtomicAdd(&pool->uAtomicCounter, 1u); AuAtomicAdd(&pool->uAtomicCounter, 1u);
} }
else
{
AuAtomicAdd(&uScheduledHighPerfTimers, 1u);
}
SchedNextTime(ns); SchedNextTime(ns);
return AuTryInsert(gOrderedEntries, return AuTryInsert(gOrderedEntries,
AuConstReference(ns), AuConstReference(ns),

View File

@ -38,7 +38,9 @@ namespace Aurora::Memory
namespace Aurora namespace Aurora
{ {
static bool gShouldResPathDoNothing {}; static bool gShouldResPathDoNothing {}; // always
static bool gShouldResPathDoNothing2 {}; // win11 singleshot
static ULONG gLastActualResolution {};
#if !defined(AURORA_PLATFORM_WIN32) #if !defined(AURORA_PLATFORM_WIN32)
HMODULE UWPLibraryW(LPCWSTR lpLibFileName); HMODULE UWPLibraryW(LPCWSTR lpLibFileName);
@ -264,6 +266,7 @@ namespace Aurora
ADD_GET_PROC(Nt, RtlWakeByAddressAll) ADD_GET_PROC(Nt, RtlWakeByAddressAll)
ADD_GET_PROC(Nt, RtlWakeAddressSingle) ADD_GET_PROC(Nt, RtlWakeAddressSingle)
ADD_GET_PROC(Nt, ZwSetTimerResolution) ADD_GET_PROC(Nt, ZwSetTimerResolution)
ADD_GET_PROC(Nt, ZwQueryTimerResolution)
ADD_GET_PROC(Nt, NtQueryInformationProcess) ADD_GET_PROC(Nt, NtQueryInformationProcess)
ADD_GET_PROC(Nt, NtNotifyChangeDirectoryFile) ADD_GET_PROC(Nt, NtNotifyChangeDirectoryFile)
ADD_GET_PROC(Nt, NtTerminateProcess) ADD_GET_PROC(Nt, NtTerminateProcess)
@ -310,6 +313,7 @@ namespace Aurora
ADD_GET_PROC(Kernel32, Module32FirstW) ADD_GET_PROC(Kernel32, Module32FirstW)
ADD_GET_PROC(Kernel32, Module32NextW) ADD_GET_PROC(Kernel32, Module32NextW)
ADD_GET_PROC(Kernel32, CreateJobObjectW) ADD_GET_PROC(Kernel32, CreateJobObjectW)
ADD_GET_PROC(Kernel32, CreateWaitableTimerExW)
ADD_GET_PROC(Kernel32, GetConsoleScreenBufferInfo) ADD_GET_PROC(Kernel32, GetConsoleScreenBufferInfo)
ADD_GET_PROC(Kernel32, SetConsoleScreenBufferSize) ADD_GET_PROC(Kernel32, SetConsoleScreenBufferSize)
@ -563,6 +567,8 @@ namespace Aurora
return bool(GetEnvironmentVariableW(L"AURORA_IS_NETBOOK", nullptr, 0)); return bool(GetEnvironmentVariableW(L"AURORA_IS_NETBOOK", nullptr, 0));
} }
void Win32DropSchedulerResolutionNow();
void Win32DropInit() void Win32DropInit()
{ {
gShouldResPathDoNothing = gShouldResPathDoNothing =
@ -577,6 +583,8 @@ namespace Aurora
#endif #endif
; ;
gShouldResPathDoNothing2 = gShouldResPathDoNothing;
if (gShouldResPathDoNothing) if (gShouldResPathDoNothing)
{ {
return; return;
@ -596,29 +604,98 @@ namespace Aurora
powerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED; powerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
powerThrottling.StateMask = 0; powerThrottling.StateMask = 0;
gShouldResPathDoNothing = bool(pSetProcessInformation(GetCurrentProcess(), gShouldResPathDoNothing2 = bool(pSetProcessInformation(GetCurrentProcess(),
ProcessPowerThrottling,
&powerThrottling,
sizeof(powerThrottling)));
powerThrottling.ControlMask = PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION;
powerThrottling.StateMask = 0;
gShouldResPathDoNothing &= bool(pSetProcessInformation(GetCurrentProcess(),
ProcessPowerThrottling, ProcessPowerThrottling,
&powerThrottling, &powerThrottling,
sizeof(powerThrottling))); sizeof(powerThrottling)));
powerThrottling.ControlMask = PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION;
powerThrottling.StateMask = 0;
gShouldResPathDoNothing2 &= bool(pSetProcessInformation(GetCurrentProcess(),
ProcessPowerThrottling,
&powerThrottling,
sizeof(powerThrottling)));
if (!gShouldResPathDoNothing2 &&
(AuSWInfo::IsWindows11OrGreater() || AuSwInfo::IsWindows10Milestone20H1OrGreater()))
{
Win32DropSchedulerResolutionNow();
}
else
{
gShouldResPathDoNothing2 = false;
}
AuThreading::InitOnceLocker::Finish(&gInitOnce); AuThreading::InitOnceLocker::Finish(&gInitOnce);
} /* else no-wait. intentionally nop*/ } /* else no-wait. intentionally nop*/
} }
#endif #endif
} }
void Win32DropSchedulerResolutionForced()
{
ULONG ullActualResolution {};
if (!gShouldResPathDoNothing)
{
Win32DropSchedulerResolution();
return;
}
if (pZwQueryTimerResolution)
{
static AuInitOnce gInitOnce;
gInitOnce.Call([]()
{
ULONG IDC[2];
pZwQueryTimerResolution(&IDC[0], &IDC[1], &gLastActualResolution);
});
}
}
void Win32DropSchedulerResolutionNow()
{
ULONG ullActualResolution {};
if (!pZwSetTimerResolution)
{
return;
}
auto uRet = pZwSetTimerResolution(1, true, &ullActualResolution);
if (uRet == 0)
{
return;
}
else if (uRet == 0xC0000245)
{
if ((uRet = pZwSetTimerResolution(5'000, true, &ullActualResolution)) == 0)
{
return;
}
}
}
void Win32DropSchedulerResolutionForcedUndo()
{
ULONG ullActualResolution {};
if (!gShouldResPathDoNothing ||
!pZwSetTimerResolution ||
!gLastActualResolution)
{
return;
}
(void)pZwSetTimerResolution(gLastActualResolution, true, &ullActualResolution);
}
void Win32DropSchedulerResolution() void Win32DropSchedulerResolution()
{ {
ULONG ullActualResolution {}; ULONG ullActualResolution {};
if (gShouldResPathDoNothing) if (gShouldResPathDoNothing2)
{ {
return; return;
} }
@ -636,22 +713,7 @@ namespace Aurora
} }
} }
if (pZwSetTimerResolution) Win32DropSchedulerResolutionNow();
{
auto uRet = pZwSetTimerResolution(1, true, &ullActualResolution);
if (uRet == 0)
{
return;
}
else if (uRet == 0xC0000245)
{
if ((uRet = pZwSetTimerResolution(5'000, true, &ullActualResolution)) == 0)
{
return;
}
}
}
} }
HANDLE UWPCreateFileMappingA(HANDLE hFile, HANDLE UWPCreateFileMappingA(HANDLE hFile,

View File

@ -283,6 +283,13 @@ namespace Aurora
SIZE_T dwNumberOfBytesToMap SIZE_T dwNumberOfBytesToMap
); );
inline HANDLE(__stdcall *pCreateWaitableTimerExW)(
LPSECURITY_ATTRIBUTES lpTimerAttributes,
LPCWSTR lpTimerName,
DWORD dwFlags,
DWORD dwDesiredAccess
);
inline NTSTATUS(__stdcall *pNtNotifyChangeDirectoryFile)( inline NTSTATUS(__stdcall *pNtNotifyChangeDirectoryFile)(
HANDLE FileHandle, HANDLE FileHandle,
HANDLE Event, HANDLE Event,
@ -487,6 +494,12 @@ namespace Aurora
PULONG ActualResolution PULONG ActualResolution
); );
inline NTSTATUS(__stdcall *pZwQueryTimerResolution)(
PULONG CoarsestResolution,
PULONG FinestResolution,
PULONG ActualResolution
);
inline BOOLEAN(__stdcall *pRtlGenRandom)( inline BOOLEAN(__stdcall *pRtlGenRandom)(
PVOID RandomBuffer, PVOID RandomBuffer,
ULONG RandomBufferLength ULONG RandomBufferLength
@ -1371,6 +1384,8 @@ namespace Aurora
void Win32DropInit(); void Win32DropInit();
void Win32DropSchedulerResolution(); void Win32DropSchedulerResolution();
void Win32DropSchedulerResolutionForcedUndo();
void Win32DropSchedulerResolutionForced();
void Win32Terminate(); void Win32Terminate();

View File

@ -11,13 +11,24 @@
namespace Aurora::IO::Loop namespace Aurora::IO::Loop
{ {
LSTimer::LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, HANDLE handle) : static AuUInt32 gHighResTimers {};
LSTimer::LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, HANDLE handle, bool bHighRes) :
LSHandle(AuReinterpretCast<AuUInt>(handle)), LSHandle(AuReinterpretCast<AuUInt>(handle)),
reschedStepNsOrZero_(AuMSToNS<AuUInt64>(reschedStepMsOrZero)), reschedStepNsOrZero_(AuMSToNS<AuUInt64>(reschedStepMsOrZero)),
bSingleshot(bSingleshot), bSingleshot(bSingleshot),
maxIterationsOrZero_(maxIterationsOrZero) maxIterationsOrZero_(maxIterationsOrZero),
bHighRes_(bHighRes)
{ {
this->targetTime_ = AuTime::ConvertTimestamp(AuTime::CurrentClockMS()); this->targetTime_ = AuTime::ConvertTimestamp(AuTime::CurrentClockMS());
if (this->bHighRes_)
{
if (AuAtomicAdd(&gHighResTimers, 1u) == 1)
{
Win32DropSchedulerResolutionForced();
}
}
} }
LSTimer::~LSTimer() LSTimer::~LSTimer()
@ -25,6 +36,14 @@ namespace Aurora::IO::Loop
auto handle = AuReinterpretCast<HANDLE>(this->handle); auto handle = AuReinterpretCast<HANDLE>(this->handle);
AuWin32CloseHandle(handle); AuWin32CloseHandle(handle);
this->handle = kInvalidHandle; this->handle = kInvalidHandle;
if (this->bHighRes_)
{
if (AuAtomicSub(&gHighResTimers, 1u) == 0)
{
Win32DropSchedulerResolutionForcedUndo();
}
}
} }
void LSTimer::UpdateTimeWall(AuUInt64 absTimeMs) void LSTimer::UpdateTimeWall(AuUInt64 absTimeMs)
@ -132,9 +151,6 @@ namespace Aurora::IO::Loop
AuSPtr<ITimer> NewLSTimerOS(AuUInt64 absStartTimeMs, AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady) AuSPtr<ITimer> NewLSTimerOS(AuUInt64 absStartTimeMs, AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady)
{ {
// https://docs.microsoft.com/en-us/windows/win32/api/threadpoolapiset/nf-threadpoolapiset-setthreadpoolwait
// TODO: Is that any better with an event?
auto handle = CreateWaitableTimerW(nullptr, !bSingleshot, nullptr); auto handle = CreateWaitableTimerW(nullptr, !bSingleshot, nullptr);
if (!handle) if (!handle)
{ {
@ -142,7 +158,49 @@ namespace Aurora::IO::Loop
return {}; return {};
} }
auto object = AuMakeShared<LSTimer>(reschedStepMsOrZero, maxIterationsOrZero, bSingleshot, handle); auto object = AuMakeShared<LSTimer>(reschedStepMsOrZero, maxIterationsOrZero, bSingleshot, handle, false);
if (!object)
{
SysPushErrorMem();
AuWin32CloseHandle(handle);
return {};
}
if (absStartTimeMs)
{
if (bIsStartTimeSteady)
{
object->UpdateTimeSteady(absStartTimeMs);
}
else
{
object->UpdateTimeWall(absStartTimeMs);
}
}
return object;
}
AuSPtr<ITimer> NewLSTimerOSHiRes(AuUInt64 absStartTimeMs, AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady)
{
if (!AuSWInfo::IsWindows10MilestoneRS4OrGreater())
{
return {};
}
if (!pCreateWaitableTimerExW)
{
return {};
}
auto handle = pCreateWaitableTimerExW(nullptr, nullptr, (bSingleshot ? 0 : 1) | CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
if (!handle)
{
SysPushErrorIO();
return {};
}
auto object = AuMakeShared<LSTimer>(reschedStepMsOrZero, maxIterationsOrZero, bSingleshot, handle, true);
if (!object) if (!object)
{ {
SysPushErrorMem(); SysPushErrorMem();

View File

@ -12,7 +12,7 @@ namespace Aurora::IO::Loop
{ {
struct LSTimer : ITimer, virtual LSHandle struct LSTimer : ITimer, virtual LSHandle
{ {
LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, HANDLE handle); LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, HANDLE handle, bool bHighRes);
~LSTimer(); ~LSTimer();
PROXY_LOOP_LOOPSOURCE_EXT_APIS_; PROXY_LOOP_LOOPSOURCE_EXT_APIS_;
@ -38,5 +38,6 @@ namespace Aurora::IO::Loop
AuUInt64 targetTime_ {0}; AuUInt64 targetTime_ {0};
AuUInt32 count_ {0}; AuUInt32 count_ {0};
bool bSingleshot {}; bool bSingleshot {};
bool bHighRes_ {};
}; };
} }

View File

@ -12,6 +12,10 @@ namespace Aurora::IO::Loop
AuSPtr<ITimer> NewLSTimerOS(AuUInt64 qwAbsStartTimeMs, AuUInt32 dwReschedStepMsOrZero, AuUInt32 dwMaxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady); AuSPtr<ITimer> NewLSTimerOS(AuUInt64 qwAbsStartTimeMs, AuUInt32 dwReschedStepMsOrZero, AuUInt32 dwMaxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady);
AuSPtr<ITimer> NewLSTimerIP(AuUInt64 qwAbsStartTimeMs, AuUInt32 dwReschedStepMsOrZero, AuUInt32 dwMaxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady); AuSPtr<ITimer> NewLSTimerIP(AuUInt64 qwAbsStartTimeMs, AuUInt32 dwReschedStepMsOrZero, AuUInt32 dwMaxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady);
#if defined(AURORA_IS_MODERNNT_DERIVED)
AuSPtr<ITimer> NewLSTimerOSHiRes(AuUInt64 absStartTimeMs, AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady);
#endif
static bool MustUseAltTimer() static bool MustUseAltTimer()
{ {
return gRuntimeConfig.ioConfig.bForceAltOSTimerPrimitives; return gRuntimeConfig.ioConfig.bForceAltOSTimerPrimitives;
@ -28,6 +32,13 @@ namespace Aurora::IO::Loop
AUKN_SYM AuSPtr<ITimer> NewLSTimerHighResolution(AuUInt64 qwAbsStartTimeMs, AuUInt32 dwReschedStepMsOrZero, AuUInt32 dwMaxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady) AUKN_SYM AuSPtr<ITimer> NewLSTimerHighResolution(AuUInt64 qwAbsStartTimeMs, AuUInt32 dwReschedStepMsOrZero, AuUInt32 dwMaxIterationsOrZero, bool bSingleshot, bool bIsStartTimeSteady)
{ {
#if defined(AURORA_IS_MODERNNT_DERIVED)
if (auto pHighResIO = NewLSTimerOSHiRes(qwAbsStartTimeMs, dwReschedStepMsOrZero, dwMaxIterationsOrZero, bSingleshot, bIsStartTimeSteady))
{
return pHighResIO;
}
#endif
if (IsHPInProcess()) if (IsHPInProcess())
{ {
return NewLSTimerIP(qwAbsStartTimeMs, dwReschedStepMsOrZero, dwMaxIterationsOrZero, bSingleshot, bIsStartTimeSteady); return NewLSTimerIP(qwAbsStartTimeMs, dwReschedStepMsOrZero, dwMaxIterationsOrZero, bSingleshot, bIsStartTimeSteady);

View File

@ -84,9 +84,21 @@ namespace Aurora::Threading
return; return;
} }
if (qwTimeout < AuMSToNS<AuUInt64>(1)) if (qwTimeout > AuMSToNS<AuUInt64>(60))
{ {
uEndTimeSteadyNS -= 250'000ull; uEndTimeSteadyNS -= 20'000'000ull;
}
else if (qwTimeout > AuMSToNS<AuUInt64>(40))
{
uEndTimeSteadyNS -= 10'000'000ull;
}
else if (qwTimeout > AuMSToNS<AuUInt64>(10))
{
uEndTimeSteadyNS -= 4'000'000ull;
}
else if (qwTimeout < AuMSToNS<AuUInt64>(1'300))
{
uEndTimeSteadyNS -= 500'000ull;
} }
Win32DropSchedulerResolution(); Win32DropSchedulerResolution();
@ -95,7 +107,7 @@ namespace Aurora::Threading
{ {
if (qwTimeout < AuMSToNS<AuUInt64>(1)) if (qwTimeout < AuMSToNS<AuUInt64>(1))
{ {
uEndTimeSteadyNS -= 100'000ull; uEndTimeSteadyNS -= 250'000ull;
} }
} }
#endif #endif
@ -109,7 +121,7 @@ namespace Aurora::Threading
#else #else
if (AuThreadPrimitives::ThrdCfg::gPlatformIsSMPProcessorOptimized) if (AuThreadPrimitives::ThrdCfg::gPlatformIsSMPProcessorOptimized)
{ {
if (uEndTimeSteadyNS2 - uNowNS <= 100000ull) if (uEndTimeSteadyNS2 - uNowNS <= 230000ull)
{ {
auto uNow = AuAtomicAdd(&AuThreadPrimitives::gSpinAdaptiveCurrentCount, 1u); auto uNow = AuAtomicAdd(&AuThreadPrimitives::gSpinAdaptiveCurrentCount, 1u);
if (!AuThreadPrimitives::gSpinAdaptiveThreshold || uNow <= AuThreadPrimitives::gSpinAdaptiveThreshold) if (!AuThreadPrimitives::gSpinAdaptiveThreshold || uNow <= AuThreadPrimitives::gSpinAdaptiveThreshold)
@ -203,7 +215,14 @@ namespace Aurora::Threading
} }
else else
{ {
break; if (!uEndTimeSteadyNS)
{
ContextYield();
}
else
{
break;
}
} }
} }
#endif #endif