/*====================================== * CORE : MAINROUTINE *--------------------------------------*/ int main (int argc, char **argv) { {// initialize program arguments char *p1; if((p1 = strrchr(argv[0], '/')) != NULL || (p1 = strrchr(argv[0], '\\')) != NULL ){ char *pwd = NULL; //path working directory int n=0; SERVER_NAME = ++p1; n = p1-argv[0]; //calc dir name len pwd = safestrncpy((char*)malloc(n + 1), argv[0], n); if(chdir(pwd) != 0) ShowError("Couldn't change working directory to %s for %s, runtime will probably fail",pwd,SERVER_NAME); free(pwd); }else{ // On Windows the .bat files have the executeable names as parameters without any path seperator [Lemongrass] SERVER_NAME = argv[0]; } } malloc_init();// needed for Show* in display_title() [FlavioJS] #ifdef MINICORE // minimalist Core display_title(); usercheck(); do_init(argc,argv); do_final(); #else// not MINICORE set_server_type(); display_title(); usercheck(); Sql_Init(); rathread_init(); mempool_init(); db_init(); signals_init(); #ifdef _WIN32 cevents_init(); #endif timer_init(); socket_init(); do_init(argc,argv); // Main runtime cycle while (runflag != CORE_ST_STOP) { int next = do_timer(gettick_nocache()); do_sockets(next); } do_final(); timer_final(); socket_final(); db_final(); mempool_final(); rathread_final(); ers_final(); #endif malloc_final(); return 0; }
/* * Interrupt handler for interrupts coming from the Galileo chip. * It could be timer interrupt, built in ethernet ports etc... */ static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs) { unsigned int irq_src, int_high_src, irq_src_mask, int_high_src_mask; int handled; GT_READ(GT_INTRCAUSE_OFS, &irq_src); GT_READ(GT_INTRMASK_OFS, &irq_src_mask); GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); irq_src = irq_src & irq_src_mask; int_high_src = int_high_src & int_high_src_mask; handled = 0; /* Execute all interrupt handlers */ /* Check for timer interrupt */ if (irq_src & 0x00000800) { handled = 1; irq_src &= ~0x00000800; // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); do_timer(regs); } if (irq_src) { printk(KERN_INFO "Other Galileo interrupt received irq_src %x\n", irq_src); #if CURRENTLY_UNUSED for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { if (irq_src & (1 << count)) { if (irq_handlers[INT_CAUSE_MAIN][count]. routine) { queue_task(&irq_handlers [INT_CAUSE_MAIN][count], &tq_immediate); mark_bh(IMMEDIATE_BH); handled = 1; } } } #endif /* UNUSED */ } GT_WRITE(GT_INTRCAUSE_OFS, 0); GT_WRITE(GT_HINTRCAUSE_OFS, 0); #undef GALILEO_I2O #ifdef GALILEO_I2O /* * Future I2O support. We currently attach I2O interrupt handlers to * the Galileo interrupt (int 4) and handle them in do_IRQ. */ if (isInBoundDoorBellInterruptSet()) { printk(KERN_INFO "I2O doorbell interrupt received.\n"); handled = 1; } if (isInBoundPostQueueInterruptSet()) { printk(KERN_INFO "I2O Queue interrupt received.\n"); handled = 1; } /* * This normally would be outside of the ifdef, but since we're * handling I2O outside of this handler, this printk shows up every * time we get a valid I2O interrupt. So turn this off for now. */ if (handled == 0) { if (counter < 50) { printk("Spurious Galileo interrupt...\n"); counter++; } } #endif }
static irqreturn_t timer_interrupt (int irq, void *dev_id) { unsigned long new_itm; if (unlikely(cpu_is_offline(smp_processor_id()))) { return IRQ_HANDLED; } platform_timer_interrupt(irq, dev_id); new_itm = local_cpu_data->itm_next; if (!time_after(ia64_get_itc(), new_itm)) printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", ia64_get_itc(), new_itm); profile_tick(CPU_PROFILING); if (paravirt_do_steal_accounting(&new_itm)) goto skip_process_time_accounting; while (1) { update_process_times(user_mode(get_irq_regs())); new_itm += local_cpu_data->itm_delta; if (smp_processor_id() == time_keeper_id) { /* * Here we are in the timer irq handler. We have irqs locally * disabled, but we don't know if the timer_bh is running on * another CPU. We need to avoid to SMP race by acquiring the * xtime_lock. */ write_seqlock(&xtime_lock); do_timer(1); local_cpu_data->itm_next = new_itm; write_sequnlock(&xtime_lock); } else local_cpu_data->itm_next = new_itm; if (time_after(new_itm, ia64_get_itc())) break; /* * Allow IPIs to interrupt the timer loop. */ local_irq_enable(); local_irq_disable(); } skip_process_time_accounting: do { /* * If we're too close to the next clock tick for * comfort, we increase the safety margin by * intentionally dropping the next tick(s). We do NOT * update itm.next because that would force us to call * do_timer() which in turn would let our clock run * too fast (with the potentially devastating effect * of losing monotony of time). */ while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2)) new_itm += local_cpu_data->itm_delta; ia64_set_itm(new_itm); /* double check, in case we got hit by a (slow) PMI: */ } while (time_after_eq(ia64_get_itc(), new_itm)); return IRQ_HANDLED; }
/* * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. * We set it up to overflow again in 1/HZ seconds. */ void timer_interrupt(struct pt_regs * regs) { int next_dec; unsigned long cpu = smp_processor_id(); unsigned jiffy_stamp = last_jiffy_stamp(cpu); extern void do_IRQ(struct pt_regs *); if (atomic_read(&ppc_n_lost_interrupts) != 0) do_IRQ(regs); irq_enter(); while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) { jiffy_stamp += tb_ticks_per_jiffy; profile_tick(CPU_PROFILING, regs); update_process_times(user_mode(regs)); if (smp_processor_id()) continue; /* We are in an interrupt, no need to save/restore flags */ write_seqlock(&xtime_lock); tb_last_stamp = jiffy_stamp; do_timer(regs); /* * update the rtc when needed, this should be performed on the * right fraction of a second. Half or full second ? * Full second works on mk48t59 clocks, others need testing. * Note that this update is basically only used through * the adjtimex system calls. Setting the HW clock in * any other way is a /dev/rtc and userland business. * This is still wrong by -0.5/+1.5 jiffies because of the * timer interrupt resolution and possible delay, but here we * hit a quantization limit which can only be solved by higher * resolution timers and decoupling time management from timer * interrupts. This is also wrong on the clocks * which require being written at the half second boundary. * We should have an rtc call that only sets the minutes and * seconds like on Intel to avoid problems with non UTC clocks. */ if ( ppc_md.set_rtc_time && ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else /* Try again one minute later */ last_rtc_update += 60; } write_sequnlock(&xtime_lock); } if ( !disarm_decr[smp_processor_id()] ) set_dec(next_dec); last_jiffy_stamp(cpu) = jiffy_stamp; if (ppc_md.heartbeat && !ppc_md.heartbeat_count--) ppc_md.heartbeat(); irq_exit(); }
/*====================================== * CORE : MAINROUTINE *--------------------------------------*/ int main (int argc, char **argv) { {// initialize program arguments char *p1 = SERVER_NAME = argv[0]; char *p2 = p1; while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL) { SERVER_NAME = ++p1; p2 = p1; } arg_c = argc; arg_v = argv; } malloc_init();// needed for Show* in display_title() [FlavioJS] #ifdef MINICORE // minimalist Core display_title(); usercheck(); do_init(argc,argv); do_final(); #else// not MINICORE set_server_type(); display_title(); usercheck(); rathread_init(); mempool_init(); db_init(); signals_init(); #ifdef _WIN32 cevents_init(); #endif timer_init(); socket_init(); do_init(argc,argv); {// Main runtime cycle int next; while (runflag != CORE_ST_STOP) { next = do_timer(gettick_nocache()); do_sockets(next); } } do_final(); timer_final(); socket_final(); db_final(); mempool_final(); rathread_final(); #endif malloc_final(); return 0; }
void winbond_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { do_timer(regs); }
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ static void inline timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { #ifdef CONFIG_DDB5074 static unsigned cnt, period, dist; if (cnt == 0 || cnt == dist) ddb5074_led_d2(1); else if (cnt == 7 || cnt == dist+7) ddb5074_led_d2(0); if (++cnt > period) { cnt = 0; /* The hyperbolic function below modifies the heartbeat period * length in dependency of the current (5min) load. It goes * through the points f(0)=126, f(1)=86, f(5)=51, * f(inf)->30. */ period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; dist = period / 4; } #endif if(!user_mode(regs)) { if (prof_buffer && current->pid) { extern int _stext; unsigned long pc = regs->cp0_epc; pc -= (unsigned long) &_stext; pc >>= prof_shift; /* * Dont ignore out-of-bounds pc values silently, * put them into the last histogram slot, so if * present, they will show up as a sharp peak. */ if (pc > prof_len-1) pc = prof_len-1; atomic_inc((atomic_t *)&prof_buffer[pc]); } } do_timer(regs); /* * If we have an externally synchronized Linux clock, then update * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ read_lock (&xtime_lock); if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { if (set_rtc_mmss(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } /* As we return to user mode fire off the other CPU schedulers.. this is basically because we don't yet share IRQ's around. This message is rigged to be safe on the 386 - basically it's a hack, so don't look closely for now.. */ /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */ read_unlock (&xtime_lock); }