diff options
author | Vincent Sanders <vince@netsurf-browser.org> | 2011-02-08 23:42:18 +0000 |
---|---|---|
committer | Vincent Sanders <vince@netsurf-browser.org> | 2011-02-08 23:42:18 +0000 |
commit | 3c414e7668d6db3ac738f8850b9e038495ee5e3a (patch) | |
tree | 8466e11aee8f959aeace604cf801fe85e1ef7319 /windows/schedule.c | |
parent | 42990ed9ec37680791c88504595243f269f726c7 (diff) | |
download | netsurf-3c414e7668d6db3ac738f8850b9e038495ee5e3a.tar.gz netsurf-3c414e7668d6db3ac738f8850b9e038495ee5e3a.tar.bz2 |
Stop win32 frontend using 100% cpu time when idle
svn path=/trunk/netsurf/; revision=11633
Diffstat (limited to 'windows/schedule.c')
-rw-r--r-- | windows/schedule.c | 218 |
1 files changed, 118 insertions, 100 deletions
diff --git a/windows/schedule.c b/windows/schedule.c index 5414f6d56..a37a0e051 100644 --- a/windows/schedule.c +++ b/windows/schedule.c @@ -20,32 +20,20 @@ #include <time.h> #include "desktop/browser.h" -#include "windows/schedule.h" +#include "framebuffer/schedule.h" #include "utils/log.h" +#include "utils/utils.h" /* linked list of scheduled callbacks */ static struct nscallback *schedule_list = NULL; -#ifndef timeradd -#define timeradd(a, aa, result) \ - do {\ - (result)->tv_sec = (a)->tv_sec + (aa)->tv_sec;\ - (result)->tv_usec = (a)->tv_usec + (aa)->tv_usec;\ - if ((result)->tv_usec >= 1000000)\ - {\ - ++(result)->tv_sec;\ - (result)->tv_usec -= 1000000;\ - }\ - } while (0) -#endif - /** * scheduled callback. */ struct nscallback { - struct nscallback *next; + struct nscallback *next; struct timeval tv; void (*callback)(void *p); void *p; @@ -57,7 +45,7 @@ struct nscallback * * \param tival interval before the callback should be made / cs * \param callback callback function - * \param p user parameter, passed to callback function + * \param p user parameter, passed to callback function * * The callback function will be called as soon as possible after t cs have * passed. @@ -68,8 +56,8 @@ void schedule(int cs_ival, void (*callback)(void *p), void *p) struct nscallback *nscb; struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = cs_ival * 10000; + tv.tv_sec = cs_ival / 100; /* cs to seconds */ + tv.tv_usec = (cs_ival % 100) * 10000; /* remainder to microseconds */ nscb = calloc(1, sizeof(struct nscallback)); @@ -81,128 +69,158 @@ void schedule(int cs_ival, void (*callback)(void *p), void *p) nscb->callback = callback; nscb->p = p; - /* add to list front */ - nscb->next = schedule_list; - schedule_list = nscb; + /* add to list front */ + nscb->next = schedule_list; + schedule_list = nscb; } /** * Unschedule a callback. * * \param callback callback function - * \param p user parameter, passed to callback function + * \param p user parameter, passed to callback function * * All scheduled callbacks matching both callback and p are removed. */ void schedule_remove(void (*callback)(void *p), void *p) { - struct nscallback *cur_nscb; - struct nscallback *prev_nscb; - struct nscallback *unlnk_nscb; + struct nscallback *cur_nscb; + struct nscallback *prev_nscb; + struct nscallback *unlnk_nscb; - if (schedule_list == NULL) - return; + if (schedule_list == NULL) + return; LOG(("removing %p, %p", callback, p)); - cur_nscb = schedule_list; - prev_nscb = NULL; - - while (cur_nscb != NULL) { - if ((cur_nscb->callback == callback) && - (cur_nscb->p == p)) { - /* item to remove */ - - LOG(("callback entry %p removing %p(%p)", - cur_nscb, cur_nscb->callback, cur_nscb->p)); - - /* remove callback */ - unlnk_nscb = cur_nscb; - cur_nscb = unlnk_nscb->next; - - if (prev_nscb == NULL) { - schedule_list = cur_nscb; - } else { - prev_nscb->next = cur_nscb; - } - free (unlnk_nscb); - } else { - /* move to next element */ - prev_nscb = cur_nscb; - cur_nscb = prev_nscb->next; - } - } + cur_nscb = schedule_list; + prev_nscb = NULL; + + while (cur_nscb != NULL) { + if ((cur_nscb->callback == callback) && + (cur_nscb->p == p)) { + /* item to remove */ + + LOG(("callback entry %p removing %p(%p)", + cur_nscb, cur_nscb->callback, cur_nscb->p)); + + /* remove callback */ + unlnk_nscb = cur_nscb; + cur_nscb = unlnk_nscb->next; + + if (prev_nscb == NULL) { + schedule_list = cur_nscb; + } else { + prev_nscb->next = cur_nscb; + } + free (unlnk_nscb); + } else { + /* move to next element */ + prev_nscb = cur_nscb; + cur_nscb = prev_nscb->next; + } + } } /** - * Process events up to current time. + * Process scheduled callbacks up to current time. + * + * @return The number of milliseconds untill the next scheduled event + * or -1 for no event. */ - -bool schedule_run(void) +int +schedule_run(void) { struct timeval tv; - struct nscallback *cur_nscb; - struct nscallback *prev_nscb; - struct nscallback *unlnk_nscb; + struct timeval nexttime; + struct timeval rettime; + struct nscallback *cur_nscb; + struct nscallback *prev_nscb; + struct nscallback *unlnk_nscb; - if (schedule_list == NULL) - return false; + if (schedule_list == NULL) + return -1; - cur_nscb = schedule_list; - prev_nscb = NULL; + /* reset enumeration to the start of the list */ + cur_nscb = schedule_list; + prev_nscb = NULL; + nexttime = cur_nscb->tv; gettimeofday(&tv, NULL); - while (cur_nscb != NULL) { - if (timercmp(&tv, &cur_nscb->tv, >)) { - /* scheduled time */ - - /* remove callback */ - unlnk_nscb = cur_nscb; + while (cur_nscb != NULL) { + if (timercmp(&tv, &cur_nscb->tv, >)) { + /* scheduled time */ - if (prev_nscb == NULL) { - schedule_list = unlnk_nscb->next; - } else { - prev_nscb->next = unlnk_nscb->next; - } + /* remove callback */ + unlnk_nscb = cur_nscb; - LOG(("callback entry %p running %p(%p)", - unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p)); - /* call callback */ - unlnk_nscb->callback(unlnk_nscb->p); + if (prev_nscb == NULL) { + schedule_list = unlnk_nscb->next; + } else { + prev_nscb->next = unlnk_nscb->next; + } - free (unlnk_nscb); + LOG(("callback entry %p running %p(%p)", + unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p)); + /* call callback */ + unlnk_nscb->callback(unlnk_nscb->p); - /* the callback might have modded the list, so start - * again + free(unlnk_nscb); + + /* need to deal with callback modifying the list. */ + if (schedule_list == NULL) + return -1; /* no more callbacks scheduled */ + + /* reset enumeration to the start of the list */ + cur_nscb = schedule_list; + prev_nscb = NULL; + nexttime = cur_nscb->tv; + } else { + /* if the time to the event is sooner than the + * currently recorded soonest event record it */ - cur_nscb = schedule_list; - prev_nscb = NULL; - - } else { - /* move to next element */ - prev_nscb = cur_nscb; - cur_nscb = prev_nscb->next; - } - } - return true; + if (timercmp(&nexttime, &cur_nscb->tv, >)) { + nexttime = cur_nscb->tv; + } + /* move to next element */ + prev_nscb = cur_nscb; + cur_nscb = prev_nscb->next; + } + } + + /* make rettime relative to now */ + timersub(&nexttime, &tv, &rettime); + +#if DEBUG_SCHEDULER + LOG(("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000))); +#endif + /* return next event time in milliseconds (24days max wait) */ + return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000); } void list_schedule(void) { struct timeval tv; - struct nscallback *cur_nscb; + struct nscallback *cur_nscb; gettimeofday(&tv, NULL); - LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec)); + LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec)); - cur_nscb = schedule_list; + cur_nscb = schedule_list; - while (cur_nscb != NULL) { - LOG(("Schedule %p at %ld:%ld", - cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec)); - cur_nscb = cur_nscb->next; - } + while (cur_nscb != NULL) { + LOG(("Schedule %p at %ld:%ld", + cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec)); + cur_nscb = cur_nscb->next; + } } + + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ |