@@ -65,11 +65,16 @@ Process* process_create(char* name, int ppid, Domain domain, u32 entry, u32 stac
6565 cpu_state_t * cpu = (cpu_state_t * )(proc -> ksp );
6666 memset (cpu , 0 , sizeof (cpu_state_t )); // Clear CPU state
6767
68- cpu -> eip = entry ;
69- cpu -> cs = 0x1B ; // user mode (ring 3)
70- cpu -> eflags = 0x202 ;
71- cpu -> esp = proc -> usp ;
72- cpu -> ss = 0x23 ; // user data (ring 3)
68+ cpu -> eip = entry ;
69+ cpu -> cs = 0x1B ; // user code (ring 3)
70+ cpu -> eflags = 0x202 ; // sti
71+ cpu -> esp = proc -> usp ;
72+ cpu -> ss = 0x23 ; // user data (ring 3)
73+ cpu -> ds = 0x23 ; // data
74+ cpu -> es = 0x23 ;
75+ cpu -> fs = 0x23 ;
76+ cpu -> gs = 0x23 ;
77+
7378
7479 // set the table slot.
7580 processes [pid ] = proc ;
@@ -89,37 +94,81 @@ int load_program(Process* proc, void* code, size_t size) {
8994}
9095
9196
92- void cswitch (cpu_state_t * new_state ) {
93- asm (
94- "movl %0, %%esp \n"
95- "popa \n"
96- "add $8, %%esp \n"
97- "iret \n"
98- :
99- : "r" (new_state )
100- : "memory"
101- );
97+
98+
99+ void cswitch (cpu_state_t * old_state , cpu_state_t * new_state ) {
100+ asm volatile (
101+ // save
102+ "pushf \n" // flags
103+ "pusha \n" // regs
104+ "movl %%esp, %0 \n" // sp
105+
106+ // switch
107+ "movl %1, %%esp \n" // new sp
108+ "popa \n" // regs
109+ "popf \n" // flags
110+ "ret \n" // return
111+
112+ : "=m" (* old_state ) // out: old state
113+ : "m" (* new_state ) // in: new state
114+ : "memory"
115+ );
102116}
103117
104118void switch_proc (Process * next_proc ) {
105119 if (!next_proc ) return ;
106-
107- cproc = next_proc ;
108- cswitch ((cpu_state_t * )(next_proc -> ksp ));
120+
121+ Process * old_proc = cproc ;
122+ cproc = next_proc ;
123+
124+ if (old_proc ) {
125+ cswitch ((cpu_state_t * )(old_proc -> ksp ), (cpu_state_t * )(next_proc -> ksp ));
126+ } else {
127+ // first proc ever.
128+ asm volatile (
129+ "movl %0, %%esp \n"
130+ "popa \n"
131+ "add $8, %%esp \n"
132+ "iret \n"
133+ :
134+ : "r" ((cpu_state_t * )(next_proc -> ksp ))
135+ : "memory"
136+ );
137+ }
109138}
110139
111140void scheduler (void ) {
112- int npid = (cproc -> pid + 1 ) % 256 ;
113-
114- for (int i = 0 ; i < 256 ; i ++ ) {
115- int pid = (npid + i ) % 256 ;
116- if (processes [pid ] && processes [pid ]-> proc_state == READY ) {
117- if (processes [pid ] != cproc ) {
118- switch_proc (processes [pid ]);
119- }
120- return ;
121- }
122- }
141+ Process * next_proc = NULL ;
123142
124- return ; // stay on current process
143+ int start_pid = cproc ? (cproc -> pid + 1 ) % 256 : 0 ; // no current process.
144+
145+ // next proc
146+ for (int i = 0 ; i < 256 ; i ++ ) {
147+ int pid = (start_pid + i ) % 256 ;
148+ if (processes [pid ] && processes [pid ]-> proc_state == READY ) {
149+ next_proc = processes [pid ];
150+ break ;
151+ }
152+ }
153+
154+ // if theres no ready proc.
155+ if (!next_proc ) {
156+ if (cproc && (cproc -> proc_state == RUNNING || cproc -> proc_state == READY )) {
157+ // c proc can just run untill we have another one.
158+ cproc -> proc_state = RUNNING ;
159+ return ;
160+ } else {
161+ // nothing to run TODO: The system should be idle.
162+ return ;
163+ }
164+ }
165+
166+
167+ if (cproc && cproc -> proc_state == RUNNING ) {
168+ cproc -> proc_state = READY ;
169+ }
170+
171+ // switch
172+ next_proc -> proc_state = RUNNING ;
173+ switch_proc (next_proc );
125174}
0 commit comments