4
4
* Copyright (C) 2015-2020 IPONWEB Ltd. See Copyright Notice in COPYRIGHT
5
5
*/
6
6
7
+ #include <time.h>
7
8
#include <unistd.h>
8
9
#include "test_common_lua.h"
9
10
10
- #define EPSILON 1e-1
11
+ #define EPSILON 1e-6
12
+
13
+ /* Clock emulation {{{ */
14
+
15
+ /*
16
+ * We try to make the test less fragile by removing its dependence on the system
17
+ * time by overriding <clock_gettime(3)> function. For this reason, clock mock
18
+ * static counter is introduced and <clock_gettime> simply adds a jiffy to this
19
+ * counter, normalizes .nsec and .sec fields of the mock and respectively sets
20
+ * the value to the given struct timespec argument.
21
+ *
22
+ * According to jargon file (http://www.catb.org/~esr/jargon/html/J/jiffy.html):
23
+ * | 1. The duration of one tick of the system clock on your computer. Often one
24
+ * | AC cycle time (1/60 second in the U.S. and Canada, 1/50 most other
25
+ * | places), but more recently 1/100 sec has become common. "The swapper
26
+ * | runs every 6 jiffies" means that the virtual memory management routine
27
+ * | is executed once for every 6 ticks of the clock, or about ten times a
28
+ * | second.
29
+ * | 2. Confusingly, the term is sometimes also used for a 1-millisecond wall
30
+ * | time interval.
31
+ * | 3. Even more confusingly, physicists semi-jokingly use 'jiffy' to mean the
32
+ * | time required for light to travel one foot in a vacuum, which turns out
33
+ * | to be close to one nanosecond. Other physicists use the term for the
34
+ * | quantum-mechanical lower bound on meaningful time lengths.
35
+ * | 4. Indeterminate time from a few seconds to forever. "I'll do it in a
36
+ * | jiffy" means certainly not now and possibly never. This is a bit
37
+ * | contrary to the more widespread use of the word. Oppose nano.
38
+ *
39
+ * Besides, there are several <sleep(3)> calls required in the test cases to
40
+ * check whether "lua" and "wall" counters are calculated right. This function
41
+ * is also overridden, considering how time is counted within this test: since
42
+ * <sleep> receives the seconds as an argument, simply add the given amount of
43
+ * seconds to the clock mock.
44
+ *
45
+ * Unfortunately, there is one flaw in such time mocking: these are not real
46
+ * nanoseconds and seconds used in the clock mock, but just two types of
47
+ * counters: short (for consecutive actions) and long (for interrupted actions).
48
+ * Hence, we can't use some real jiffy value (i.e. the first one from the jargon
49
+ * file), considering the cumulative discrepancy between linear mocked clock
50
+ * behaviour and non-linear real clock behaviour.
51
+ *
52
+ * Considering everything above "physicists semi-joking" constant (i.e. 1 ns)
53
+ * looks fine to be a jiffy in for a clock mock.
54
+ */
55
+ #define JIFFY (1L)
56
+ #define NSECNORM ((long)1e9)
57
+
58
+ static struct timespec clock_mock = {
59
+ .tv_sec = 0 ,
60
+ .tv_nsec = 0 ,
61
+ };
62
+
63
+ extern int clock_gettime (clockid_t clockid , struct timespec * tp )
64
+ {
65
+ UNUSED (clockid );
66
+ clock_mock .tv_nsec += JIFFY ;
67
+ clock_mock .tv_sec += clock_mock .tv_nsec / NSECNORM ;
68
+ clock_mock .tv_nsec = clock_mock .tv_nsec % NSECNORM ;
69
+ tp -> tv_sec = clock_mock .tv_sec ;
70
+ tp -> tv_nsec = clock_mock .tv_nsec ;
71
+ return 0 ;
72
+ }
73
+
74
+ extern unsigned int sleep (unsigned int seconds )
75
+ {
76
+ clock_mock .tv_sec += seconds ;
77
+ return 0 ;
78
+ }
79
+
80
+ /* }}} */
11
81
12
82
const char * ujit_iprof_profile =
13
83
" return function (pfn, pcb, name, mode, level) "
@@ -298,12 +368,10 @@ unsigned int parent_iter = 5, parent_timeout = 1;
298
368
const char * parent_name = "PARENT" ;
299
369
const char * parent_chunk =
300
370
" jit.off() "
301
- " local ffi = require 'ffi' "
302
- " ffi.cdef('unsigned int sleep(unsigned int seconds);') "
303
371
" local parent = ujit.iprof.profile(function(iter, timeout) "
304
372
" local coro = coroutine.create(function(n, t) "
305
373
" for _ = 1, n do "
306
- " ffi.C. sleep(t) "
374
+ " sleep(t) "
307
375
" coroutine.yield() "
308
376
" end "
309
377
" end) "
@@ -314,6 +382,12 @@ const char *parent_chunk =
314
382
" end, parent_cb, parent_name, ujit.iprof.PLAIN) "
315
383
" parent(parent_iter, parent_timeout) " ;
316
384
385
+ static int sleep_lua (lua_State * L )
386
+ {
387
+ sleep (luaL_checkint (L , 1 ));
388
+ return 0 ;
389
+ }
390
+
317
391
static int parent_cb (lua_State * L )
318
392
{
319
393
assert_report_table (L , parent_name );
@@ -340,6 +414,8 @@ static void test_parent(void **state)
340
414
/* Check whether ujit.iprof.profile was not defined by luaL_openlibs */
341
415
assert_ujit_iprof_profile (L );
342
416
417
+ /* Register function Lua C wrapper for sleep(3) function */
418
+ lua_register (L , "sleep" , sleep_lua );
343
419
/* Register callback for reporting and entity name */
344
420
lua_register (L , "parent_cb" , parent_cb );
345
421
lua_export (L , string , parent_name );
0 commit comments