C printf () dans le gestionnaire d’interruption?

J’ai entendu printf () en C n’est pas censé être utilisé dans ISR. Est-ce parce que c’est un appel bloquant, ou est-ce parce que ce n’est pas ré-entrant?

Si printf () n’est pas ré-entrant, cela ne signifie-t-il pas qu’il ne peut pas non plus être utilisé pour un programme multi-thread, à moins d’être «synchronisé»?

Merci,

Je pense que cela pourrait être tout cela, et plus. Les implémentations typiques de printf() peuvent effectuer une allocation de mémoire dynamic (heap), ce qui n’est généralement pas la chose la plus rapide à faire et peut également avoir des problèmes de non-ré-entrée. La rapidité peut avoir de l’importance, car vous n’êtes généralement pas censé passer trop de temps dans une routine de service d’interruption.

Voir cette réponse pour une discussion sur printf() et malloc() .

Je suppose que vous entendez des interruptions, même si les gestionnaires d’interruptions dans les kernelx ont généralement des limitations bien plus spécifiques. Le même argument s’applique aux gestionnaires de signaux, mais il est généralement plus simple que les ressortingctions spéciales applicables aux gestionnaires d’interruptions. Si mon hypothèse est fausse, remplacez simplement “interruption” par “signal” dans la réponse et cela s’appliquera.

Les fonctions peuvent être thread-safe sans être en sécurité signal / interruption. Si la fonction protège son état interne avec un verrou, puis maintient ce verrou lors de l’obtention d’une interruption, le gestionnaire d’interruptions n’a aucun moyen d’acquérir ce verrou, car le chemin d’exécution qui contient le verrou est bloqué par l’interruption. Pour libérer le verrou, vous devez quitter le gestionnaire d’interruptions, reprendre l’exécution du thread jusqu’à ce que le verrou soit libéré, puis revenir au gestionnaire d’interruptions. Cela n’est généralement pas faisable à moins que votre kernel n’ait implémenté des gestionnaires d’interruption sous forme de threads pouvant donner lieu à une exécution lors de l’attente de verrous.

Une façon normale de rendre une fonction à la fois interruption et thread-safe est de bloquer les interruptions tout en maintenant le verrou, mais ceci est assez coûteux et ne peut être effectué que si cela est vraiment nécessaire.

Cela ne devrait pas être dans un ISR, car ce n’est ni réentrant ni thread-safe, mais surtout parce que c’est une fonction extrêmement énorme qui verrouille tout le programme si vous l’appelez depuis un ISR, ce qui crée instantanément une gigue d’interruption extrême tuant chaque soupçon de performance en temps réel de votre programme.

Les fonctions énormes et explosives ne doivent pas figurer dans les ISR, qu’ils soient thread-safe ou non!

J’ai entendu printf () en C n’est pas censé être utilisé dans ISR. Est-ce parce que c’est un appel bloquant, ou est-ce parce que ce n’est pas ré-entrant?

Plus précisément parce que printf() n’est pas une fonction async-signal-safe. Reportez-vous à la liste de sécurité async-signal-safe au bas de Signal Concepts .

Si vous appelez printf () à partir de là, cela fonctionnera peut-être une ou deux fois. S’ils essaient de bloquer, c’est un désastre, car les gestionnaires d’interruptions n’ont pas de contexte de thread.

Si vous liez des bibliothèques multithreads à des éléments incorporés, printf () obtiendra un verrou de style mutex pour garantir la sécurité des appels provenant de plusieurs threads.

Comme le disent les autres affiches, il suffit de ne pas appeler de telles informations auprès de gestionnaires d’interruptions. La signalisation en unités de sémaphore est toujours sûre, IME. Autres éléments uniquement s’ils sont spécifiquement indiqués comme tels dans la documentation du système d’exploitation.