#ifndef JOB_TAB_ENTRY #define JOB_TAB_ENTRY(name) JOB_##name, #if 0 extern int job_mask, isr_job_mask; extern void (*job_tab[])(void); #endif #define JOB(job) (1 << JOB_##job) #define SET_JOB(job) (job_tab.mask |= JOB(job)) #define ISR_SET_JOBS(JOBS) { \ int mask[2], i, new, jobs = JOBS; \ \ mask[1] = job_tab.isr_mask[1]; \ mask[0] = job_tab.isr_mask[0]; \ for (i = 0; ~(mask[0] & mask[1]) & jobs; ) { \ mask[i] |= jobs; \ job_tab.isr_mask[i] = mask[i]; \ i ^= 1; \ new = job_tab.isr_mask[i]; \ if (new != mask[i]) { \ jobs |= new & ~mask[i]; \ mask[i] = new; \ i ^= 1; \ } \ } \ } #define TRANSFER_ISR_JOBS { \ int mask[2], i, new; \ \ mask[1] = job_tab.isr_mask[1]; \ job_tab.mask |= job_tab.isr_mask[0]; \ for (i = 0; mask[0] || mask[1];) { \ job_tab.isr_mask[i] = 0; \ mask[i] = 0; \ i ^= 1; \ new = job_tab.isr_mask[i]; \ if (new != mask[i]) { \ mask[i] = new; \ job_tab.mask |= new; \ i ^= 1; \ } \ } \ } #define CLEAR_JOB(job) (job_tab.mask &= ~JOB(job)) #define EXTRA_JOBS() ((*job_tab.f[ffs(job_tab.mask)])()) #define REMAINING_JOBS(current) \ ((*job_tab.f[ffs(job_tab.mask & \ FIRST_PENDING_JOB - 1 - 2 * JOB(current))])()) enum job_number { #elif !defined(JOB_EXTERNAL_DECL) #define JOB_EXTERNAL_DECL extern struct s_job_tab { int mask; volatile isr_mask[2]; void (*f[JOB_TAB_SIZE])(void); } job_tab; #undef JOB_TAB_ENTRY #define JOB_TAB_ENTRY(name) extern void name(void); #else #define HAVE_JOBTAB #undef JOB_TAB_ENTRY #define JOB_TAB_ENTRY(name) name, #if 0 int job_mask, isr_job_mask; void (*job_tab[])(void) = { no_extra_job, #endif static void no_extra_job(void) { } struct s_job_tab job_tab = { 0, {0, 0}, { no_extra_job, #endif /* JOB_TAB_ENTRY */ JOB_TAB_ENTRY(shutdown_simulation) JOB_TAB_ENTRY(remove_destructed_objects) JOB_TAB_ENTRY(call_out) JOB_TAB_ENTRY(remove_deactivated_interactives) JOB_TAB_ENTRY(garbage_collection) JOB_TAB_ENTRY(check_call_out) /* Entries below can leave the job pending */ #define FIRST_PENDING_JOB JOB(urgent_data) JOB_TAB_ENTRY(urgent_data) JOB_TAB_ENTRY(flush_all_output) JOB_TAB_ENTRY(do_compact_mappings) #ifndef JOB_EXTERNAL_DECL #define JOB_TAB_SIZE (JOB_do_compact_mappings + 2) }; #elif defined(HAVE_JOBTAB) }}; #endif #if !defined(JOB_EXTERNAL_DECL) || defined(NEED_JOBTAB) > defined(HAVE_JOBTAB) #include "schedule.h" #endif