10
votes

Un multitâche préventif est-il possible sur les interrupteurs DCPU-16?

Je regarde dans diverses conceptions de système d'exploitation dans l'espoir d'écrire un système d'exploitation multitâche simple pour le DCPU-16. Cependant, tout ce que j'ai lu sur la mise en œuvre du multitâche préventif est centré sur les interruptions. On dirait que dans l'ère du matériel et des logiciels de 16 bits, le multitâche coopératif était plus courant, mais cela nécessite que chaque programme soit écrit avec multitâche à l'esprit.

Y a-t-il un moyen de mettre en œuvre le multitâche préventif sur une architecture interrupte? Tout ce que je peux penser, c'est un interprète qui changerait de manière dynamique des tâches, mais cela aurait une énorme performance touchée (éventuellement sur l'ordre de 10-20x + si elle devait analyser chaque opération et ne laissa rien de courir de manière nativement, je suis imaginer).


3 commentaires

Notez que la DCPU-16 interrompt maintenant.


Est-ce que ça? À compter du 4 mai 2014, la version de la documentation disponible sur le site Web ( 0x10c.com/doc/dcpu -16.txt ) est toujours 1.1 et n'a aucune interruption. Y a-t-il une documentation sur les nouvelles fonctionnalités?


Je suppose que vous ne reditez pas et n'utilisez pas le forum. Vérifiez Ce mauvais garçon (spécifique 1.7) out! Nous discutons à ce sujet sur freenode IRC # 0x10c-dev si vous voulez tomber.


4 Réponses :


4
votes

Multiasking préemptif est normalement mis en œuvre en ayant une interruption de routines post-statut / événements intéressants à un planificateur, qui décide des tâches à suspendre et de nouvelles tâches à démarrer / à continuer en fonction de la priorité. Cependant, d'autres événements intéressants peuvent survenir lorsqu'une tâche en cours d'exécution fait appel à une routine OS, qui peut avoir le même effet.

Mais tout ce qui compte, c'est que certains événements sont notés quelque part et que le planificateur décide de courir. Vous pouvez donc faire de toutes ces modifications / planches d'événement ne se produisent que sur les appels OS.

Vous pouvez ajouter des appels flagrants au planificateur à des points "pratiques" dans divers codes d'application de tâche pour rendre votre commutateur système plus souvent. Qu'il s'agisse simplement de commutation ou utilise des informations de base telles que le temps écoulé depuis que le dernier appel est un détail du planificateur.

Votre système ne sera pas aussi réactif que celui dilué par des interruptions, mais vous avez déjà donné cela en choisissant le CPU que vous avez fait.


4 commentaires

Cela présente donc l'inconvénient de la coopérative multitasking en ce sens qu'il n'ya pas de limite supérieure stricte sur la durée de laquelle la CPU peut fonctionner sans frapper le planificateur (par exemple, si un processus passe dans une boucle qui n'implique aucun appels OS), mais depuis que cela détourne Le système d'exploitation appelle à des fins de planification, il fonctionnera sur tout programme qui fait des appels de système d'exploitation?


@Andrewg. exactement. Et c'est la manière dont le Mac OS classique a ajouté multitâche, initialement comme une extension dans le système 5. Les appels appropriés dans le système d'exploitation ont été traités comme des opportunités multitâches coopératives. Comme vous le dites, il n'y a pas de limite supérieure stricte - par ex. Un processus qui, vraisemblablement par une erreur de conception, entre une boucle infinie sans appels de système d'exploitation accrochera tout le système.


@Tommy C'est ce qu'est une minuterie de surveillance matérielle qui affirme la réinitialisation de la CPU et la routine de réinitialisation intégrée qui vous déroute la pile du point d'entrée de programme est destinée. Voir mon explication pour pourquoi ce n'est pas incroyablement fou.


@Andrewg.: C'est dans l'essence multitâche coopérative, surtout si vous utilisez les appels flagrants.



2
votes

Je pense que votre évaluation est correcte. Le multitâche préventif se produit si le planificateur peut interrompre (dans le sens non infligé du dictionnaire) une tâche exécutée et passez à une autre de manière autonome. Donc, il doit y avoir une sorte d'acteur qui incite le planificateur à l'action. S'il n'y a pas de dispositifs d'interruption (dans le sens technique infléchi), il y a peu de choses que vous pouvez faire en général.

Cependant, plutôt que de passer à un interprète complet, une idée qui se produit est simplement de reprogrammer dynamiquement le code du programme fourni. Donc, avant d'entrer dans un processus, le planificateur connaît le processus complet, y compris quelle valeur de compteur de programme qu'il va entrer. Il peut ensuite analyser à partir de là, remplacer, dire, soit le vingtième code d'instruction, soit le code d'instruction de saut suivant qui n'est pas immédiatement au comptoir de programme avec un saut dans le planificateur. Lorsque le processus revient, le planificateur met l'instruction originale dans. Si c'est un saut (conditionnel ou autre), il effets également le saut de manière appropriée.

