2014-04-29 6 views
2

Je travaille sur une application OSX qui transmet des données à un périphérique matériel via un port série USB. Le matériel a un petit tampon série qui est drainé à un taux variable et devrait toujours rester non vide.Création d'un fil de discussion en temps réel sous OSX

Nous avons une boucle d'écriture dans son propre NSThread qui vérifie si le tampon matériel est plein, et sinon, écrit des données jusqu'à ce qu'il soit. La majorité des itérations de boucle n'écrivent rien et prennent presque pas de temps, mais elles peuvent parfois prendre jusqu'à quelques millisecondes (comme avec CACurrentMediaTime). Le thread dort pendant 100ns après chaque itération. (Je sais que le temps de sommeil semble incroyablement court, mais si nous tombons vers le haut, le matériel commence à obtenir des données affamée.)

Cela fonctionne bien la plupart du temps. Cependant, si le thread principal ou une autre application commence à faire un travail intensif sur le processeur, le thread d'écriture ralentit et ne peut pas diffuser des données assez rapidement pour empêcher la file d'attente du périphérique de se vider. Donc, nous aimerions rendre le thread d'écriture en série en temps réel. J'ai lu the Apple docs sur demande de planification en temps réel grâce à l'API Mach, puis essayé d'adapter l'extrait de code de SetPriorityRealtimeAudio (mach_port_t mach_thread_id) dans le Chromium source. Toutefois, cela ne fonctionne pas - l'application reste tout aussi sensible aux ralentissements de la communication série. Des idées? Je ne suis pas sûr si j'ai besoin de changer le comportement du thread d'écriture, ou si je passe dans les mauvais paramètres de stratégie de thread, ou les deux. J'ai expérimenté diverses valeurs de période/calcul/contrainte, et forcer un cycle de fonctionnement plus cohérent (écrire pour 100ns max puis dormir pour 100ns) mais pas de chance.

Une question connexe: Comment puis-je vérifier directement la priorité du fil, et/ou dire si elle commence REDUCTIONS en temps réel et étant ensuite rétrogradé vs pas d'être promu pour commencer? En ce moment, je ne fais que des inférences à partir des performances du matériel, il est donc difficile de dire exactement ce qui se passe.

+0

Le pilote « de série USB » ne pas interrompre sur « TxEmpty » , permettant ainsi une interface non-interrogation? Sinon, ça craint. –

+0

C'est un système d'exploitation multi-thread avec un planificateur qui est censé faire cela. Pouvez-vous nous expliquer un peu plus pourquoi il y a un tel problème (utilisez-vous un dispositif médical essentiel à la vie?), Et donnez un certain nombre de vitesses, ainsi que des détails sur l'environnement (autre trucs qui courent sur la machine)? Avez-vous résolu la cause de la variabilité, ou essayez-vous d'aller directement forcer un thread qui est en temps réel/haute priorité?Les applications sur des OS multithread doivent généralement être sympas et doivent considérer le système d'exploitation comme l'arbitre de la programmation. – jefflunt

+1

@jefflunt yeah - ressemble à un mauvais sondage d'E/S - la chose même que les multitâches préemptifs modernes ont été conçus pour éviter. –

Répondre

0

Ma suggestion consiste à déplacer le thread d'exécution nécessitant la priorité la plus élevée dans un processus distinct. Apple le fait souvent pour les processus en temps réel tels que la conduite de l'appareil photo intégré. En fonction des versions du système d'exploitation que vous ciblez, vous pouvez utiliser les objets distribués (prédécesseur de XPC) ou XPC.

Vous pouvez également lancer votre propre mécanisme RPC et utiliser les techniques de fourche Unix standard pour créer un processus enfant distinct. Étant donné que votre application principale est le propriétaire du processus enfant, vous devez également pouvoir définir la priorité d'ordonnancement du processus en plus de la priorité de thread individuelle dans le processus.

Comme je modifier ce post, j'ai une vidéo WWDC en arrière-plan et a également commencé une tâche d'enregistrement vidéo QuickTime. Comme vous pouvez le voir, les aspects en temps réel de ces deux applications sont en cours d'exécution dans les processus XPC distincts:

ps -ax | grep Video 
1933 ??   0:00.08 /System/Library/Frameworks/VideoToolbox.framework/Versions/A/XPCServices/VTDecoderXPCService.xpc/Contents/MacOS/VTDecoderXPCService 
2332 ??   0:08.94 /System/Library/Frameworks/VideoToolbox.framework/Versions/A/XPCServices/VTDecoderXPCService.xpc/Contents/MacOS/VTDecoderXPCService 

XPC Services at developer.apple.com

Distributed Objects at developer.apple.com