Double-chain table in uclinux2.6

Source: Internet
Author: User

A double-stranded table is a data structure that is used in the uclinux2.6 kernel. It separates the data and operations of the double-stranded table, so that some operations of the double-stranded table do not involve specific data. The examples in this article are drivers/MTD/mtdpart. C and include/Linux/list. h. 1 DefinitionThe definition of double-stranded tables and their basic operations are implemented in include/Linux/list. in H, the following is its definition:/** simple doubly linked list implementation. ** some of the internal functions ("_ XXX") are useful when * manipulating whole lists rather than single entries, as * Sometimes we already know the next/Prev entries and we can * generate better code by using them directly rather than * using the generic single-entry routines. */struct list_head {St Ruct list_head * Next, * Prev;}; uClinux also provides a macro to define the header of a double-stranded table: # define list_head_init (name) {& (name), & (name )} # define list_head (name)/struct list_head name = list_head_init (name) from the above definition, we can see that the next and Prev pointers of the header are directed to itself during initialization. The following is an example in mtdpart. C:/* Our partition linked list */static list_head (mtd_partitions ); 2 combination of linked list and DataNo specific data can be seen from the definition of the linked list. How can this double-chain table be used? Let's take a look at the use of mtdpart. C. /* Our partition node Structure */struct mtd_part {... Struct list_head list ;...}; This is the data structure linked to a double-stranded table. In this structure, a list of list_head is declared, and this member will be used for the link of this structure. Int add_mtd_partitions (struct mtd_info * master, const struct mtd_partition * parts, int nbparts) {struct mtd_part * slave; int I; for (I = 0; I <nbparts; I ++) {/* allocate the partition structure */Slave = kmalloc (sizeof (* slave), gfp_kernel );... List_add (& slave-> list, & mtd_partitions );...} Return 0;} It is through the list_add function that links the specific data structure to the table header of the double-stranded table. The following is the implementation of list_add:/** Insert a new entry between two known consecutive entries. ** this is only for internal list manipulation where we know * The Prev/next entries already! */# Ifndef config_debug_liststatic inline void _ list_add (struct list_head * New, struct list_head * Prev, struct list_head * Next) {next-> Prev = new; new-> next = next; New-> Prev = Prev; Prev-> next = new;} # elseextern void _ list_add (struct list_head * New, struct list_head * Prev, struct list_head * Next); # endif/*** list_add-Add a new entry * @ New: New entry to be added * @ head: list head to add it after ** Insert a new entry after the specified head. * This is good for implementing stacks. */# ifndef config_debug_liststatic inline void list_add (struct list_head * New, struct list_head * head) {_ list_add (new, head, head-> next );} # elseextern void list_add (struct list_head * New, struct list_head * head); # endif 3. Access to double-stranded table membersHow can I access the members of a dual-link table? The following is mtdpart. example of C:/** this function unregisters and destroy all slave MTD objects which are * attached to the given master mtd object. */INT del_mtd_partitions (struct mtd_info * master) {struct list_head * node; struct mtd_part * slave; For (node = mtd_partitions.next; node! = & Mtd_partitions; node = node-> next) {slave = list_entry (node, struct mtd_part, list );...} Return 0;} the secret is defined in the macro list_entry:/*** list_entry-get the struct for this entry * @ PTR: The & struct list_head pointer. * @ type: the type of the struct this is embedded in. * @ member: the name of the list_struct within the struct. */# define list_entry (PTR, type, member)/container_of (PTR, type, member) /*** container_of-cast a member of a structure out to the Containing Structure * @ PTR: Pointer to the member. * @ type: the type of the container struct this is embedded in. * @ member: the name of the member within the struct. **/# define container_of (PTR, type, member) ({/const typeof (type *) 0)-> member) * _ mptr = (PTR ); /(type *) (char *) _ mptr-offsetof (type, member);}) Note the use of the keyword typeof, in the visual DSP documentation, the typeof keyword is an extension to C originally implement Ed in the GCC compiler. it shoshould be used with caution because it is not compatible with other dialects of C or C ++ and has not been adopted by the more recent c99 standard. the definition of offsetof is better understood: # define offsetof (type, member) (size_t) & (type *) 0)-> member) in the above example, a For Loop is directly used to access the members of the linked list. A more common method is to use the following macro:/*** list_for_each-iterate over a list * @ pos: the & struct list_head to use as a loop cursor. * @ H EAD: The head for your list. */# define list_for_each (Pos, head)/For (Pos = (head)-> next; prefetch (POS-> next), pos! = (Head);/Pos = pos-> next) Example: static list_head (part_parsers); static struct mtd_part_parser * get_partition_parser (const char * Name) {struct list_head * this;... List_for_each (this, & part_parsers) {struct mtd_part_parser * P = list_entry (this, struct mtd_part_parser, list );... }...} 4 advantagesThe implementation of the dual-chain table in uClinux has the advantage that the code is greatly simplified with a small space cost (8-byte linked list header. If you only use one pointer to store the table header of a double-link table, you must determine whether the header pointer is null during each insert or delete operation!

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.