示例#1
0
/*
 * 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();
	}
}
示例#2
0
/*
 * 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();
	}
}