Skip to content

Commit 1307b26

Browse files
committed
Cheap waitpid()
1 parent 26dd761 commit 1307b26

File tree

13 files changed

+111
-38
lines changed

13 files changed

+111
-38
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ binaries: $(bt_stage1) $(bt_stage2) $(kernel_core) $(rm_static)
102102
SECTOR_COUNT_BT_STAGE1 = 1
103103
SECTOR_COUNT_SHARED_LIBRARY = 1
104104
SECTOR_COUNT_BT_STAGE2 = 12
105-
SECTOR_COUNT_KERNEL = 47
105+
SECTOR_COUNT_KERNEL = 48
106106

107107
SECTOR_START_BT_STAGE1 = 0
108108
SECTOR_START_SHARED_LIBRARY = $(shell expr $(SECTOR_START_BT_STAGE1) + $(SECTOR_COUNT_BT_STAGE1) )

include/fuzzy/kernel/process/process.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ enum process_state{
1313
STATE_READY,
1414
STATE_RUNNING,
1515
STATE_EXIT, // should be unallocated in next scheduling cycle
16+
STATE_BLOCK, // process is waiting on IO, process_wait, etc.
17+
};
18+
19+
enum process_state_block {
20+
STATE_BLOCK_PROCESS_WAIT, // waiting for another process termination.
1621
};
1722

1823
struct Process {
@@ -22,6 +27,16 @@ struct Process {
2227
unsigned int *e;
2328

2429
int status_code;
30+
31+
unsigned int ppid; // parent pid, 0 to root under kernel_core
32+
33+
enum process_state_block block_type; // valid, if state == BLOCK
34+
union {
35+
struct {
36+
unsigned int blocked_on_pid;
37+
unsigned int blocking_pid; // TODO: make list
38+
} process_wait;
39+
} block_data; // valid if state == BLOCK
2540
};
2641

2742
void process_scheduler_init();
@@ -35,11 +50,12 @@ int get_gdt_number_from_entry_id(int id);
3550
// allocation
3651
int get_idt_cs_entry(int process_id);
3752
int get_idt_ds_entry(int process_id);
38-
int get_idt_reverse_pid_lookup(int cs);
53+
int get_idt_reverse_pid_lookup_cs(int cs);
54+
int get_idt_reverse_pid_lookup_ds(int ds);
3955

4056
// process create or kill
41-
int process_create(int argc, char *argv[]);
42-
void process_kill(int user_ds, int status);
57+
int process_create(unsigned int ppid, int argc, char *argv[]);
58+
void process_kill(unsigned int pid, int status);
4359

4460
// scheduler
4561

@@ -50,3 +66,6 @@ void process_scheduler(int *_e_ip, int *_e_cs, int *_e_sp, int *_e_ss);
5066
// user space <-> kernel space data transfer helper
5167
extern void syscall_strncpy_user_to_kernel(int user_ds, char *src_es_address, char *dest_ds_address, size_t size);
5268
extern void syscall_strncpy_kernel_to_user(int user_ds, char *dest_address, char *src_address, size_t size);
69+
70+
// state logic
71+
int process_waitpid(unsigned int pid, unsigned int blocked_on_pid);

src/drivers/keyboard/keyboard.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ char keyboard_get_key_pressed_blocking() {
166166
return c;
167167
}
168168

169+
char keyboard_get_key_pressed_poll() {
170+
for (int i = 0; !keyboard_scanner_ascii_is_available() && i < 100; i++) {
171+
keyboard_scanner_step();
172+
}
173+
char c = keyboard_scanner_ascii_get();
174+
return c;
175+
}
176+
169177
void keyboard_init() {
170178
unsigned char original_colors = get_color_fgbg();
171179
sleep_mini(3000000);

src/drivers/keyboard/keyboard.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
void keyboard_init();
44

5-
char keyboard_get_key_pressed_blocking();
5+
char keyboard_get_key_pressed_blocking();
6+
char keyboard_get_key_pressed_poll();

src/drivers/keyboard/scancode_handler.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,10 @@ int keyboard_scanner_ascii_is_available() {
209209
}
210210

211211
char keyboard_scanner_ascii_get() {
212+
char c = last_ascii;
212213
last_ascii_available = 0;
213-
return last_ascii;
214+
last_ascii = 0;
215+
return c;
214216
}
215217

216218
void keyboard_scanner_handler_init() {

src/kernel/process/allocation.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct GDTEntry gdt_table[GDT_TABLE_SIZE];
7272
struct GDTReference gdtr;
7373

7474
struct Process *get_process(int pid) {
75+
if(pid<0 || pid>=MAX_PROCESS) return NULL;
7576
return &processes[pid];
7677
}
7778

@@ -83,6 +84,7 @@ void process_scheduler_init() {
8384
// after the process scheduler starts
8485
// main thread kernel is ready to be killed.
8586
processes[PID_KERNEL].state=STATE_EXIT;
87+
processes[PID_KERNEL].ppid=PID_KERNEL;
8688

8789
populate_gdt_table(
8890
&gdtr, gdt_table, GDT_TABLE_SIZE,
@@ -121,7 +123,7 @@ static int create_infant_process_argv_stack(int user_ds, int user_sp,
121123
return user_sp;
122124
}
123125

124-
int process_create(int argc, char *argv[]) {
126+
int process_create(unsigned int ppid, int argc, char *argv[]) {
125127
// returnd pid >= 0 if success
126128
int pid = -1;
127129
for (int i = 0; i < MAX_PROCESS; ++i) {
@@ -157,6 +159,7 @@ int process_create(int argc, char *argv[]) {
157159

158160

159161
// update process state
162+
process->ppid = ppid;
160163
process->state = STATE_LOADING;
161164
process->cs = get_gdt_number_from_entry_id(idt_cs_entry);
162165
process->ip = 0;
@@ -167,8 +170,7 @@ int process_create(int argc, char *argv[]) {
167170
return pid;
168171
}
169172

170-
void process_kill(int user_ds, int status) {
171-
int pid = get_idt_reverse_pid_lookup_ds(user_ds);
173+
void process_kill(unsigned int pid, int status) {
172174
struct Process *process = &processes[pid];
173175
process->status_code = status;
174176
process->state = STATE_EXIT;

src/kernel/process/process.c

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
#include <lib/utils/logging.h>
99
#include <lib/utils/output.h>
1010

11-
int process_spawn(int lba_index, int sector_count, int argc, char *argv[]) {
11+
int process_spawn(int lba_index, int sector_count,
12+
unsigned int ppid, int argc, char *argv[]) {
1213
print_info("[process_spawn] create");
13-
int pid = process_create(argc, argv);
14+
int pid = process_create(ppid, argc, argv);
1415
if(pid<0) {
1516
print_log("Failed to reserved a new pid");
1617
return -1;
@@ -26,30 +27,25 @@ int process_spawn(int lba_index, int sector_count, int argc, char *argv[]) {
2627
struct Process *process = get_process(pid);
2728
process->state = STATE_READY;
2829
VERIFY_STACKGUARD();
29-
return 0;
30+
return pid;
3031
}
3132

3233
int process_exec(int lba_index, int sector_count) {
3334
// Not yet implemented
3435
return -1;
3536
}
3637

37-
int syscall_1_process_exit(int user_ds, int status) {
38-
process_kill(user_ds, status);
38+
int syscall_1_process_exit(int pid, int status) {
39+
process_kill(pid, status);
3940
return 0;
4041
}
4142

42-
int syscall_1_process_spawn_lba_sc(int lba_start, int sector_count) {
43-
int fake_argc = 1;
44-
ARGV fake_argv={"fake_spawn", NULL};
45-
return process_spawn(lba_start, sector_count, fake_argc, fake_argv);
46-
}
47-
48-
int syscall_1_process_exec_lba_sc(int lba_start, int sector_count) {
49-
return process_exec(lba_start, sector_count);
43+
int syscall_1_process_wait(int pid, int blocked_on_pid) {
44+
return process_waitpid(pid, blocked_on_pid);
5045
}
5146

52-
int syscall_1_process_spawn_fname(int user_ds, char *_us_filename, char *_us_argv[]) {
47+
int syscall_1_process_spawn_fname(unsigned int user_pid,
48+
int user_ds, char *_us_filename, char *_us_argv[]) {
5349
// User must send all PROCESS_MAX_ARGC arguments.
5450
char *argv_with_uspointer[PROCESS_MAX_ARGC];
5551
char filename[FS_FFS_FILENAME_LIMIT];
@@ -74,20 +70,19 @@ int syscall_1_process_spawn_fname(int user_ds, char *_us_filename, char *_us_arg
7470
int lba_start = resolve_abs_lba(FFS_UNIQUE_PARITION_ID, entry.content.start_block_id);
7571
int sector_count = (entry.content.filesize + FS_BLOCK_SIZE -1)/FS_BLOCK_SIZE;
7672

77-
return process_spawn(lba_start, sector_count, argc, argv);
73+
return process_spawn(lba_start, sector_count, user_pid, argc, argv);
7874
}
7975

8076
int syscall_1_process(int operation, int a0, int a1, int a2, int a3, int user_ds) {
77+
int user_pid = get_idt_reverse_pid_lookup_ds(user_ds);
8178
switch (operation) {
8279
case SYSCALL_PROCESS_SUB_EXIT:
83-
syscall_1_process_exit(user_ds, a0);
80+
syscall_1_process_exit(user_pid, a0);
8481
return 0;
85-
case SYSCALL_PROCESS_SUB_SPAWN_LBA_SC:
86-
return syscall_1_process_spawn_lba_sc(a0, a1);
87-
case SYSCALL_PROCESS_SUB_EXEC_LBA_SC:
88-
return syscall_1_process_exec_lba_sc(a0, a1);
82+
case SYSCALL_PROCESS_SUB_WAIT:
83+
return syscall_1_process_wait(user_pid, a0);
8984
case SYSCALL_PROCESS_SUB_SPAWN_FNAME:
90-
return syscall_1_process_spawn_fname(user_ds, (char*)a0, (char**)a1);
85+
return syscall_1_process_spawn_fname(user_pid, user_ds, (char*)a0, (char**)a1);
9186
}
9287
return -1;
9388
}

src/kernel/process/scheduler.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ void process_scheduler(int *_e_ip, int *_e_cs, int *_e_sp, int *_e_ss) {
7474
process->ss = e_ss;
7575
process->sp = e_sp;
7676
}
77+
// last process can be
78+
// - RUNNING
79+
// - BLOCK # TODO: implement
7780

7881
struct Process *nprocess = get_process(npid);
7982
nprocess->state = STATE_RUNNING;
@@ -86,4 +89,19 @@ void process_scheduler(int *_e_ip, int *_e_cs, int *_e_sp, int *_e_ss) {
8689
*_e_cs = e_cs;
8790
*_e_sp = e_sp;
8891
*_e_ss = e_ss;
89-
}
92+
}
93+
94+
int process_waitpid(unsigned int pid, unsigned int blocked_on_pid) {
95+
// TODO: this implementation has flaws.
96+
// We need to do better something.
97+
// It currently allows blocking on any pid, and rely on syscall client
98+
// for yield.
99+
struct Process *other_process = get_process(blocked_on_pid);
100+
if(other_process==NULL) {
101+
return -1; // err
102+
}
103+
if(other_process->state == STATE_COLD) {
104+
return 0; // no error, wait over
105+
}
106+
return 1; // no error, keep waiting
107+
}

src/kernel/syscall/syscall.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
int SYSCALL_TABLE[SYSCALL_SIZE];
1515

1616
int syscall_0_keyboard_getch(int a0,int a1,int a2,int a3, int user_ds) {
17-
return keyboard_get_key_pressed_blocking();
17+
return keyboard_get_key_pressed_poll();
1818
}
1919

2020
extern int interrupt_handler_0x32_syscall_handler();

src/usr/include/process.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
#pragma once
22

33
#define SYSCALL_PROCESS_SUB_EXIT 0
4-
#define SYSCALL_PROCESS_SUB_SPAWN_LBA_SC 1
5-
#define SYSCALL_PROCESS_SUB_EXEC_LBA_SC 2
6-
#define SYSCALL_PROCESS_SUB_SPAWN_FNAME 3
4+
#define SYSCALL_PROCESS_SUB_WAIT 1
5+
#define SYSCALL_PROCESS_SUB_SPAWN_FNAME 2
76

87
#define PROCESS_MAX_ARGC 6
98
#define PROCESS_MAX_ARG_LEN 32
@@ -15,3 +14,4 @@ int spawnl(char *path, char *arg0, ...);
1514
int spawnv(char *path, char *argv[]);
1615

1716
void yield();
17+
int waitpid(unsigned int blocked_on_pid);

0 commit comments

Comments
 (0)