diff --git a/src/include/internals.h b/src/include/internals.h index 0c7079e6..f9dc9b63 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -258,7 +258,7 @@ struct _MSGQUEUE int loop_depth; // message loop depth, for dialog boxes int idle_counter; // the idle connter for MSG_IDLE - DWORD last_ticks_desktop; // the last tick count for desktop timer + DWORD last_ticks; // the last tick count saved; since 5.0.14 /* Since 5.0.0, MiniGUI provides support for timers per message thread */ int nr_timers; // the number of active timers diff --git a/src/include/timer.h b/src/include/timer.h index 4978cc8b..f2f7a9ee 100644 --- a/src/include/timer.h +++ b/src/include/timer.h @@ -74,7 +74,7 @@ typedef struct _MSGQUEUE MSGQUEUE; extern "C" { #endif /* __cplusplus */ -void __mg_update_tick_count (void* data); +DWORD __mg_update_tick_count (MSGQUEUE* msg_queue); int __mg_check_expired_timers (MSGQUEUE* msg_queue, DWORD inter); void __mg_remove_timers_by_msg_queue (MSGQUEUE* msg_queue); void __mg_remove_timer (MSGQUEUE* msg_queue, int slot); diff --git a/src/kernel/desktop-ths.c b/src/kernel/desktop-ths.c index 402714b7..b79d09ac 100644 --- a/src/kernel/desktop-ths.c +++ b/src/kernel/desktop-ths.c @@ -145,7 +145,7 @@ static IDLEHANDLER std_idle_handler; static BOOL idle_handler_for_desktop_thread (MSGQUEUE *msg_queue, BOOL wait) { - __mg_update_tick_count (NULL); + __mg_update_tick_count (msg_queue); return std_idle_handler (msg_queue, wait); } diff --git a/src/kernel/timer.c b/src/kernel/timer.c index ff895c90..93f49fe4 100644 --- a/src/kernel/timer.c +++ b/src/kernel/timer.c @@ -44,7 +44,7 @@ * . */ /* -** timer.c: The Timer module for MiniGUI-Threads. +** timer.c: The Timer module for MiniGUI. ** ** Current maintainer: Wei Yongming. ** @@ -79,139 +79,44 @@ DWORD __mg_tick_counter = 0; -/* update timer count for desktop thread */ -void __mg_update_tick_count (void *data) +/* update timer count for message and desktop thread */ +DWORD __mg_update_tick_count (MSGQUEUE* msg_queue) { + DWORD ticks; + #if defined(_MGRM_PROCESSES) if (mgIsServer) { - __mg_tick_counter = __mg_os_get_time_ticks (); - SHAREDRES_TIMER_COUNTER = __mg_tick_counter; + ticks = __mg_os_get_time_ticks (); + SHAREDRES_TIMER_COUNTER = ticks; } else { - __mg_tick_counter = SHAREDRES_TIMER_COUNTER; + ticks = SHAREDRES_TIMER_COUNTER; } #else /* defined _MGRM_PROCESSES */ - __mg_tick_counter = __mg_os_get_time_ticks (); + ticks = __mg_os_get_time_ticks (); #endif /* not defined _MGRM_PROCESSES */ - /* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT - message, and the interval for the timer of desktop changes to 0.05s. */ - if (__mg_tick_counter > - __mg_dsk_msg_queue->last_ticks_desktop + DESKTOP_TIMER_INERTVAL) { - __mg_dsk_msg_queue->dwState |= QS_DESKTIMER; + if (msg_queue && ticks != msg_queue->last_ticks) { + /* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT + message, and the interval for the timer of desktop changes to 0.05s. + */ + if (msg_queue == __mg_dsk_msg_queue) { + if (ticks > __mg_dsk_msg_queue->last_ticks + + DESKTOP_TIMER_INERTVAL) { + __mg_dsk_msg_queue->dwState |= QS_DESKTIMER; #ifdef _MGRM_THREADS /* only wake up desktop for threads mode */ - POST_MSGQ (__mg_dsk_msg_queue); + POST_MSGQ (__mg_dsk_msg_queue); #endif - __mg_dsk_msg_queue->last_ticks_desktop = __mg_tick_counter; + } + } + + msg_queue->last_ticks = ticks; } -#if 0 /* deprecated code */ -#if defined(_MGRM_PROCESSES) - if (mgIsServer) { - DWORD elapsed_ticks; - - /* Since 5.0.0, we use elapsed time in ms to count the ticks */ - elapsed_ticks = __mg_os_get_elapsed_ms (); - elapsed_ticks = (elapsed_ticks + 5) / 10; - - __mg_tick_counter += elapsed_ticks; - SHAREDRES_TIMER_COUNTER = __mg_tick_counter; - } - else { - __mg_tick_counter = SHAREDRES_TIMER_COUNTER; - } -#else /* defined _MGRM_PROCESSES */ - DWORD elapsed_ticks; - - /* Since 5.0.0, we use elapsed time in ms to count the ticks */ - elapsed_ticks = __mg_os_get_elapsed_ms (); - elapsed_ticks = (elapsed_ticks + 5) / 10; - __mg_tick_counter += elapsed_ticks; -#endif /* not defined _MGRM_PROCESSES */ - - /* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT - message, and the interval for the timer of desktop changes to 0.05s. */ - if (__mg_tick_counter > - __mg_dsk_msg_queue->last_ticks_desktop + DESKTOP_TIMER_INERTVAL) { - __mg_dsk_msg_queue->dwState |= QS_DESKTIMER; -#ifdef _MGRM_THREADS /* only wake up desktop for threads mode */ - POST_MSGQ (__mg_dsk_msg_queue); -#endif - __mg_dsk_msg_queue->last_ticks_desktop = __mg_tick_counter; - } -#endif /* deprecated code */ + __mg_tick_counter = ticks; + return ticks; } -#ifdef __NOUNIX__ - -static BOOL install_system_timer (void) -{ - return TRUE; -} - -static BOOL unintall_system_timer (void) -{ - return TRUE; -} - -#else /* defined __NOUNIX__ */ - -#include -#include -#include - -static struct sigaction old_alarm_handler; -static struct itimerval old_timer; - -static BOOL install_system_timer (void) -{ - struct itimerval timerv; - struct sigaction siga; - - sigaction (SIGALRM, NULL, &old_alarm_handler); - - siga = old_alarm_handler; - siga.sa_handler = (void(*)(int))__mg_update_tick_count; -#ifndef _MGRM_STANDALONE - siga.sa_flags = 0; -#else - siga.sa_flags = SA_RESTART; -#endif - sigaction (SIGALRM, &siga, NULL); - - timerv.it_interval.tv_sec = 0; -#if defined(__uClinux__) && defined(_MGRM_STANDALONE) - timerv.it_interval.tv_usec = 100000; /* 100 ms */ -#else - timerv.it_interval.tv_usec = 10000; /* 10 ms */ -#endif - timerv.it_value = timerv.it_interval; - - if (setitimer (ITIMER_REAL, &timerv, &old_timer) == -1) { - TIMER_ERR_SYS ("setitimer call failed!\n"); - return FALSE; - } - - return TRUE; -} - -static BOOL unintall_system_timer (void) -{ - if (setitimer (ITIMER_REAL, &old_timer, 0) == -1) { - TIMER_ERR_SYS ("setitimer call failed!\n"); - return FALSE; - } - - if (sigaction (SIGALRM, &old_alarm_handler, NULL) == -1) { - TIMER_ERR_SYS ("sigaction call failed!\n"); - return FALSE; - } - - return TRUE; -} - -#endif /* not defined __NOUNIX__ */ - BOOL mg_InitTimer (BOOL use_sys_timer) { __mg_tick_counter = 0; @@ -219,7 +124,8 @@ BOOL mg_InitTimer (BOOL use_sys_timer) __mg_os_start_time(); if (use_sys_timer) { - install_system_timer (); + // Since 5.0.14, do nothing. + // install_system_timer (); } return TRUE; @@ -227,8 +133,10 @@ BOOL mg_InitTimer (BOOL use_sys_timer) void mg_TerminateTimer (BOOL use_sys_timer) { - if (use_sys_timer) - unintall_system_timer (); + if (use_sys_timer) { + // Since 5.0.14, do nothing. + // unintall_system_timer (); + } } /************************* Functions run in message thread *******************/ @@ -247,34 +155,21 @@ int __mg_check_expired_timers (MSGQUEUE* msg_queue, DWORD inter) int i; TIMER** timer_slots = msg_queue->timer_slots; + __mg_update_tick_count (msg_queue); + for (i = 0; i < DEF_NR_TIMERS; i++) { if (timer_slots[i]) { - if (__mg_tick_counter >= timer_slots[i]->ticks_expected) { + if (msg_queue->last_ticks >= timer_slots[i]->ticks_expected) { /* setting timer flag is simple, we do not need to lock msgq, or else we may encounter dead lock here */ msg_queue->expired_timer_mask |= (0x01UL << i); POST_MSGQ (msg_queue); - timer_slots[i]->ticks_expected += timer_slots[i]->interv; - timer_slots[i]->ticks_fired = __mg_tick_counter; + timer_slots[i]->ticks_expected = + msg_queue->last_ticks + timer_slots[i]->interv; + timer_slots[i]->ticks_fired = msg_queue->last_ticks; nr++; } -#if 0 /* deprecated code */ - timer_slots[i]->count += inter; - if (timer_slots[i]->count >= timer_slots[i]->interv) { -#ifdef _MGRM_PROCESSES - timer_slots[i]->ticks_current = SHAREDRES_TIMER_COUNTER; -#else - timer_slots[i]->ticks_current = __mg_tick_counter; -#endif - /* setting timer flag is simple, we do not need to lock msgq, - or else we may encounter dead lock here */ - msg_queue->expired_timer_mask |= (0x01UL << i); - POST_MSGQ (msg_queue); - timer_slots[i]->count -= timer_slots[i]->interv; - nr++; - } -#endif /* deprecated code */ } } } @@ -291,12 +186,7 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv, int i; int slot = -1; TIMER** timer_slots; - PMSGQUEUE pMsgQueue; - -#ifndef _MGRM_THREADS - /* Force to update tick count */ - GetTickCount(); -#endif + PMSGQUEUE msg_queue; if (id == 0) { _WRN_PRINTF ("bad identifier (%ld).\n", id); @@ -307,12 +197,14 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv, interv = 1; } - timer_slots = getTimerSlotsForThisThread (&pMsgQueue); + timer_slots = getTimerSlotsForThisThread (&msg_queue); if (MG_UNLIKELY (timer_slots == NULL)) { _WRN_PRINTF ("called for non message thread\n"); goto badret; } + __mg_update_tick_count (msg_queue); + /* Since 5.0.0: only check hWnd if timer_proc is NULL */ if (MG_UNLIKELY (timer_proc == NULL && !getMainWinIfWindowInThisThread (hWnd))) { @@ -331,7 +223,7 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv, /* Since 5.0.0: we reset timer parameters for duplicated call of this function */ timer_slots[i]->interv = interv; - timer_slots[i]->ticks_expected = __mg_tick_counter + interv; + timer_slots[i]->ticks_expected = msg_queue->last_ticks + interv; timer_slots[i]->ticks_fired = 0; timer_slots[i]->proc = timer_proc; return TRUE; @@ -348,14 +240,14 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv, timer_slots[slot]->hWnd = hWnd; timer_slots[slot]->id = id; timer_slots[slot]->interv = interv; - timer_slots[slot]->ticks_expected = __mg_tick_counter + interv; + timer_slots[slot]->ticks_expected = msg_queue->last_ticks + interv; timer_slots[slot]->ticks_fired = 0; timer_slots[slot]->proc = timer_proc; _DBG_PRINTF ("ticks_expected (%d): %lu, tick_counter: %lu\n", - slot, timer_slots[slot]->ticks_expected, __mg_tick_counter); + slot, timer_slots[slot]->ticks_expected, msg_queue->last_ticks); - pMsgQueue->nr_timers++; + msg_queue->nr_timers++; return TRUE; @@ -363,24 +255,6 @@ badret: return FALSE; } -#if 0 /* deprected code */ -#ifdef _MGRM_PROCESSES -static void reset_select_timeout (TIMER** timer_slots) -{ - int i; - - unsigned int interv = 0; - for (i = 0; i < DEF_NR_TIMERS; i++) { - if (timer_slots[i]) { - if (interv == 0 || timer_slots[i]->interv < interv) - interv = timer_slots[i]->interv; - } - } - __mg_set_select_timeout (USEC_10MS * interv); -} -#endif -#endif /* deprecated code */ - void __mg_remove_timer (MSGQUEUE* msg_queue, int slot) { TIMER** timer_slots; @@ -470,13 +344,14 @@ BOOL GUIAPI ResetTimerEx (HWND hWnd, LINT id, DWORD interv, if (MG_LIKELY (msg_queue)) { TIMER** timer_slots = msg_queue->timer_slots; + __mg_update_tick_count (msg_queue); for (i = 0; i < DEF_NR_TIMERS; i++) { if (timer_slots[i] && timer_slots[i]->hWnd == hWnd && timer_slots[i]->id == id) { /* Should clear old timer flags */ msg_queue->expired_timer_mask &= ~(0x01UL << i); timer_slots[i]->interv = interv; - timer_slots[i]->ticks_expected = __mg_tick_counter + interv; + timer_slots[i]->ticks_expected = msg_queue->last_ticks + interv; timer_slots[i]->ticks_fired = 0; if (timer_proc != (TIMERPROC)INV_PTR) timer_slots[i]->proc = timer_proc; @@ -548,20 +423,6 @@ BOOL GUIAPI HaveFreeTimer (void) DWORD GUIAPI GetTickCount (void) { -#if defined(_MGRM_PROCESSES) - if (mgIsServer) { - __mg_tick_counter = __mg_os_get_time_ticks (); - SHAREDRES_TIMER_COUNTER = __mg_tick_counter; - } - else { - __mg_tick_counter = SHAREDRES_TIMER_COUNTER; - } -#elif defined(_MGRM_STANDALONE) - __mg_tick_counter = __mg_os_get_time_ticks (); -#else /* not defined _MGRM_PROCESSES and _MGRM_PROCESSES */ - /* do nothing here because the desktop thread updates the tick count */ -#endif /* not defined _MGRM_PROCESSES and _MGRM_PROCESSES */ - - return __mg_tick_counter; + return __mg_update_tick_count(getMsgQueueForThisThread ()); }