Re: list.h/macros

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Feb 15, 2004 at 12:14:25AM -0800, prasanna wakhare wrote:
> Hello ALL,
> struct list_head {
>         struct list_head *next, *prev;
> };
> 
> #define LIST_HEAD_INIT(name) { &(name), &(name) }
> 
> #define LIST_HEAD(name) \
>         struct list_head name = LIST_HEAD_INIT(name)
> 
> #define INIT_LIST_HEAD(ptr) do { \
>         (ptr)->next = (ptr); (ptr)->prev = (ptr); \
> } while (0)
> 
> #define list_entry(ptr, type, member) \
>         ((type *)((char *)(ptr)-(unsigned
> long)(&((type *)0)->member)))
> 
> #define list_for_each(pos, head) \
>         for (pos = (head)->next; pos != (head); pos =
> pos->next)
> 
>

Assume a list-entry defined like this:

  struct entry {
    int key;
    char val[64];
    struct list_head node;
  }

As you can see the "node" structure is encapsulated inside the
application-structure, and *not* the other way arround (as it might be
the case in some typical CS textbooks). Now if you have a "struct
list_head *" pointer "n" pointing to the "node" member of a "struct
entry" structure, and you want to get a pointer to the *encapsulating*
applicatio structure, then that's what you use the list_entry() macro
for:

  struct list_head *n;
  struct entry *pentry;

  ...

  pentry = list_entry(n, struct entry, node);

Schematically:

 "pentry"---->entry
             +-----------+
             |  key      |
             |  val      |
     "n"------->node     |
             |  +------+ |
             |  | next | |
             |  | prev | |
             |  +------+ |
             +-----------+

And here's an example of where this might be usefull. Assume you have
a tist defined like this:

  stuct list {
    int count;
    struct list_head head;
  } mylist;


So now if you want to find the entry where "key == THIS_KEY" you could
go like this:

   struct list_head *n;
   struct entry *pentry;

   list_for_each(n, &mylist.head) {
       pentry = list_entry(n, struct list_entry, node);
       if ( pentry->key == THIS_KEY ) break;
   }

The "list_for_each" macro will actually expand to a "for" statement.

Hope this helps.

/npat

-- 
I xeroxed a mirror.  Now I have an extra xerox machine.
  -- Stephen Wright

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux