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>