void kdi_softcall(void (*func)(void)) { kdi_softcall_func = func; if (softhead == NULL) siron(); }
/* * Call function func with argument arg * at some later time at software interrupt priority */ void softcall(void (*func)(void *), void *arg) { softcall_t *sc; clock_t w; /* * protect against cross-calls */ mutex_enter(&softcall_lock); /* coalesce identical softcalls */ for (sc = softhead; sc != 0; sc = sc->sc_next) { if (sc->sc_func == func && sc->sc_arg == arg) { goto intr; } } if ((sc = softfree) == 0) panic("too many softcalls"); softfree = sc->sc_next; sc->sc_func = func; sc->sc_arg = arg; sc->sc_next = 0; if (softhead) { softtail->sc_next = sc; softtail = sc; } else softhead = softtail = sc; intr: if (softcall_state & SOFT_IDLE) { softcall_state = SOFT_PEND; softcall_tick = lbolt; mutex_exit(&softcall_lock); siron(); } else if (softcall_state & (SOFT_DRAIN|SOFT_PEND)) { w = lbolt - softcall_tick; if (w <= softcall_delay || ncpus == 1) { mutex_exit(&softcall_lock); return; } if (!(softcall_state & SOFT_STEAL)) { softcall_state |= SOFT_STEAL; /* * We want to give some more chance before * fishing around again. */ softcall_tick = lbolt; } /* softcall_lock will be released by this routine */ (void) softcall_choose_cpu(); } }
/* * Call function func with argument arg * at some later time at software interrupt priority */ void softcall(void (*func)(void *), void *arg) { softcall_t *sc; clock_t w, now; /* * protect against cross-calls */ mutex_enter(&softcall_lock); /* coalesce identical softcalls */ for (sc = softhead; sc != 0; sc = sc->sc_next) { if (sc->sc_func == func && sc->sc_arg == arg) { goto intr; } } if ((sc = softfree) == 0) panic("too many softcalls"); softfree = sc->sc_next; sc->sc_func = func; sc->sc_arg = arg; sc->sc_next = 0; if (softhead) { softtail->sc_next = sc; softtail = sc; } else softhead = softtail = sc; intr: if (softcall_state & SOFT_IDLE) { softcall_state = SOFT_PEND; softcall_tick = lbolt; mutex_exit(&softcall_lock); siron(); } else if (softcall_state & (SOFT_DRAIN|SOFT_PEND)) { now = lbolt; w = now - softcall_tick; if (w <= softcall_delay || ncpus == 1) { mutex_exit(&softcall_lock); return; } /* * Did we poke less than a second ago? */ if (now - softcall_lastpoke < hz) { /* * We did, increment the poke count and * see if we are poking too often */ if (softcall_pokecount++ == 0) softcall_countstart = now; if (softcall_pokecount > softcall_pokemax) { /* * If poking too much increase the delay */ if (now - softcall_countstart <= hz) softcall_delay++; softcall_pokecount = 0; } } else { /* * poke rate has dropped off, reset the poke monitor */ softcall_pokecount = 0; } softcall_lastpoke = lbolt; if (!(softcall_state & SOFT_STEAL)) { softcall_state |= SOFT_STEAL; /* * We want to give some more chance before * fishing around again. */ softcall_tick = lbolt; } /* softcall_lock will be released by this routine */ (void) softcall_choose_cpu(); } }