@@ -123,8 +123,7 @@ static int create_infant_process_argv_stack(int user_ds, int user_sp,
123123 return user_sp ;
124124}
125125
126- int process_create (unsigned int ppid , int argc , char * argv []) {
127- // returnd pid >= 0 if success
126+ static int get_cold_pid () {
128127 int pid = -1 ;
129128 for (int i = 0 ; i < MAX_PROCESS ; ++ i ) {
130129 if (i == PID_KERNEL ) continue ;
@@ -133,8 +132,17 @@ int process_create(unsigned int ppid, int argc, char *argv[]) {
133132 break ;
134133 }
135134 }
135+ return pid ;
136+ }
137+
138+ int process_create (unsigned int ppid , int argc , char * argv []) {
139+ // returnd pid >= 0 if success
140+ int pid = get_cold_pid ();
136141 if (pid < 0 ) return pid ;
137142 struct Process * process = & processes [pid ];
143+ // reset state
144+ process -> flagirq0_fork_ready = 0 ;
145+ process -> flagirq0_fork_newchild = -1 ;
138146
139147 int memory_location = memmgr_app_abs_location (pid );
140148 int memory_size = memmgr_app_size (pid );
@@ -165,8 +173,12 @@ int process_create(unsigned int ppid, int argc, char *argv[]) {
165173 process -> ip = 0 ;
166174 // initially ds == ss
167175 process -> ss = get_gdt_number_from_entry_id (idt_ds_entry );
168- process -> sp = create_infant_process_argv_stack (process -> ss , STACKINIT_APP , argc , argv );
169- process -> sp = create_infant_process_irq0_stack (process -> ss , process -> sp );
176+ if (argc > 0 ) {
177+ // process_create for those who don't care about stack initilization
178+ // like fork(), they will copy whole segment memory.
179+ process -> sp = create_infant_process_argv_stack (process -> ss , STACKINIT_APP , argc , argv );
180+ process -> sp = create_infant_process_irq0_stack (process -> ss , process -> sp );
181+ }
170182 return pid ;
171183}
172184
@@ -176,6 +188,57 @@ void process_kill(unsigned int pid, int status) {
176188 process -> state = STATE_EXIT ;
177189}
178190
191+ int process_fork_mark_ready (int pid ) {
192+ struct Process * process = get_process (pid );
193+ if (process == NULL ) return -2 ;
194+ if (process -> flagirq0_fork_ready > 0 ) return -3 ; // denied; fork already requested.
195+ process -> flagirq0_fork_ready = 1 ; // success; fork requested
196+ return 0 ;
197+ }
198+
199+ int process_fork_check_ready (int pid ) {
200+ // should be called after process_fork_mark_ready
201+ struct Process * process = get_process (pid );
202+ if (process == NULL ) return -2 ;
203+ if (process -> flagirq0_fork_ready == -1 ) return -3 ; // fork request: failed
204+ // bad state from user side
205+ if (process -> flagirq0_fork_ready == 1 ) return -4 ; // fork request: still waiting
206+ return process -> flagirq0_fork_newchild ; // fork request: success and return new pid
207+ }
208+
209+ int process_fork (unsigned int ppid ) {
210+ // should be called from irq0 only.
211+ int npid = process_create (ppid , 0 , NULL );
212+ if (npid < 0 ) return npid ;
213+ struct Process * process = get_process (ppid );
214+ struct Process * nprocess = get_process (npid );
215+
216+ nprocess -> state = STATE_READY ;
217+
218+ nprocess -> sp = process -> sp ;
219+ nprocess -> ip = process -> ip ;
220+
221+ process -> state = STATE_EXIT ;
222+
223+ size_t size = min (
224+ memmgr_app_size (ppid ),
225+ memmgr_app_size (npid )
226+ );
227+ int dst_ds = get_gdt_number_from_entry_id (get_idt_ds_entry (npid ));
228+ int src_ds = get_gdt_number_from_entry_id (get_idt_ds_entry (ppid ));
229+
230+ kernel_memncpy_absolute (
231+ dst_ds ,
232+ 0 ,
233+ src_ds ,
234+ 0 ,
235+ size
236+ );
237+ print_log ("copy success" );
238+ // PANIC(0, "A");
239+ return npid ;
240+ }
241+
179242int process_load_from_disk (int pid , int lba_index , int sector_count ) {
180243 int memory_location = memmgr_app_abs_location (pid );
181244 int err = load_sectors (memory_location , 0x80 , lba_index , sector_count );
0 commit comments