Skip to content
This repository was archived by the owner on Jul 21, 2025. It is now read-only.

Commit fc22e40

Browse files
authored
Fix
1 parent 671a961 commit fc22e40

File tree

1 file changed

+79
-30
lines changed

1 file changed

+79
-30
lines changed

kernel/core/process.c

Lines changed: 79 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

104118
void 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

111140
void 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

Comments
 (0)