patseb patseb - 1 month ago 14
C Question

Linux Kernel List LIST_HEAD_INIT vs INIT_LIST_HEAD

I'm trying to understand linux kernel linked list.

Depends on Linux Kernel Linked List I've should initialize list head by

INIT_LIST_HEAD
but here(Linux Kernel Program) they are talking about
LIST_HEAD_INIT
.

I wrote working code, but I'm not sure if I did it in proper way, could someone verify that ?

#include <stdio.h>
#include <stdlib.h>
#include "list.h"

typedef struct edge_attr {
int d;
struct list_head list;
} edge_attributes_t;

typedef struct edge {
int id;
edge_attributes_t *attributes;
} edge_t;

int main () {
int i;
struct list_head *pos;
edge_attributes_t *elem;
edge_t *a = (edge_t*)malloc(sizeof(edge_t));

a->id = 12;
a->attributes = (edge_attributes_t*) malloc(sizeof(edge_attributes_t));

INIT_LIST_HEAD(&a->attributes->list);

for (i=0; i<5; ++i) {
elem = (edge_attributes_t*)malloc(sizeof(edge_attributes_t));
elem->d = i;
list_add(&elem->list, &a->attributes->list);
}

list_for_each(pos, &(a->attributes->list)) {
elem = list_entry(pos, edge_attributes_t, list);
printf("%d \n", elem->d);
}

return 0;
}

Answer

A quick LXR search shows:

#define LIST_HEAD_INIT(name) { &(name), &(name) }

static inline void INIT_LIST_HEAD(struct list_head *list)
{
        list->next = list;
        list->prev = list;
}

So INIT_LIST_HEAD gets a struct list head * and initializes it, while LIST_HEAD_INIT returns the address of the passed pointer in a suitable fashioned for use as an initializer for a list:

struct list_head lst1;
/* .... */
INIT_LIST_HEAD(&lst1);



struct list_head lst2 = LIST_HEAD_INIT(lst2);