My Project
Chargement...
Recherche...
Aucune correspondance
tache.c
Aller à la documentation de ce fichier.
1
7#include <manux/tache.h>
8#include <manux/temps.h>
9#include <manux/scheduler.h> /* tacheEnCours */
10#include <manux/memoire.h>
11#include <manux/segment.h>
12#ifdef MANUX_TACHE_CONSOLE
13# include <manux/console.h>
14#endif
15#include <manux/atomique.h>
16#include <manux/segment.h> /* setDescripteurSegment */
17#include <manux/pagination.h> /* repertoirePaginationSysteme */
18
19#include <manux/fichier.h> /* pour créer stdout WARNING, à mettre ailleurs */
20#include <manux/errno.h> // Les codes d'erreur
21#include <manux/string.h> // memcpy
22#include <manux/printk.h>
23#include <manux/debug.h>
24
25#define printkc printk
26
27#if defined(MANUX_TACHES) && defined(MANUX_EXCLUSION_MUTUELLE) && !defined(MANUX_REENTRANT)
29#endif
35
36unsigned int nbActivations = 0; // Nombre d'appels à activerTache
37
39/*
40 * Activation d'une tâche
41 */
42{
43 volatile uint32_t selecteur[2] = {0 , tache->indiceTSSDescriptor};
44
45 __asm__ __volatile__ ("ljmp * %0"::"m" (*selecteur));
46}
47
54static
55void tacheExecuter(void)
56{
57#if defined(MANUX_TACHES) && defined(MANUX_EXCLUSION_MUTUELLE) && !defined(MANUX_REENTRANT)
58 // On commmence en mode noyau, ...
59 exclusionMutuelleEntrer(&verrouGeneralDuNoyau);
60 assert(tacheDansLeNoyau == 0);
61 tacheDansLeNoyau = tacheEnCours->numero;
62#endif
63 Tache * moi = tacheEnCours;
64
65 printk_debug(DBG_KERNEL_TACHE, "Demarage de la tache %d (exec 0x%x) ...\n",
66 moi->numero,
68
69#if defined(MANUX_TACHES) && defined(MANUX_EXCLUSION_MUTUELLE) && !defined(MANUX_REENTRANT)
70 // On commmence en mode noyau, ...
71 tacheDansLeNoyau = 0;
72 exclusionMutuelleSortir(&verrouGeneralDuNoyau);
73#endif
74
75 moi->fonctionPrincipale();
76
77#if defined(MANUX_TACHES) && defined(MANUX_EXCLUSION_MUTUELLE) && !defined(MANUX_REENTRANT)
78 // On commmence en mode noyau, ...
79 exclusionMutuelleEntrer(&verrouGeneralDuNoyau);
80 assert(tacheDansLeNoyau == 0);
81 tacheDansLeNoyau = tacheEnCours->numero;
82#endif
83
84 printk_debug(DBG_KERNEL_TACHE, "Fin de la tache %d, ...\n", moi->numero);
85
86 // On bascule dans les taches terminées
87 moi->etat = Tache_Terminee;
89 moi,
90 (CelluleTache*)moi+sizeof(Tache));
91
92 // On peut maintenant détruire les structures qui lui étaient
93 // allouées
94
95 // WARNING : à faire !
96
97#if defined(MANUX_TACHES) && defined(MANUX_EXCLUSION_MUTUELLE) && !defined(MANUX_REENTRANT)
98 // On commmence en mode noyau, ...
99 tacheDansLeNoyau = 0;
100 exclusionMutuelleSortir(&verrouGeneralDuNoyau);
101#endif
102
103 // On rend la main
104 ordonnanceur();
105}
106
113Tache * tacheCreer(CorpsTache corpsTache)
114{
115 void * unePage;
116 Tache * tache;
117 void * pile; // Elle a sa propre pile
118
120
121 /* On stoque les infos en zone système */
122 unePage = allouerPage();
123 if (unePage == NULL) {
124 printk_debug(DBG_KERNEL_TACHE, "plus de memoire disponible\n");
125 return NULL;
126 }
127
128 tache = (Tache *) unePage;
129
130 pile = (void*) allouerPage();
131
132 if (pile == NULL) {
133 printk_debug(DBG_KERNEL_TACHE, "plus de memoire disponible\n");
134 // WARNING : libérer la page de la tache
135 return NULL;
136 }
137
138 /* Initialisation du descripteur de tache */
139 tache->tss.Reserve1 = (uint16_t) 0;
140 tache->tss.Reserve2 = (uint16_t) 0;
141 tache->tss.Reserve3 = (uint16_t) 0;
142 tache->tss.Reserve4 = (uint16_t) 0;
143 tache->tss.Reserve5 = (uint16_t) 0;
144 tache->tss.Reserve6 = (uint16_t) 0;
145 tache->tss.Reserve7 = (uint16_t) 0;
146 tache->tss.Reserve8 = (uint16_t) 0;
147 tache->tss.Reserve9 = (uint16_t) 0;
148 tache->tss.Reserve10 = (uint16_t) 0;
149 tache->tss.Reserve11 = (uint16_t) 0;
150 tache->tss.Reserve12 = (uint16_t) 0;
151 tache->tss.CS = 0x08; /* WARNING, hardcodé pas beau ! */
152 tache->tss.DS = 0x10; /* WARNING, hardcodé pas beau ! */
153 tache->tss.ES = 0x10; /* WARNING, hardcodé pas beau ! */
154 tache->tss.FS = 0x10; /* WARNING, hardcodé pas beau ! */
155 tache->tss.GS = 0x10; /* WARNING, hardcodé pas beau ! */
156 tache->tss.SS = 0x18; /* WARNING, hardcodé pas beau ! */
157 tache->tss.ESP = (uint32_t)pile + 4092; /* WARNING !! */
158 if (corpsTache) {
159 tache->fonctionPrincipale = corpsTache;
160 tache->tss.EIP = (uint32_t)tacheExecuter;
161 } else {
162 tache->tss.EIP = NULL;
163 }
164 tache->tss.EFLAGS = (uint32_t)0x200;
165
166 // Ajout de la tâche dans la GDT
168 &tache->tss,
169 0x67, FALSE);
170
171 // On recharge la GDT (nécessaire suite changement de taille ?)
173
174 // On lui affecte son numero
175 tache->numero = numeroProchaineTache++;
176
177#ifdef MANUX_FICHIER
178 // Pas de fichier ouvert pour le moment
179 for (int i = 0; i < MANUX_NB_MAX_FICHIERS; i++){
180 tache->fichiers[i] = NULL;
181 }
182 tache->nbFichiersOuverts = 0;
183
184# ifdef MANUX_HERITER_FICHIERS
185 if (tache->numero > 1) {
186 // On hérite les fichiers de la tâche mère
187 printk_debug(DBG_KERNEL_SYSFI, "Tache %d herite %d fichiers de tache %d\n",
188 tache->numero, tacheEnCours->nbFichiersOuverts, tacheEnCours->numero);
189 for (int i = 0; i < MANUX_NB_MAX_FICHIERS; i++){
190 //tache->fichiers[i] = tacheEnCours->fichiers[i];
191 if (tacheEnCours->fichiers[i] != NULL) {
192 tache->fichiers[i] = fichierDupliquer(tacheEnCours->fichiers[i]);
193 }
194 }
195 tache->nbFichiersOuverts = tacheEnCours->nbFichiersOuverts;
196 printk_debug(DBG_KERNEL_SYSFI, "Tache %d herite %d fichiers de tache %d OK\n",
197 tache->numero, tacheEnCours->nbFichiersOuverts, tacheEnCours->numero);
198 }
199# endif
200#endif
201
202#ifdef MANUX_TACHE_CONSOLE
203 // Pas de console spécifique pour le moment
204 tache->console = consoleNoyau();
205#endif
206
207#if defined(MANUX_APPEL_SYSTEME) && defined(MANUX_AS_AUDIT)
208 for (int i = 0; i < NB_MAX_APPELS_SYSTEME; i++) {
209 nbAppelsSystemeIn[i] = 0;
210 nbAppelsSystemeOut[i] = 0;
211 }
212#endif
213 // A priori elle est préemptible
214 tache->nonPreemptible = 0;
215
216 // Elle n'a pas encore été activée
217 tache->nbActivations = 0;
218 tache->tempsExecution = (Temps)0;
219
220 // Zone mémoire utilisable
222
223#ifdef MANUX_PAGINATION
224 /* On lui affecte son PDBR */
226
227 /* On ajoute la page décrivant la tâche en début de mémoire spécifique */
228 ajouterPage((PageDirectory *)&tache->tss.CR3,
229 tache,
230 tache->tailleMemoire);
232#endif
233 // printk("hhhhh\n");
234
235 /* On lui affecte sa LDT */
236 // tache->ldt = (DescriptorTable *)(unePage + sizeof(Tache));
237 /* tache->ldt = (DescriptorTable *)allouerPage();
238 tache->tss.LDT = (uint16_t)setDescripteurSegment(gdtSysteme,
239 (uint32_t)&(tache->ldt->taille),
240 LDT_NB_BYTES,
241 0x82, 0xC0);
242 */
243 tache->ldt = NULL;
244 tache->tss.LDT = NULL;
245
246 /* On recharge la GDT */
247 // chargerGDT(gdtSysteme);
248
249 /* Copie de la LDT, maintenant qu'elle est complète */
250 //memcpy(tache->ldt, gdtSysteme, tailleGDTSysteme);
251
252
253 /* Elle est prète à être exécutée */
254 tache->etat = Tache_Prete;
255
256 /* On affiche quelques infos */
257 printk_debug(DBG_KERNEL_TACHE, "Tache[%d] = 0x%x\n", tache->numero, tache);
258#ifdef MANUX_TACHE_CONSOLE
259 printk_debug(DBG_KERNEL_TACHE, "cons = 0x%x, tss=0x%x, ldt=0x%x\n", tache->console, tache->tss, tache->ldt);
260#else
261 printk_debug(DBG_KERNEL_TACHE, "tss=0x%x, ldt=0x%x\n", tache->tss, tache->ldt);
262#endif
263
265 tache,
266 (CelluleTache*)tache+sizeof(Tache)+sizeof(CelluleTache));
267
268 printk_debug(DBG_KERNEL_TACHE, "Tache %d creee, main = 0x%d ...\n",
269 tache->numero,
270 tache->fonctionPrincipale);
271
273 return tache;
274}
275
276#ifdef MANUX_TACHE_CONSOLE
280void tacheSetConsole(Tache * tache, struct _Console * cons)
281{
282 tache->console = cons;
283
284#ifdef MANUX_FICHIER // et sinon !?
285 Fichier * f;
286 INoeud * i;
287
288 i = consoleCreerINoeud(cons);
289 f = fichierCreer(i, O_WRONLY, 0);
290
291 tache->fichiers[0] = f;
292#endif // MANUX_FICHIER
293}
294
295#ifdef MANUX_FICHIER
301inline
302static
303int tacheNumFichierLibre(Tache * tache)
304{
305 int result = 0;
306
307 while ((result < MANUX_NB_MAX_FICHIERS) && (tache->fichiers[result])) {
308 result++;
309 }
310 return result;
311}
312
320int tacheAjouterFichiers(Tache * tache, int n, Fichier * fichiers[], int * fds)
321{
322 int nbLibres;
323 int result = 0;
324 int fd;
325
326 // WARNING à protéger par un mutex lock
327
328 // A-t-on la place ?
329 nbLibres = MANUX_NB_MAX_FICHIERS - tache->nbFichiersOuverts;
330
331 // Si oui on affecte
332 if (nbLibres >= n) {
333 for (int i = 0; i < n; i++) {
334 fd = tacheNumFichierLibre(tache);
335 assert(fd >= 0);
337 fds[i] = fd;
338 tache->fichiers[fd] = fichiers[i];
339 tache->nbFichiersOuverts ++;
340 result++;
341 }
342 }
343
344 return result;
345}
346#endif // MANUX_FICHIER
347
348#endif // MANUX_TACHE_CONSOLE
349
354{
355 printkc(" [ %d] %s %4d %2d:%2d 0x%x 0x%x 0x%x\n",
356 tache->numero,
357 (tache->etat == Tache_En_Cours)?"c":(((tache->etat == Tache_Prete)?"p":((tache->etat == Tache_Terminee)?"t":"b"))),
358 tache->nbActivations,
361 tache,
362#ifdef MANUX_TACHE_CONSOLE
363 tache->console,
364#else
365 0x00, // WARNING : bof
366#endif
367 tache->ldt);
368}
369
374{
375 CelluleTache * celluleTache;
376
377 printkc("\n ------------------------<SCHEDULER t = %d:%d (%d)>----------------------------\n",
381
382 printkc("\n Num prochaine tache : %d\n", numeroProchaineTache);
383 printkc(" [num] et nbAc tpsEx tache console ldt\n");
384 for (celluleTache = listeToutesLesTaches.tete;
385 celluleTache != NULL;
386 celluleTache = celluleTache->suivant){
387 afficherEtatUneTache(celluleTache->tache);
388 }
389 printkc("\n------------------------------------------------------------------------------\n");
390}
391
Définition des opérations de synchronisation de ManuX.
Définition des exlusions mutuelles.
void exclusionMutuelleEntrer(ExclusionMutuelle *em)
Entrée en exclusion mutuelle.
void exclusionMutuelleSortir(ExclusionMutuelle *em)
#define O_WRONLY
Definition fichier.h:28
#define MANUX_TAILLE_PAGE
Temps nbTopHorloge
Definition horloge.c:22
#define NB_MAX_APPELS_SYSTEME
Définition des fonctions de base d'accés à la console.
Console * consoleNoyau(void)
Obtention d'un pointeur sur la console par défaut.
Definition console.c:808
int nombrePagesSysteme
Definition memoire.c:48
void * allouerPage(void)
Definition memoire.c:234
Définition des fonctions de base d'entrée-sortie du noyau.
#define NULL
Definition stddef.h:10
unsigned long uint32_t
Definition types.h:20
uint16_t TacheID
Definition types.h:61
unsigned short uint16_t
Definition types.h:16
#define FALSE
Definition types.h:40
int32_t Temps
Definition types.h:71
int fd[2]
void insererCelluleTache(ListeTache *listeTaches, struct _Tache *tache, CelluleTache *celluleTache)
Definition listetaches.c:17
#define DBG_KERNEL_TACHE
Definition debug.h:26
#define assert(cond)
Definition debug.h:126
#define DBG_KERNEL_SYSFI
Definition debug.h:24
#define printk_debug(lvl, fmt, args...)
Definition debug.h:86
int ajouterPage(PageDirectory *repertoirePagination, Page adressePhysique, void *adresseVirtuelle)
Definition pagination.c:133
void creerTablePagination(PageDirectory *repertoirePagination)
Definition pagination.c:74
PDE * PageDirectory
Definition pagination.h:28
ListeTache listeTachesTerminees
: La liste des tâches achevées
Definition scheduler.c:86
ListeTache listeToutesLesTaches
: La liste de toutes les tâches existant sur le système.
Definition scheduler.c:81
Tache * tacheEnCours
: L'identification de la tâche en cours
Definition scheduler.c:91
void ordonnanceur(void)
Basculer vers la prochaine tache à exécuter.
Definition scheduler.c:98
int ajouterDescTSS(DescriptorTable *dt, void *adresse, uint32_t limite, booleen busyTask)
Definition segment.c:211
void chargerGDT(DescriptorTable *gdt)
Definition segment.c:65
DescriptorTable * gdtSysteme
Definition segment.c:12
struct _Tache * tache
Definition listetaches.h:14
struct _CelluleTache * suivant
Definition listetaches.h:15
Structure d'une console.
Definition console.h:37
: Qu'est-ce qu'un fichier ouvert du point de vue du noyau ?
Definition fichier.h:46
: Un INoeud représente un fichier, d'un point de vue statique Il s'agit donc de la description d'un f...
Definition inoeud.h:27
uint16_t FS
Definition tache.h:70
uint16_t Reserve11
Definition tache.h:75
uint16_t Reserve4
Definition tache.h:55
uint16_t Reserve1
Definition tache.h:46
uint16_t Reserve6
Definition tache.h:65
uint16_t Reserve10
Definition tache.h:73
uint16_t Reserve12
Definition tache.h:76
uint16_t Reserve3
Definition tache.h:52
uint16_t Reserve7
Definition tache.h:67
uint16_t GS
Definition tache.h:72
uint32_t CR3
Definition tache.h:56
uint32_t ESP
Definition tache.h:60
uint16_t SS
Definition tache.h:66
uint16_t Reserve2
Definition tache.h:49
uint32_t EIP
Definition tache.h:57
uint16_t DS
Definition tache.h:68
uint16_t Reserve5
Definition tache.h:63
uint32_t EFLAGS
Definition tache.h:58
uint16_t CS
Definition tache.h:64
uint16_t Reserve9
Definition tache.h:71
uint16_t LDT
Definition tache.h:74
uint16_t Reserve8
Definition tache.h:69
uint16_t ES
Definition tache.h:62
CelluleTache * tete
Definition listetaches.h:19
: Définition du type décrivant une tache.
Definition tache.h:83
EtatTache etat
Definition tache.h:89
DescriptorTable * ldt
Definition tache.h:85
CorpsTache * fonctionPrincipale
Definition tache.h:92
uint32_t nbActivations
Definition tache.h:104
Temps tempsExecution
Definition tache.h:105
uint16_t indiceTSSDescriptor
Definition tache.h:86
void * tailleMemoire
Definition tache.h:90
TacheID numero
Definition tache.h:88
uint8_t nonPreemptible
Definition tache.h:94
IntelTSS tss
Definition tache.h:84
#define MANUX_NB_MAX_FICHIERS
void basculerVersTache(Tache *tache)
Definition tache.c:38
TacheID numeroProchaineTache
:Le numero de la prochaine tache (WARNING : et si on cycle ?)
Definition tache.c:34
#define printkc
Definition tache.c:25
void afficherEtatTaches(void)
Affichage des tâches.
Definition tache.c:373
unsigned int nbActivations
Definition tache.c:36
Tache * tacheCreer(CorpsTache corpsTache)
: Création d'une tâche.
Definition tache.c:113
void afficherEtatUneTache(Tache *tache)
Affichage de l'état d'une tâche à des fins de debug.
Definition tache.c:353
@ Tache_Terminee
Definition tache.h:32
@ Tache_En_Cours
Definition tache.h:29
@ Tache_Prete
Definition tache.h:30
#define totalMinutesDansTemps(t)
Definition temps.h:17
#define secondesDansTemps(t)
Definition temps.h:19