2009-02-17 6 views
8

J'ai lu le chapitre 7 dans le 'Pilotes de périphériques Linux' (which can be found here) que le temps peut être mesuré en 'jiffies'. Le problème avec la variable stock jiffies est qu'elle s'enroule assez souvent (surtout si votre CONFIG_HZ est réglé sur 1000).Indication du temps dans le noyau Linux 2.6

Dans mon module noyau, j'économise une valeur Jiffies qui est définie à un certain moment dans le futur et la compare plus tard avec la valeur 'jiffies' actuelle. Je l'ai déjà appris qu'il ya des fonctions qui prennent l'enveloppe 32bit tournemain en considération afin de comparer deux valeurs que je utilise ceci:

if (time_after(jiffies, some_future_jiffies_value)) 
{ 
    // we've already passed the saved value 
} 

vient ici ma question: Alors maintenant, je veux mettre le « some_future_jiffies_value » à "maintenant + 10 ms". Ceci peut facilement être accompli en faisant ceci:

some_future_jiffies_value = jiffies + msecs_to_jiffies(10); 

Est-ce correct? Que se passe-t-il si les jiffies actuels sont proches de MAX_JIFFY_OFFSET et que la valeur résultante de msecs_to_jiffies (10) place un peu plus value_jiffies_value après ce décalage? Est-ce que ça va automatiquement ou dois-je ajouter du code pour vérifier cela? Y at-il des fonctions qui me sauvent d'avoir à faire face à cela?

Mise à jour:

Pour éviter des choses Wraparound j'ai réécrite ma boucle de sommeil:

// Sleep for the appropriate time 
    while (time_after(some_future_jiffies_value, jiffies)) 
    { 
     set_current_state(TASK_INTERRUPTIBLE); 
     schedule_timeout(1); 
    } 

Je suppose que cela est plus juste portable?

Mise à jour 2:

Merci beaucoup « ctuffli » pour prendre le temps de revenir à cette question et de fournir des commentaires sur mes commentaires aussi bien. Mon pilote de noyau fonctionne bien maintenant et il est beaucoup moins laid comparé à la situation avant que vous me fournissiez tous ces conseils. Merci!

+0

Une autre idée: l'utilisation de get \ _jiffies \ _64() m'empêcherait-elle d'avoir à penser au wraparound et de me laisser faire des calculs simples? – Benjamin

Répondre

6

Ce que vous implémentez est ici essentiellement msleep_interruptible() (linux/kernel/timer.c)

/** 
* msleep_interruptible - sleep waiting for signals 
* @msecs: Time in milliseconds to sleep for 
*/ 
unsigned long msleep_interruptible(unsigned int msecs) 

Cette fonction a l'avantage que la spécification est en millisecondes et se cache les détails de jiffies emballage interne. Assurez-vous de vérifier les valeurs de retour lorsque cet appel renvoie le nombre de jiffies restantes. Zéro signifie que l'appel a dormi le nombre spécifié de millisecondes tandis qu'une valeur non nulle indique que l'appel a été interrompu autant de fois au début.

En ce qui concerne l'emballage, voir la section 6.2.1.2 pour une description des jiffies et de l'emballage. En outre, ce post essaie de décrire l'habillage dans l'abstrait.

+0

Si je regarde la source de msleep_interruptible, il semble remarquablement similaire! Je devrais encore considérer la valeur de retour de cette fonction si je comprends bien puisque le sommeil interruptible peut retourner plus tôt que prévu juste? – Benjamin

+0

En ce qui concerne la mise au point d'un dépassement de délai MAX_JIFFY_OFFSET, avez-vous une idée si cela vous convient? Je vois que cela arrive souvent dans les sources du noyau, mais c'est une question plus théorique que je me posais. Merci d'avoir pris le temps de répondre jusqu'à présent! :) – Benjamin

Questions connexes