Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Oct 1996 13:28:26 -0700 (MST)
From:      Terry Lambert <terry@lambert.org>
To:        ilv@coatepec.uaemex.mx (Isidoro Liendo)
Cc:        questions@freebsd.org, hackers@freebsd.org
Subject:   Re: Interrupts and ipintr
Message-ID:  <199610092028.NAA18610@phaeton.artisoft.com>
In-Reply-To: <325B2035.167EB0E7@coatepec.uaemex.mx> from "Isidoro Liendo" at Oct 8, 96 10:47:01 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> I'am trying to figure out how does FreeBSD "register" the function
> ipintr so that whenever a network interrupt occurs it "knows" that
> the funtion to be call is precisly ipintr (if the packets that arrived
> is and IP packet of course). I have read the code and I found a call
> to NETISR_SET(NETISR_IP,ipintr) in the file ip_input.c. 
> 
> Does this call "register" ipintr as the function to be called during the
> interrupt? 
> 
> I also have "followed" this macro to DATA_SET and the to MAKE_SET after 
> which something called "asm()" is called. Could anybody explain me what
> does this function does?

The _SET macros operate on "linker sets".

A "linker set" is an array of addresses which is placed in a symbol
reference by the linker.

You can think of it as an agregate initializer of a global struct:

	struct linker_set {
		int	ls_length;
		caddr_t	ls_items[];
	};

So you get:

	struct linker_set some_set = {
		3,
		{	&item1,
			&item2,
			&item3,
			NULL
		}
	};

Where item1 comes from one object file, item2 from another, and so
on.

So it's like a global agregate initializer that you can declare across
a bunch of files.


The reason you use these things is to allow you to include object files
and have everything "magically work" without having to #ifdef the number
of items.  If you wanted to make item1, item2, and item3 optional in our
example, you'd need:


	struct linker_set some_set = {
#ifdef ITEM1_OPTION
#ifdef ITEM2_OPTION
#ifdef ITEM3_OPTION
		3,		/* items 1 + 2 + 3*/
#else	/* !ITEM3_OPTION*/
		2,		/* items 1 + 2*/
#endif	/* !ITEM3_OPTION*/
#else	/* !ITEM2_OPTION*/
#ifdef ITEM3_OPTION
		2,		/* items 1 + 3*/
#else	/* !ITEM3_OPTION*/
		1,		/* item 1*/
#endif	/* !ITEM3_OPTION*/
#endif	/* !ITEM2_OPTION*/
#else	/* !ITEM1_OPTION*/
#ifdef ITEM2_OPTION
#ifdef ITEM3_OPTION
		2,		/* items 2 + 3*/
#else	/* !ITEM3_OPTION*/
		1,		/* item 2*/
#endif	/* !ITEM3_OPTION*/
#else	/* !ITEM2_OPTION*/
#ifdef ITEM3_OPTION
		1,		/* item 3*/
#else	/* !ITEM3_OPTION*/
		0,		/* no items*/
#endif	/* !ITEM3_OPTION*/
#endif	/* !ITEM2_OPTION*/
#endif	/* !ITEM1_OPTION*/
		3,
		{
#ifdef ITEM1_OPTION
			&item1,
#endif	/* ITEM1_OPTION*/
#ifdef ITEM2_OPTION
			&item2,
#endif	/* ITEM2_OPTION*/
#ifdef ITEM3_OPTION
			&item3,
#endif	/* ITEM3_OPTION*/
			NULL
		}
	};

And then conditionally compile the file containing it.

A bit more complicated, don't you think?  8-).


To get bact to your first question, it adds a funtion to the list of
functions that get called for the NETISR -- Net Interrupt Service Routine.


					Regards,
					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199610092028.NAA18610>