

## tick 调用栈

function unix.tick()
    return math.modf(chronos.nanotime()*1000)
end

LARGE_INTEGER freq;

typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG HighPart;
    } DUMMYSTRUCTNAME;
    struct {
        DWORD LowPart;
        LONG HighPart;
    } u;
    LONGLONG QuadPart;
} LARGE_INTEGER;

typedef __int64 LONGLONG;





/* type of numbers in Lua */
typedef LUA_NUMBER lua_Number;

/* type for integer functions */
typedef LUA_INTEGER lua_Integer;

#define LUA_NUMBER       double


lua_Number : double


static int chronos_nanotime(lua_State * L)
{
    //TODO All the apple stuff is untested because, like, I don't even got Apple.
    //If like, you have a mac, let me know whether this works.
    //see https://stackoverflow.com/questions/675626/coreaudio-audiotimestamp-mhosttime-clock-frequency
    //for info.
#ifdef CHRONOS_USE_COREAUDIO
    //Apparently this is just a wrapper around mach_absolute_time() anyway.
    lua_pushnumber(
        L,
        (lua_Number)AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) * 1.e9
    );
    return 1;
#else
    static int init = 1;
    static double resolution;
    static double multiplier;
    mach_timebase_info_data_t res_info;
    if(init){
        mach_timebase_info(&res_info);
        resolution = (double)res_info.numer / res_info.denom;
        multiplier = 1. / 1.e9;
        init = 0;
    }

    lua_pushnumber(L, (lua_Number)(mach_absolute_time() * resolution) * multiplier);
    return 1;
#endif
}


#define getticks mach_absolute_time

static inline CycleCounterTicks getticks(void)

typedef unsigned long CycleCounterTicks;


## 分析tick
getticks 返回系统tick uint64_t 0~+R
mach_absolute_time 返回系统tick uint64_t 0~+R
chronos_nanotime 返回结对S double
unix.tick() 返回绝对ms 






## 时间比较

local ret,timer = scheduler:tick(unix.tick())
if ret and ret == true then
    local msg = nil
    msg = unix.MSG_TIMER
    return msg, timer.param
end


if not id or not ms then return 0 end
scheduler:timer(ms, 1,nil,id)
return 1


## Scheduler
-- do a scheduler tick
-- time: current time (numeric type)
function Scheduler:tick(time)
  -- update time
  if time > self.time then -- valid
    self.time = time
  else -- invalid
    time = self.time
  end

  -- check timers
  local timers = self.timers
  local triggers = {}
  --local timer = timers[1] -- root
  local i = 1
  while(true) do
    local timer = timers[i]
    i = i + 1
    if not timer then break end
    if time >= timer.wake then
      scheduler_heap_delete(self, 1)
      return true,timer
    end
  end
  return false
end

## 问题点
  if time > self.time then -- valid
    self.time = time
  else -- invalid
  -- 错误地方,这个赋值是错误的
    time = self.time
  end

若tick 溢出 self.time 是个很大的值 time 是tick应该是很小的值

此时调用add timer

## add Timer


local function scheduler_add(self, timer)
.....
  timer.wake = self.time+timer.delay
....
end


## 再回到tick比较

if time >= timer.wake then
  scheduler_heap_delete(self, 1)
  return true,timer
end


self.time+timer.delay 可能大于tick 最大值,即使小于这个值,页需要等待tick再溢出一次才能命中

## 测试浮现



scp ghzhang@192.168.22.104:openwrt_lora/feeds/lnxall_package/lua-libutils/files/*.lua /usr/lib/lua/ ;/etc/init.d/protocol_parser restart

scp ghzhang@192.168.22.104:openwrt_lora/feeds/lnxall_package/lua-libutils/files/*.lua /usr/lib/lua/ ;lua /usr/lib/lua/task_example.lua

scp ghzhang@192.168.22.104:openwrt_lora/build_dir/target-arm_cortex-a7+neon-vfpv4_musl-1.1.16_eabi/lua-libutils-2.0.0/*.so /usr/lib/lua/

resumeAfter     2022-03-03 17:23:00
resumeAfter     2022-03-03 17:23:00
resumeAfter     2022-03-03 17:22:58
resumeAfter     2022-03-03 17:22:41
resumeAfter     2022-03-03 17:23:00
root@218812FF0073:/tmp# date
Thu Mar  3 17:28:23 CST 2022


加快测试浮现

return math.modf(chronos.nanotime()*1000)

local tick = chronos.nanotime()*10000
return math.modf(tick%(300000 * 2.2))


## 改进


unix.init = eptimer.init
unix.timer_start = eptimer.start
unix.timer_stop = eptimer.stop
unix.msleep = eptimer.msleep
unix.sleep = eptimer.sleep
用C替换 ELScheduler.lua timer