Bien sûr, ce système ne fonctionne que si le code de programme ne se modifie pas de manière dynamique. Et dans ce cas, vous pouvez le prétraiter afin que vous sachiez à l'avance lorsque des sauts sont sans recherche linéaire. Vous pouvez techniquement permettre un code auto-modificateur bien écrit s'il était disposé à nommer toutes les adresses pouvant être modifiées, ce qui vous permet de les éviter de ces modifications dynamiques de votre planificateur.

Vous finiriez par suivre un type d'interprète, mais seulement pour les sauts.


0 commentaires

4
votes

En fait, oui. La méthode la plus efficace consiste à simplement corriger les temps d'exécution dans le chargeur. Les trucs de noyau / daemon peuvent avoir des correctifs personnalisés pour une meilleure réactivité. Mieux encore, si vous avez accès à toute la source, vous pouvez corriger dans le compilateur.

Le patch peut consister en un planificateur distribué de Tremples. Chaque programme peut être corrigé pour avoir une minuterie de très faible latence; Sur charge, il définira la minuterie et sur chaque retour du planificateur, il le réinitialisera. Une méthode simpliste permettrait à code de faire simplement un xxx

qui ne cède pas trop de performances. Le problème principal consiste à trouver de bons points pour les apparaître. Entre chaque appel de fonction est un démarrage, et la détection de boucles et l'insérer est primitive mais efficace si vous avez vraiment besoin de préempter de manière réactive.

Ce n'est pas parfait, Mais ça va marcher.

Le problème principal consiste à s'assurer que le rendement de la minuterie est une faible latence; De cette façon, c'est juste une comparaison et une branche. En outre, des exceptions de traitement - des erreurs dans le code qui cause, disent, des boucles infinies - d'une manière ou d'une autre. Vous pouvez utiliser techniquement une minuterie de chien de surveillance matérielle assez simple et affirmer une réinitialisation sur la CPU sans éliminer aucune bélier; Une routine IN-RAM serait l'endroit où réinitialiser les points vectoriels, qui inspecteraient et déroulerait la pile à l'appel du programme (écrasant ainsi le programme mais préservant tout le reste). C'est un peu comme une force brute si elle-tout-échoue - le programme-the-the-the-the-the-the. Ou vous pouvez potentiellement la modifier à la multi-tâche de cette manière, réinitialiser comme une interruption, mais c'est beaucoup plus difficile.

SO ... Oui. C'est possible mais compliqué; À l'aide de techniques de compilateurs JIT et de traducteurs dynamiques (les émulateurs les utilisent).

C'est un peu d'explication embrouillée, je sais, mais je suis très fatigué. Si ce n'est pas assez clair, je peux revenir et le refroidir demain.

D'ailleurs, affirmez la réinitialisation sur un programme central de la CPU qui sonne folle, mais c'est une technique de l'heure et éprouvée. Les premières versions de Windows ont même fait exécuter le mode de compatibilité, je pense que 386, correctement, car il n'y avait aucun moyen de revenir à 32 bits du mode 16 bits. D'autres processeurs et systèmes d'OSES l'ont fait aussi.

Edit: Donc, j'ai fait des recherches sur ce que le DCPU est, haha. Ce n'est pas un vrai processeur. Je ne sais pas si vous pouvez affirmer Réinitialiser dans l'émulateur de Notch, je lui demanderais. Technique pratique, c'est-à-dire.


1 commentaires

Serait-il précis de résumer votre suggestion comme multitâche coopérative automatique?



0
votes

Un autre moyen est de garder à de petites tâches basées sur une file d'attente d'événement (comme des applications d'interface graphique actuelle)

Ceci est également coopératif mais a pour effet de ne pas avoir besoin d'appels d'exploitation que vous venez de revenir de la tâche, puis de passer à la prochaine tâche

Si vous devez alors poursuivre une tâche, vous devez transmettre la prochaine "fonction" et un pointeur sur les données dont vous avez besoin pour la file d'attente de tâches


2 commentaires

Cela n'exige-t-il pas que tous les programmes sur le système ne cassent pas leur traitement en petites tâches se terminant par un appel d'exploitation (essentiellement coopératif multitâche)? Ou souhaitez-vous inspecter de manière dynamique et réécrire des tâches?


@Andrewg. n'ai-je pas dit cela dans ma deuxième phrase? Mais oui, oui, ce serait, bien que plus un retour à la file d'attente lorsque vous avez terminé