La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Liste générique dans Linux 2.6 Source : Understanding the Linux kernel Chap3 processes p.87.

Présentations similaires


Présentation au sujet: "Liste générique dans Linux 2.6 Source : Understanding the Linux kernel Chap3 processes p.87."— Transcription de la présentation:

1 Liste générique dans Linux 2.6 Source : Understanding the Linux kernel Chap3 processes p.87

2 plan Pointeur Structure Chaînage Liste

3 Les pointeurs éé Gestion de lespace mémoire en cours dexécution éè Modifications de variables passées en paramètres de fonction éèé Représentation de tableaux: accès direct et indexé

4 int* a; Déclaration dun pointeur vers un entier et initialisation à NULL int* a = NULL; a Rappels sur les pointeurs

5

6 int* a = malloc(3*sizeof(int)); Allocation dynamique et assignement int* a = (int*)malloc(3*sizeof(int)); a *a

7 Désallocation dynamique free(a); a a = NULL; *a

8 Rappels #define NB_ELEMENTS 2 int *pk; pk = malloc(NB_ELEMENTS * sizeof(int)); //allocation pour 2 int *pk = 10; *(pk + 1) = 20; #define NB_ELEMENTS 2 int *pk; pk = malloc(NB_ELEMENTS * sizeof(int)); //allocation pour 2 int *pk = 10; *(pk + 1) = 20; Malloc.c 00000000 pk=0x33c18 pk+1=0x33c1c 00000000 00001010 00000000 00010100 10 20

9 Rappels : les structures struct nomprenomage { char nom[1]; char prenom[4]; int age; }; Struct nomprenomage * ptr; ptr = &nomprenomage; ptr->age ~ (*ptr).nom struct nomprenomage { char nom[1]; char prenom[4]; int age; }; Struct nomprenomage * ptr; ptr = &nomprenomage; ptr->age ~ (*ptr).nom 0x2 nom0 0x3 prenom1 0x10 age8

10 Rappels struct nomprenomage { char nom[10]; char prenom[10]; int age; }; Struct nomprenomage groupe[n]; struct nomprenomage { char nom[10]; char prenom[10]; int age; }; Struct nomprenomage groupe[n]; groupe[i].nom référence le nom de la personne qui a lindex i.

11 Rappels struct adresse { char *rue; int num; } nomadresse; struct adresse { char *rue; int num; } nomadresse; Cette définition réserve en mémoire la place pour 2 variables : La variable nomadresse.num de type int La variable nomadresse.rue de type pointeur sur le type char Cette définition ne réserve pas de place pour stocker le nom de rue.

12 Rappels: structures et pointeurs struct adresse { char *rue; int num; } nomadresse; struct adresse nomadresse *ptr; ptr=&nomadresse; struct adresse { char *rue; int num; } nomadresse; struct adresse nomadresse *ptr; ptr=&nomadresse; On a donc *ptr== nomadresse nomadresse.Num ou (*ptr).num désigne une variable de type int Les parenthèses sont nécessaires car lopérateur point. Qui donne laccès aux champs dune structure est prioritaire sur * On désignera volontiers (*ptr).num par ptr->num

13 Rappel : erreur courante struct adresse { char *rue; int num; }; struct adresse nomadresse *ptr; … ptr->num=12 struct adresse { char *rue; int num; }; struct adresse nomadresse *ptr; … ptr->num=12 A lexécution tout peut arrivé ! struct adresse nomadresse *ptr; réserve la place pour stoquer une adresse mais ne garantie pas que la valeur de p est une adresse où lon puisse stocker la structure ; elle ne réserve pas la place dune structure à ladresse pointée par ptr. il faut soit : ptr=&nomadresse; ou ptr = malloc(sizeof(*ptr));

14 Rappel : liste 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) include/linux/list.h

15 Double liste chaînée ? La liste est doublement chaînée. Elle ne contient aucune donnée à lintérieur ? prev next list_head

16 Déclaration exemple de déclaration linux/kernel/timer.c dans static inline void __run_timers(tvec_base_t *base) struct list_head work_list = LIST_HEAD_INIT(work_list); struct list_head *head = &work_list;

17 Chaînage List_head est le premier élément vide qui joue un rôle particulier de placeholder pour la tête de la nouvelle liste prev next list_head prev next list_head prev next list_head

18 Chaînage prev next list_head prev next list_head prev next list_head prev next list_head new prevnext

19 Chaînage prev next list_head prev next list_head prev next list_head prev next list_head new prevnext next->prev = new; new->next = next; new->prev = prev; prev->next = new;

20 Chaînage prev next list_head prev next list_head prev next list_head prev next list_head new prevnext next->prev = new; new->next = next; new->prev = prev; prev->next = new;

