Skip to content

Commit 6ada8e6

Browse files
author
Hugo
committed
je suis dans le flou pour sys_exit, je n'ai pas compris où revenir à la fin du sys_exit, pour l'instant ça fonctionne mais on choisit le processus suivant. Il faudra peut-etre changer ça du coup. Mais si c'est bon alors j'en suis à retourner le status au kernel.
1 parent e0853a6 commit 6ada8e6

File tree

4 files changed

+87
-8
lines changed

4 files changed

+87
-8
lines changed

Aurel-Hugo/kmain.c

+23-2
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,25 @@ void user_process()
1313
}
1414
}
1515

16+
void user_process_stopping()
17+
{
18+
int v=0;
19+
while(v<1)
20+
{
21+
v++;
22+
sys_yield();
23+
}
24+
sys_exit(0);
25+
}
26+
1627
void kmain( void )
1728
{
1829
sched_init();
1930

2031
int i;
2132
for(i=0;i<NB_PROCESS;i++)
2233
{
23-
create_process((func_t*) &user_process);
34+
create_process((func_t*) &user_process_stopping);
2435
}
2536

2637
__asm("cps 0x10"); // switch CPU to USER mode
@@ -30,4 +41,14 @@ void kmain( void )
3041
{
3142
sys_yield();
3243
}
33-
}
44+
}
45+
46+
/** Question 6.5 **
47+
Parce qu'il est impossible pour le moment de savoir quand le processus a fini son travail.
48+
*/
49+
50+
/** Question 6.6 **
51+
On est obligé de faire un tour complet du round robin pour trouver le "previous" du pcb courant
52+
(celui à supprimer).
53+
Oui ça peut être génant si il y a trop de processus : perte de temps importante
54+
*/

Aurel-Hugo/src/sched.c

+52-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ struct pcb_s kmain_process;
66

77
extern unsigned int* sp_sauv;
88

9+
#define SIZE_OF_PROCESS_STACK_OCTETS 10000
10+
11+
/* SYS_ACTION */
12+
913
void
1014
sys_yieldto(struct pcb_s* dest)
1115
{
@@ -26,9 +30,20 @@ sys_yield(void)
2630
__asm("mov %0, sp" : "=r"(current_process->sp));
2731
__asm("swi #0");
2832
__asm("mov sp, %0" : : "r"(current_process->sp));
29-
__asm("mov lr, %0" : : "r"(current_process->lr_user)); // current_process est maintenant "dest"
33+
__asm("mov lr, %0" : : "r"(current_process->lr_user));
34+
}
35+
36+
void
37+
sys_exit(int status)
38+
{
39+
__asm("mov r0, #7");
40+
__asm("swi #0");
41+
__asm("mov sp, %0" : : "r"(current_process->sp));
42+
__asm("mov lr, %0" : : "r"(current_process->lr_user));
3043
}
3144

45+
/* DO_SYS_ACTION */
46+
3247
void
3348
do_sys_yieldto(void)
3449
{
@@ -59,7 +74,7 @@ do_sys_yield(void)
5974
int i;
6075
for(i=0 ; i<13 ; i++)
6176
{
62-
// on enregistre les registres courant
77+
// on enregistre les registres courants
6378
old_process->registres[i] = sp_sauv[i];
6479
// puis on charge les registres du nouveau processus
6580
sp_sauv[i] = current_process->registres[i];
@@ -70,27 +85,61 @@ do_sys_yield(void)
7085
__asm("msr SPSR, %0" : : "r"(current_process->cpsr));
7186
}
7287

88+
89+
void
90+
do_sys_exit()
91+
{
92+
current_process->etat = TERMINATED;
93+
current_process->previous->next = current_process->next;
94+
current_process->next->previous = current_process->previous;
95+
struct pcb_s* to_delete = current_process;
96+
elect();
97+
kFree((void *)to_delete->sp, SIZE_OF_PROCESS_STACK_OCTETS);
98+
kFree((void *)to_delete, sizeof(struct pcb_s));
99+
// ici tout est propre mais il faut encore que l'on change de contexte
100+
// on passe donc au processus suivant
101+
int i;
102+
for(i=0 ; i<13 ; i++)
103+
{
104+
// puis on charge les registres du nouveau processus
105+
sp_sauv[i] = current_process->registres[i];
106+
}
107+
// puis on restaure le CPSR du nouveau processus
108+
__asm("msr SPSR, %0" : : "r"(current_process->cpsr));
109+
}
110+
111+
/* Autre */
112+
73113
void
74114
sched_init(void)
75115
{
76116
kheap_init();
77117
current_process = &kmain_process;
78118
current_process->next = current_process;
119+
current_process->previous = current_process;
120+
current_process->etat = RUNNING;
79121
}
80122

81123
void
82124
create_process(func_t* entry)
83125
{
84126
struct pcb_s* pcb_res = (struct pcb_s*) kAlloc(sizeof(struct pcb_s));
85127
pcb_res->lr_user = entry;
86-
pcb_res->sp = (uint32_t*) (kAlloc( 10000 ) + sizeof(uint8_t)*10000);
128+
pcb_res->sp = (uint32_t*) (kAlloc(SIZE_OF_PROCESS_STACK_OCTETS) + sizeof(uint8_t)*SIZE_OF_PROCESS_STACK_OCTETS);
87129
struct pcb_s* pcb_res_next = current_process->next;
130+
88131
current_process->next = pcb_res;
132+
pcb_res->previous = current_process;
133+
89134
pcb_res->next = pcb_res_next;
135+
pcb_res_next->previous = pcb_res;
90136
}
91137

92138
void
93139
elect()
94140
{
141+
// si le processus courant tournait, alors on l'arrete
142+
current_process->etat = (current_process->etat==RUNNING) ? READY : current_process->etat;
95143
current_process = current_process->next;
144+
current_process->etat = RUNNING;
96145
}

Aurel-Hugo/src/sched.h

+11-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <stdint.h>
55

66
typedef int (func_t) (void) ;
7+
typedef enum {READY, RUNNING, TERMINATED} status;
78
struct pcb_s
89
{
910
uint32_t registres[13];
@@ -12,13 +13,20 @@ struct pcb_s
1213
uint32_t* sp;
1314
uint32_t* cpsr;
1415
struct pcb_s* next;
16+
struct pcb_s* previous;
17+
status etat;
1518
};
1619

17-
void do_sys_yieldto(void);
18-
void do_sys_yield(void);
19-
20+
// lance dest en tant que prochain processus à executer
2021
void sys_yieldto(struct pcb_s* dest);
22+
// laisse l'ordonnanceur choisir le prochain processus à executer
2123
void sys_yield();
24+
// Termine le processus courant avec le code de retour status.
25+
void sys_exit(int status);
26+
27+
void do_sys_yieldto(void);
28+
void do_sys_yield(void);
29+
void do_sys_exit();
2230

2331
void sched_init(void);
2432
void create_process(func_t* entry);

Aurel-Hugo/src/syscall.c

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ swi_handler(void)
9090
case 4: do_sys_gettime(); break;
9191
case 5: do_sys_yieldto(); break;
9292
case 6: do_sys_yield(); break;
93+
case 7: do_sys_exit(); break;
9394
default: PANIC();
9495
}
9596
__asm("ldmfd sp!, {r0-r12, pc}^");

0 commit comments

Comments
 (0)