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>
