Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3819
Modified Files: Tag: devel_0_38 m_sched.c Log Message: improved idle callbacks
Index: m_sched.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_sched.c,v retrieving revision 1.5.4.15 retrieving revision 1.5.4.16 diff -C2 -d -r1.5.4.15 -r1.5.4.16 *** m_sched.c 16 Jan 2005 16:07:45 -0000 1.5.4.15 --- m_sched.c 16 Jan 2005 21:51:20 -0000 1.5.4.16 *************** *** 629,635 **** t_int* argv; t_int argc; } t_sched_callback;
- static t_sched_callback * idle_callback = NULL;
void sys_callback(t_int (*callback) (t_int* argv), t_int* argv, t_int argc) --- 629,635 ---- t_int* argv; t_int argc; + struct _sched_callback* next; /* next callback in ringbuffer */ } t_sched_callback;
void sys_callback(t_int (*callback) (t_int* argv), t_int* argv, t_int argc) *************** *** 641,644 **** --- 641,645 ---- new->argv = (t_int*) copybytes (argv, argc * sizeof (t_int)); new->argc = argc; + new->next = NULL;
if (callback_fifo == NULL) *************** *** 648,651 **** --- 649,655 ---- }
+ #if 0 /* old version, todo: profiling */ + static t_sched_callback * idle_callback = NULL; + static t_int run_idle_callbacks(void) { *************** *** 671,675 **** freebytes ((void*)idle_callback, sizeof(t_sched_callback)); idle_callback = fifo_get(callback_fifo); ! /* callbacks returning 1 will be run again */ case 1: --- 675,679 ---- freebytes ((void*)idle_callback, sizeof(t_sched_callback)); idle_callback = fifo_get(callback_fifo); ! /* callbacks returning 1 will be run again */ case 1: *************** *** 678,687 **** /* callbacks returning 2 will be run during the next idle callback */ case 2: ! return 0; } } while ((idle_callback != NULL) && (remain > 0));
! /* sleep for the rest of the time */ if(remain > 100) sys_microsleep(remain); return 0; --- 682,692 ---- /* callbacks returning 2 will be run during the next idle callback */ case 2: ! goto sleep; } } while ((idle_callback != NULL) && (remain > 0));
! sleep: ! /* sleep for the rest of the time */ if(remain > 100) sys_microsleep(remain); return 0; *************** *** 691,693 **** --- 696,774 ---- }
+ + #else /* improved ringbuffer version */ + static t_sched_callback *ringbuffer_head; + + static t_int run_idle_callbacks(void) + { + t_sched_callback * new_callback; + + /* append idle callback to ringbuffer */ + new_callback = (t_sched_callback*) fifo_get(callback_fifo); + while (new_callback != NULL) + { + t_sched_callback * next; + if (ringbuffer_head == NULL) + { + ringbuffer_head = new_callback; + } + else + { + next = ringbuffer_head; + while (next->next != 0) + next = next->next; + next->next = new_callback; + } + new_callback = (t_sched_callback*) fifo_get(callback_fifo); + } + + if (ringbuffer_head != NULL) + { + double remain; + double stop = sys_getrealtime() + sys_sleepgrain; + t_sched_callback * idle_callback = ringbuffer_head; + t_sched_callback * last = NULL; + t_sched_callback * next; + + do + { + int status = (idle_callback->function)(idle_callback->argv); + remain = stop-sys_getrealtime(); + + switch (status) + { + /* callbacks returning 0 will be deleted */ + case 0: + next = idle_callback->next; + freebytes (idle_callback->argv, idle_callback->argc); + freebytes ((void*)idle_callback, sizeof(t_sched_callback)); + + if (last == NULL) + ringbuffer_head = next; + else + last->next = next; + + idle_callback = next; + + /* callbacks returning 1 will be run again */ + case 1: + break; + + /* callbacks returning 2 will be run during the next idle callback */ + case 2: + last = idle_callback; + idle_callback = idle_callback->next; + } + } + while ((idle_callback != NULL) && (remain > 0)); + + sleep: + /* sleep for the rest of the time */ + if(remain > 100) sys_microsleep(remain); + return 0; + } + else + return 1; /* sleep */ + } + #endif /* } tb */