21 Chaînage prev next list_head prev next list_head prev next list_head prev next list_head new prevnext next->prev = new; new->next = next; new->prev = prev; prev->next = new;

22 Chaînage prev next list_head prev next list_head prev next list_head prev next list_head new prevnext next->prev = new; new->next = next; new->prev = prev; prev->next = new;

23 Chaînage prev next list_head prev next list_head prev next list_head prev next list_head prevnext next->prev = new; new->next = next; new->prev = prev; prev->next = new;

24 Fin dinsertion connaissant Prev et Next prev next list_head prev next list_head prev next list_head prev next list_head prev next list_head prev next list_head prev next list_head Avant Après

25 Insertion en tête prev next list_head prev next list_head prev next list_head prev next list_head new

26 Insertion en queue prev next list_head prev next list_head prev next list_head prev next list_head new

27 Autres fonctions List_empty List_delete

28 Macros /** * list_for_each-iterate over a list * @pos:the &struct list_head to use as a loop counter. * @head:the head for your list. */ #define list_for_each(pos, head) \ for (pos = (head)->next; prefetch(pos->next), pos != (head); \ pos = pos->next)

29 plan Pointeur Structure Chaînage Liste

30 Manipulation des listes prev next list_head prev next list_head prev next list_head prev next list_head Struc1Struc2Struc3

31 Et pas un pointage sur la tête de la structure prev next list_head prev next list_head prev next list_head prev next list_head Struc1Struc2Struc3

32 Manipulation des listes prev next list_head prev next list_head prev next listétudiants prev next list_head Struc1Struc2Struc3 prev next list_head prev next list_head prev next listalternants

33 Manipulation des listes prev next list_head prev next list_head prev next list_head prev next list_head Struc1Struc2Struc3 Mais comment récupérer ces pointeurs ?

34 Rappels struct humain { char nom[1]; char prenom[4]; int age; }; 0x2 nom 0x3 prenom 0x10 age Containerof.c

35 Offsetof : offsetof(struct nomprenomage,age))= &((struct nomprenomage *)0)->age Or (struct nomprenomage *)0 définit un pointeur de valeur 0 offsetof(struct nomprenomage,age)= (struct nomprenomage *)0 – &((struct nomprenomage *)0)->age Linux/stdef.h

36 Rappels struct humain { char nom[1]; char prenom[4]; int age; }; 0x2 nom0 0x3 prenom1 0x10 age8 Containerof.c offsetof

37 Comment obtenir la valeur du pointeur sur la struct struct humain { char nom[1]; char prenom[4]; int age; }; 0x2 nom 0x3 prenom 0x10 age Connu Containerof.c ?

38 Container_of #define container_of(ptr, type, member) ({\ const typeof( ((type *)0)->member ) *__mptr = (ptr);\ (type *)( (char *)__mptr - offsetof(type,member) );}) Pour avoir ladresse du début de la structure connaissant ladresse dun des membres : ptr = container_of(ptrhumain ->age,struct humain,age); Include/linux/kernel.h

39 List_entry(p,t,m) #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:the 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) );})

40 Pourquoi une liste générique Le noyau a besoin de conserver beaucoup dinformations La liste de tous les processus La liste des processus actifs La liste des processus actifs suspendus A compléter Pour éviter dimplémenter pour chaque type de liste les primitives de bases et pour un gain de mémoire, il est intéressant de définir une structure de liste générique.

41 Exemple avec les processus Include/linux/sched.h struct task_struct { … struct list_head run_list; … struct list_head tasks; … struct list_head ptrace_children; struct list_head ptrace_list; … struct list_head children;/* list of my children */ struct list_head sibling;/* linkage in my parent's children list */ … struct list_head cpu_timers[3]; };

42 Macro list_for_each_entry /** * list_for_each_entry-iterate over list of given type * @pos:the type * to use as a loop counter. * @head:the head for your list. * @member:the name of the list_struct within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) Permet de pointer sur chaque éléments de la liste :

43 Manipulation des listes prev next list _head prev next list _head prev next étudiants prev next list_head Struc1Struc2Struc3 prev next list_head prev next list_head prev next alternants 0x33c0 offset=0 0x33c8 offset=8 0x33cf offset=f

44 Rappels struct humain { char nom[1]; char prenom[4]; int age; }; offsetof(struct humain,age)); = 8 0xff2 nom0 0xff3 prenom1 0xffA age8 adresse offsetof


Télécharger ppt "Liste générique dans Linux 2.6 Source : Understanding the Linux kernel Chap3 processes p.87."

Présentations similaires


Annonces Google