3232
3333static UINT processCount ;
3434static KProcessInfo * currentProcess = NULL ;
35+ static KProcessInfo * rootProcess = NULL ;
3536static ListNode schedulerQueueHead = { 0 };
3637
3738static bool s_switchProcess (KProcessInfo * nextProcess , ProcessRegisterState * currentProcessState );
@@ -49,6 +50,7 @@ static void s_showQueueItems (ListNode* forward, bool directionForward);
4950#else
5051 #define s_showQueueItems (...) (void)0
5152#endif // DEBUG
53+ static void change_parent_process (KProcessInfo * const p , KProcessInfo * const parent );
5254
5355__attribute__ ((noreturn )) void jump_to_process (U32 type , x86_CR3 cr3 , ProcessRegisterState * regs );
5456
@@ -399,6 +401,13 @@ static bool s_switchProcess (KProcessInfo* nextProcess, ProcessRegisterState* cu
399401
400402 nextProcess -> state = PROCESS_STATE_RUNNING ;
401403 currentProcess = nextProcess ;
404+
405+ // Root process is set at the time of switching and not at creation time to ensure that the
406+ // creation of the root process was successful.
407+ if (currentProcess -> parent == NULL ) {
408+ rootProcess = currentProcess ;
409+ }
410+
402411 jump_to_process (nextProcess -> flags , cr3 , reg );
403412
404413 UNREACHABLE ();
@@ -445,12 +454,23 @@ static bool kprocess_kill_process (KProcessInfo** process, U8 exitCode)
445454 if (!(cpinfo = LIST_ITEM (node , KProcessInfo , childrenListNode ))) {
446455 FATAL_BUG ();
447456 }
457+
448458 INFO ("Killing child process. PID: %u" , cpinfo -> processID );
449- if (!kprocess_kill_process (& cpinfo , KPROCESS_EXIT_CODE_FORCE_KILLED )) {
450- FATAL_BUG (); // Under normal condition its not possible for such a failure.
459+
460+ // Only thread process are killed. Non-thread processes are made child processes of the
461+ // Root process.
462+ if (BIT_ISUNSET (cpinfo -> flags , PROCESS_FLAGS_THREAD )) {
463+ INFO ("Non thread process cannot be killed. Being adopted by root process." );
464+ change_parent_process (cpinfo , rootProcess );
465+ k_assert (cpinfo -> parent == rootProcess , "Wrong parent set for process" );
466+ } else {
467+ INFO ("Killing child thread process. PID: %u" , cpinfo -> processID );
468+ if (!kprocess_kill_process (& cpinfo , KPROCESS_EXIT_CODE_FORCE_KILLED )) {
469+ FATAL_BUG (); // Under normal condition its not possible for such a failure.
470+ }
451471 }
452472 }
453- INFO ("All child processes killed. Now killing parent: %x" , l_process -> processID );
473+ INFO ("All child processes killed/adopted . Now killing parent: %x" , l_process -> processID );
454474
455475 // If current process is not the process being killed, then there is no need to change
456476 // Page Directories.
@@ -523,6 +543,20 @@ static bool kprocess_kill_process (KProcessInfo** process, U8 exitCode)
523543}
524544#pragma GCC diagnostic pop
525545
546+ static void change_parent_process (KProcessInfo * const p , KProcessInfo * const parent )
547+ {
548+ // Root process cannot be child of another process
549+ k_assert (p != rootProcess , "Child process cannot be child of another process" );
550+
551+ // Remove the process from the list of its current parent
552+ list_remove (& p -> childrenListNode );
553+
554+ // Processes created by threads are owned by its parent process.
555+ p -> parent = BIT_ISSET (parent -> flags , PROCESS_FLAGS_THREAD ) ? parent -> parent : parent ;
556+ // Add the process to the list of its new parent.
557+ list_add_before (& p -> parent -> childrenListHead , & p -> childrenListNode );
558+ }
559+
526560void kprocess_init ()
527561{
528562 list_init (& schedulerQueueHead );
@@ -580,18 +614,12 @@ INT kprocess_create (void* processStartAddress, SIZE binLengthBytes, KProcessFla
580614 // Root processes does not have a parent.
581615 pinfo -> parent = NULL ;
582616 if (currentProcess == NULL ) {
583- // Must be creation of root process. Must not be a flag
584- k_assert (BIT_ISUNSET (pinfo -> flags , PROCESS_FLAGS_THREAD ), "Orphan thread " );
617+ // Must be creation of root process. Must not be a thread process.
618+ k_assert (BIT_ISUNSET (pinfo -> flags , PROCESS_FLAGS_THREAD ), "Threads cannot be Root " );
585619 INFO ("Root process creation" );
586620 } else {
587- // Processes created by threads are owned by its parent process.
588- pinfo -> parent = BIT_ISSET (currentProcess -> flags , PROCESS_FLAGS_THREAD )
589- ? currentProcess -> parent
590- : currentProcess ;
591-
621+ change_parent_process (pinfo , currentProcess );
592622 k_assert (pinfo -> parent != NULL , "Non-Root processes & Threads must have a parent" );
593- // Parent is non-root process
594- list_add_before (& pinfo -> parent -> childrenListHead , & pinfo -> childrenListNode );
595623 }
596624
597625 INFO ("New process: ID = %u, Parent ID: %u" , pinfo -> processID , PARENT_PROCESS_ID (pinfo ));
0 commit comments