IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Administration système Discussion :

[Noyau] Scheduler et liste


Sujet :

Administration système

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de thecaptain
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Décembre 2003
    Messages
    919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Décembre 2003
    Messages : 919
    Par défaut [Noyau] Scheduler et liste
    Salut à tous,

    Dans le cadre d'un projet académique, nous sommes amenés à écrire un petit scheduler basique pour le noyau 2.6.33.

    Le fonctionnement est très simple : il y a 5 listes de priorités et le scheduler exécute toujours les tâches qui sont contenues dans la première liste non vide (de la plus haute priorité à la plus faible). A l'intérieur d'une liste, les tâches sont exécutées en round-robin (chaque tâche obtient un certain nombre de slice) et lorsqu'une tâche a tourné un certain nombre de fois, elle est déplacée dans la prochaine liste de plus basse priorité.

    J'ai donc écrit le scheduler sans trop de problème. Tout fonctionne comme ça doit pendant un certain temps. Par contre, tout d'un coup les tâches sont exécutées en mode FIFO (plus de round-robin à l'intérieur des listes).

    Voici les structures que j'utilise (les constantes ne sont généralement que des entiers) :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    struct dummy_rq {
        struct list_head list;
        struct task_struct *task;
     
        //priority list in which the task resides (linked with the 'list' attribute)
        int priority_list;
     
        //number representing the aging of a process. As this value reaches zero it
        //will have a lower priority inside the dummy scheduler
        int time_tick_age;
        int time_tick_age_init;
     
        //number of tick a process is allowed to stay running. Once this value reaches
        //zero, it will be added at the end of the queue so another one can be executed
        //by the cpu (round-robin)
        int time_tick_init;
        int time_tick;
    };

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct rq 
    {
        struct dummy_rq dummy_rq_queues[NB_PRIORITY_QUEUES];
        //... pleins d'autres attributs
    }

    Et ici les principaux morceaux de code pour la récupération d'une tâche :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //récupère la prochaine tâche à exécuter (prend toujours la
    //première dans la première liste vide - les liste sont ordonnées)
    static struct task_struct *pick_next_task_dummy(struct rq *rq)
    {
        for (index=0 ; index<NB_PRIORITY_QUEUES ; ++index)
        {
            if (!list_empty(&rq->dummy_rq_queues[index].list)) 
            {
                struct dummy_rq* dummy = list_first_entry(&rq->dummy_rq_queues[index].list, struct dummy_rq, list);
                return dummy->task;
            }
        }
     
        return NULL;
    }
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    //fonction appelées à chacke time slice du CPU. La tâche courante reste
    //un certain nombre de tick et puis est passée à la fin de la liste
    static void task_tick_dummy(struct rq *rq, struct task_struct *curr, int queued)
    {
        struct dummy_rq* current_task;
     
        current_task = _get_dummy(rq, curr);
        if (current_task == NULL) return; 
     
        current_task->time_tick--;     
        if (current_task->time_tick <= 0)
        {
            current_task->time_tick = current_task->time_tick_init;
     
            current_task->time_tick_age--;
            if (current_task->time_tick_age <= 0)
            {
                current_task->time_tick_age = current_task->time_tick_age_init;
                update_priority(rq, current_task, (current_task->priority_list)+1);
            }
            else
            {
                list_move_tail(&current_task->list, &rq->dummy_rq_queues[current_task->priority_list].list);
            }
        }
    }

    J'ai affiché à coup de printk ce qui se passait dans cette liste au bout d'un moment. Il semble que tout d'un coup la tâche retournée par pick_next_task_dummy soit toujours la même et ce malgré qu'elle ait été mise en fin de queue via list_move_tail dans la fonction task_tick_dummy... De plus, lorsque la tâche est enlevée de la queue (list_del), c'est bien la suivante qui s'exécute (mais toujours pas de round-robin).

    Le plus bizarre est que ce problème n'apparait qu'après un certain temps (environ 10 min) après avoir booté le noyau. Avant ça, le scheduler fonctionne correctement !

    Il y a probablement un truc que je comprends pas ou que j'utilise mal, donc si quelqu'un a une idée je suis preneur

    Merci d'avance !

  2. #2
    Membre émérite
    Avatar de thecaptain
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Décembre 2003
    Messages
    919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Décembre 2003
    Messages : 919
    Par défaut
    Resalut à tous,

    J'ai finalement trouvé la solution : après chaque appel à list_move_tail(...), il faut également ajouter un appel à resched_task(...) afin que le scheduler soit dans un état cohérent semble-t-il.
    Après avoir fait cela, plus aucun problème de round robin !

    @++

Discussions similaires

  1. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 21h25
  2. Primitive du noyau
    Par freud dans le forum Programmation d'OS
    Réponses: 5
    Dernier message: 25/11/2002, 04h17
  3. liste d'objets
    Par Pierrot dans le forum Langage
    Réponses: 2
    Dernier message: 27/09/2002, 10h56
  4. Compter le nombre ligne listée (COUNT) ?
    Par StouffR dans le forum Langage SQL
    Réponses: 7
    Dernier message: 02/09/2002, 10h41
  5. Listes déroulantes liées entre elles
    Par denisC dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 27/07/2002, 16h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo