FreeBSD/sys/kern/kern_intr.c
/*
 * This is the main code for interrupt threads.
 */
This is the main code for interrupt threads.
This is the main code for interrupt threads .
static void
ithread_loop(void *arg)
{
	struct intr_thread *ithd;
	struct intr_event *ie;
	struct thread *td;
	struct proc *p;
	int wake;
	td = curthread;
	p = td->td_proc;
	ithd = (struct intr_thread *)arg;
	KASSERT(ithd->it_thread == td,
	    ("%s: ithread and proc linkage out of sync", __func__));
	ie = ithd->it_event;
	ie->ie_count = 0;
	wake = 0;
	for (;;) {
		if (ithd->it_flags & IT_DEAD) {
			CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
			    p->p_pid, td->td_name);
			free(ithd, M_ITHREAD);
			kthread_exit();
		}
		while (atomic_cmpset_acq_int(&ithd->it_need, 1, 0) != 0)
			ithread_execute_handlers(p, ie);
		WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread");
		mtx_assert(&Giant, MA_NOTOWNED);
		thread_lock(td);
		if (atomic_load_acq_int(&ithd->it_need) == 0 &&
		    (ithd->it_flags & (IT_DEAD | IT_WAIT)) == 0) {
			TD_SET_IWAIT(td);
			ie->ie_count = 0;
			mi_switch(SW_VOL | SWT_IWAIT, NULL);
		}
		if (ithd->it_flags & IT_WAIT) {
			wake = 1;
			ithd->it_flags &= ~IT_WAIT;
		}
		thread_unlock(td);
		if (wake) {
			wakeup(ithd);
			wake = 0;
		}
	}
}
static void ithread_loop ( void * arg ) { struct intr_thread * ithd ; struct intr_event * ie ; struct thread * td ; struct proc * p ; int wake ; td = curthread ; p = td -> td_proc ; ithd = ( struct intr_thread * ) arg ; KASSERT ( ithd -> it_thread == td , ( " " , __func__ ) ) ; ie = ithd -> it_event ; ie -> ie_count = 0 ; wake = 0 ; for ( ; ; ) { if ( ithd -> it_flags & IT_DEAD ) { CTR3 ( KTR_INTR , " " , __func__ , p -> p_pid , td -> td_name ) ; free ( ithd , M_ITHREAD ) ; kthread_exit ( ) ; } while ( atomic_cmpset_acq_int ( & ithd -> it_need , 1 , 0 ) != 0 ) ithread_execute_handlers ( p , ie ) ; WITNESS_WARN ( WARN_PANIC , NULL , " " ) ; mtx_assert ( & Giant , MA_NOTOWNED ) ; thread_lock ( td ) ; if ( atomic_load_acq_int ( & ithd -> it_need ) == 0 && ( ithd -> it_flags & ( IT_DEAD | IT_WAIT ) ) == 0 ) { TD_SET_IWAIT ( td ) ; ie -> ie_count = 0 ; mi_switch ( SW_VOL | SWT_IWAIT , NULL ) ; } if ( ithd -> it_flags & IT_WAIT ) { wake = 1 ; ithd -> it_flags &= ~ IT_WAIT ; } thread_unlock ( td ) ; if ( wake ) { wakeup ( ithd ) ; wake = 0 ; } } }
This is the main code for interrupt threads.
This is the main code for interrupt threads .
/*
	 * As long as we have interrupts outstanding, go through the
	 * list of handlers, giving each one a go at it.
	 */ /*
		 * If we are an orphaned thread, then just die.
		 */ /*
		 * Service interrupts.  If another interrupt arrives while
		 * we are running, it will set it_need to note that we
		 * should make another pass.
		 *
		 * The load_acq part of the following cmpset ensures
		 * that the load of ih_need in ithread_execute_handlers()
		 * is ordered after the load of it_need here.
		 */ /*
		 * Processed all our interrupts.  Now get the sched
		 * lock.  This may take a while and it_need may get
		 * set again, so we have to check it again.
		 */