added MOO_MSEC_TO_USEC() and MOO_USEC_TO_MSEC()

enhanced win32 ticker implementation
This commit is contained in:
hyunghwan.chung 2018-11-21 13:19:07 +00:00
parent 7ceae0caf7
commit 9f0210b31b
2 changed files with 69 additions and 36 deletions

View File

@ -379,6 +379,9 @@ typedef struct moo_bcs_t moo_bcs_t;
#define MOO_MSEC_TO_NSEC(msec) ((msec) * MOO_NSECS_PER_MSEC) #define MOO_MSEC_TO_NSEC(msec) ((msec) * MOO_NSECS_PER_MSEC)
#define MOO_NSEC_TO_MSEC(nsec) ((nsec) / MOO_NSECS_PER_MSEC) #define MOO_NSEC_TO_MSEC(nsec) ((nsec) / MOO_NSECS_PER_MSEC)
#define MOO_MSEC_TO_USEC(msec) ((msec) * MOO_USECS_PER_MSEC)
#define MOO_USEC_TO_MSEC(usec) ((usec) / MOO_USECS_PER_MSEC)
#define MOO_SEC_TO_NSEC(sec) ((sec) * MOO_NSECS_PER_SEC) #define MOO_SEC_TO_NSEC(sec) ((sec) * MOO_NSECS_PER_SEC)
#define MOO_NSEC_TO_SEC(nsec) ((nsec) / MOO_NSECS_PER_SEC) #define MOO_NSEC_TO_SEC(nsec) ((nsec) / MOO_NSECS_PER_SEC)

View File

@ -1188,7 +1188,7 @@ static void assert_fail (moo_t* moo, const moo_bch_t* expr, const moo_bch_t* fil
# define sys_dl_getsym(x,n) dlsym(x,n) # define sys_dl_getsym(x,n) dlsym(x,n)
#elif defined(USE_WIN_DLL) #elif defined(USE_WIN_DLL)
# define sys_dl_error() win_dlerror() # define sys_dl_error() msw_dlerror()
# define sys_dl_open(x) LoadLibraryExA(x, MOO_NULL, 0) # define sys_dl_open(x) LoadLibraryExA(x, MOO_NULL, 0)
# define sys_dl_openext(x) LoadLibraryExA(x, MOO_NULL, 0) # define sys_dl_openext(x) LoadLibraryExA(x, MOO_NULL, 0)
# define sys_dl_close(x) FreeLibrary(x) # define sys_dl_close(x) FreeLibrary(x)
@ -1204,7 +1204,7 @@ static void assert_fail (moo_t* moo, const moo_bch_t* expr, const moo_bch_t* fil
#if defined(USE_WIN_DLL) #if defined(USE_WIN_DLL)
static const char* win_dlerror (void) static const char* msw_dlerror (void)
{ {
/* TODO: handle wchar_t, moo_ooch_t etc? */ /* TODO: handle wchar_t, moo_ooch_t etc? */
static char buf[256]; static char buf[256];
@ -2749,51 +2749,76 @@ static MOO_INLINE void swproc_all_moos (void)
#if defined(_WIN32) #if defined(_WIN32)
static HANDLE win_tick_timer = MOO_NULL; /*INVALID_HANDLE_VALUE;*/ static HANDLE msw_tick_timer = MOO_NULL; /*INVALID_HANDLE_VALUE;*/
static int msw_tick_done = 0;
#if 0 static DWORD WINAPI msw_wait_for_timer_event (LPVOID ctx)
static VOID CALLBACK arrange_process_switching (LPVOID arg, DWORD timeLow, DWORD timeHigh) {
#else msw_tick_timer = CreateWaitableTimer(MOO_NULL, FALSE, MOO_NULL);
//static void arrange_process_switching (HWND hwnd, UINT arg2, UINT_PTR arg3, DWORD arg4) if (msw_tick_timer)
static void arrange_process_switching (HWND arg1, UINT arg2, void* arg3, DWORD arg4) {
#endif LARGE_INTEGER li;
/* lpDueTime in 100 nanoseconds */
li.QuadPart = -MOO_USEC_TO_NSEC(MOO_TICKER_INTERVAL_USECS) / 100;
/*#define MSW_TICKER_MANUAL_RESET */
#if defined(MSW_TICKER_MANUAL_RESET)
/* if manual resetting is enabled, the reset is done after
* swproc_all_moos has been called. so the interval is the
* interval specified plus the time taken in swproc_all_moos. */
SetWaitableTimer (msw_tick_timer, &li, 0, MOO_NULL, MOO_NULL, FALSE);
#else
/* with auto reset, the interval is not affected by time taken
* in swproc_all_moos() */
SetWaitableTimer (msw_tick_timer, &li, MOO_USEC_TO_MSEC(MOO_TICKER_INTERVAL_USECS), MOO_NULL, MOO_NULL, FALSE);
#endif
while (!msw_tick_done)
{
if (WaitForSingleObject(msw_tick_timer, 100000) == WAIT_OBJECT_0)
{ {
printf ("process switching tick...\n");
swproc_all_moos (); swproc_all_moos ();
#if defined(MSW_TICKER_MANUAL_RESET)
SetWaitableTimer (msw_tick_timer, &li, 0, MOO_NULL, MOO_NULL, FALSE);
#endif
}
}
CancelWaitableTimer (msw_tick_timer);
CloseHandle (msw_tick_timer);
msw_tick_timer = MOO_NULL;
}
msw_tick_done = 0;
/*ExitThread (0);*/
} }
static MOO_INLINE void start_ticker (void) static MOO_INLINE void start_ticker (void)
{ {
#if 0 HANDLE thr;
LARGE_INTEGER li;
win_tick_timer = CreateWaitableTimer(MOO_NULL, TRUE, MOO_NULL); msw_tick_done = 0;
if (win_tick_timer)
thr = CreateThread(MOO_NULL, 0, msw_wait_for_timer_event, MOO_NULL, 0, MOO_NULL);
if (thr)
{ {
/* lpDueTime in 100 nanoseconds */ /* MSDN - The thread object remains in the system until the thread has terminated
li.QuadPart = -MOO_USEC_TO_NSEC(MOO_TICKER_INTERVAL_USECS) / 100; * and all handles to it have been closed through a call to CloseHandle.
SetWaitableTimer (win_tick_timer, &li, 0, arrange_process_switching, MOO_NULL, FALSE); * it is safe to close the handle here */
CloseHandle (thr);
} }
#else
SetTimer (NULL, 0x9991, MOO_USEC_TO_MSEC(MOO_TICKER_INTERVAL_USECS), arrange_process_switching);
#endif
} }
static MOO_INLINE void stop_ticker (void) static MOO_INLINE void stop_ticker (void)
{ {
#if 0 if (msw_tick_timer) CancelWaitableTimer (msw_tick_timer);
if (win_tick_timer) msw_tick_done = 1;
{
CancelWaitableTimer (win_tick_timer);
CloseHandle (win_tick_timer);
win_tick_timer = MOO_NULL;
}
#else
KillTimer (NULL, 0x9991);
#endif
} }
#elif defined(__OS2__) #elif defined(__OS2__)
static TID os2_tick_tid;
static HEV os2_tick_sem; static HEV os2_tick_sem;
static HTIMER os2_tick_timer; static HTIMER os2_tick_timer;
static int os2_tick_done = 0; static int os2_tick_done = 0;
@ -2806,12 +2831,14 @@ static void EXPENTRY os2_wait_for_timer_event (ULONG x)
rc = DosCreateEventSem (NULL, &os2_tick_sem, DC_SEM_SHARED, FALSE); rc = DosCreateEventSem (NULL, &os2_tick_sem, DC_SEM_SHARED, FALSE);
if (rc != NO_ERROR) if (rc != NO_ERROR)
{ {
/* xxxx */ goto done;
} }
rc = DosStartTimer (1L, (HSEM)os2_tick_sem, &os2_tick_timer); rc = DosStartTimer (1L, (HSEM)os2_tick_sem, &os2_tick_timer);
if (rc != NO_ERROR) if (rc != NO_ERROR)
{ {
DosCloseEventSem ((HSEM)os2_tick_sem);
goto done;
} }
while (!os2_tick_done) while (!os2_tick_done)
@ -2824,15 +2851,19 @@ static void EXPENTRY os2_wait_for_timer_event (ULONG x)
DosStopTimer (os2_tick_timer); DosStopTimer (os2_tick_timer);
DosCloseEventSem ((HSEM)os2_tick_sem); DosCloseEventSem ((HSEM)os2_tick_sem);
done:
os2_tick_timer = NULL; os2_tick_timer = NULL;
os2_tick_sem = NULL; os2_tick_sem = NULL;
os2_tick_done = 0;
DosExit (EXIT_THREAD, 0); DosExit (EXIT_THREAD, 0);
} }
static MOO_INLINE void start_ticker (void) static MOO_INLINE void start_ticker (void)
{ {
static TID tid;
os2_tick_done = 0;
DosCreateThread (&tid, os2_wait_for_timer_event, 0, 0, 4096);
/* TODO: Error check */ /* TODO: Error check */
DosCreateThread (&os2_tick_tid, os2_wait_for_timer_event, 0, 0, 4096);
} }
static MOO_INLINE void stop_ticker (void) static MOO_INLINE void stop_ticker (void)
@ -2896,7 +2927,7 @@ static pascal void timer_intr_handler (TMTask* task)
static MOO_INLINE void start_ticker (void) static MOO_INLINE void start_ticker (void)
{ {
GetCurrentProcess (&mac_psn); GetCurrentProcess (&mac_psn);
memset (&mac_tmtask, 0, MOO_SIZEOF(mac_tmtask)); MOO_MEMSET (&mac_tmtask, 0, MOO_SIZEOF(mac_tmtask));
mac_tmtask.tmAddr = NewTimerProc (timer_intr_handler); mac_tmtask.tmAddr = NewTimerProc (timer_intr_handler);
InsXTime ((QElem*)&mac_tmtask); InsXTime ((QElem*)&mac_tmtask);
PrimeTime ((QElem*)&mac_tmtask, TMTASK_DELAY); PrimeTime ((QElem*)&mac_tmtask, TMTASK_DELAY);
@ -2915,7 +2946,6 @@ static void arrange_process_switching (int sig)
swproc_all_moos (); swproc_all_moos ();
} }
static MOO_INLINE void start_ticker (void) static MOO_INLINE void start_ticker (void)
{ {
if (set_signal_handler(SIGVTALRM, arrange_process_switching, SA_RESTART) >= 0) if (set_signal_handler(SIGVTALRM, arrange_process_switching, SA_RESTART) >= 0)