mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 06:32:44 +00:00 
			
		
		
		
	Finally unbreak the colonel process and make it the true idle process.
This commit is contained in:
		
							parent
							
								
									440029c9d1
								
							
						
					
					
						commit
						43f40a3050
					
				
					 4 changed files with 59 additions and 52 deletions
				
			
		|  | @ -321,8 +321,12 @@ int Process::exec(const String& path, Vector<String>&& arguments, Vector<String> | ||||||
|     kprintf("Process %u (%s) exec'd %s @ %p\n", pid(), name().characters(), path.characters(), m_tss.eip); |     kprintf("Process %u (%s) exec'd %s @ %p\n", pid(), name().characters(), path.characters(), m_tss.eip); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     if (current == this) |     set_state(ExecPhase1); | ||||||
|         Scheduler::yield(); | 
 | ||||||
|  |     if (current == this) { | ||||||
|  |         bool success = Scheduler::yield(); | ||||||
|  |         ASSERT(success); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | @ -361,7 +365,7 @@ int Process::sys$execve(const char* filename, const char** argv, const char** en | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     int rc = exec(path, move(arguments), move(environment)); |     int rc = exec(path, move(arguments), move(environment)); | ||||||
|     ASSERT(rc < 0); |     ASSERT(rc < 0); // We should never continue after a successful exec!
 | ||||||
|     return rc; |     return rc; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -43,6 +43,8 @@ public: | ||||||
|         Invalid = 0, |         Invalid = 0, | ||||||
|         Runnable, |         Runnable, | ||||||
|         Running, |         Running, | ||||||
|  |         ExecPhase1, | ||||||
|  |         ExecPhase2, | ||||||
|         Dead, |         Dead, | ||||||
|         Forgiven, |         Forgiven, | ||||||
|         BeingInspected, |         BeingInspected, | ||||||
|  | @ -304,6 +306,8 @@ static inline const char* toString(Process::State state) | ||||||
|     case Process::Runnable: return "Runnable"; |     case Process::Runnable: return "Runnable"; | ||||||
|     case Process::Running: return "Running"; |     case Process::Running: return "Running"; | ||||||
|     case Process::Dead: return "Dead"; |     case Process::Dead: return "Dead"; | ||||||
|  |     case Process::ExecPhase1: return "ExecPhase1"; | ||||||
|  |     case Process::ExecPhase2: return "ExecPhase2"; | ||||||
|     case Process::Forgiven: return "Forgiven"; |     case Process::Forgiven: return "Forgiven"; | ||||||
|     case Process::BlockedSleep: return "Sleep"; |     case Process::BlockedSleep: return "Sleep"; | ||||||
|     case Process::BlockedWait: return "Wait"; |     case Process::BlockedWait: return "Wait"; | ||||||
|  |  | ||||||
|  | @ -10,6 +10,12 @@ static const dword time_slice = 5; // *10 = 50ms | ||||||
| Process* current; | Process* current; | ||||||
| static Process* s_colonel_process; | static Process* s_colonel_process; | ||||||
| 
 | 
 | ||||||
|  | struct TaskRedirectionData { | ||||||
|  |     word selector; | ||||||
|  |     TSS32 tss; | ||||||
|  | }; | ||||||
|  | static TaskRedirectionData s_redirection; | ||||||
|  | 
 | ||||||
| bool Scheduler::pick_next() | bool Scheduler::pick_next() | ||||||
| { | { | ||||||
|     ASSERT_INTERRUPTS_DISABLED(); |     ASSERT_INTERRUPTS_DISABLED(); | ||||||
|  | @ -50,6 +56,16 @@ bool Scheduler::pick_next() | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (process.state() == Process::ExecPhase1) { | ||||||
|  |             process.set_state(Process::ExecPhase2); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (process.state() == Process::ExecPhase2) { | ||||||
|  |             process.set_state(Process::Runnable); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         // Forgive dead orphans.
 |         // Forgive dead orphans.
 | ||||||
|         if (process.state() == Process::Dead) { |         if (process.state() == Process::Dead) { | ||||||
|             if (!Process::from_pid(process.ppid())) |             if (!Process::from_pid(process.ppid())) | ||||||
|  | @ -57,11 +73,11 @@ bool Scheduler::pick_next() | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Release the forgiven.
 |         // Release the forgiven.
 | ||||||
|         Process::for_each_in_state(Process::Forgiven, [] (auto& process) { |         if (process.state() == Process::Forgiven) { | ||||||
|             g_processes->remove(&process); |             g_processes->remove(&process); | ||||||
|             g_dead_processes->append(&process); |             g_dead_processes->append(&process); | ||||||
|             return true; |             return true; | ||||||
|         }); |         }; | ||||||
| 
 | 
 | ||||||
|         return true; |         return true; | ||||||
|     }); |     }); | ||||||
|  | @ -104,25 +120,13 @@ bool Scheduler::pick_next() | ||||||
| 
 | 
 | ||||||
|         if (process->state() == Process::Runnable || process->state() == Process::Running) { |         if (process->state() == Process::Runnable || process->state() == Process::Running) { | ||||||
| #ifdef SCHEDULER_DEBUG | #ifdef SCHEDULER_DEBUG | ||||||
|             dbgprintf("switch to %s(%u)\n", process->name().characters(), process->pid()); |             dbgprintf("switch to %s(%u) @ %w:%x\n", process->name().characters(), process->pid(), process->tss().cs, process->tss().eip); | ||||||
| #endif | #endif | ||||||
|             return context_switch(*process); |             return context_switch(*process); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (process == prevHead) { |         if (process == prevHead) { | ||||||
|             // Back at process_head, nothing wants to run.
 |             // Back at process_head, nothing wants to run. Send in the colonel!
 | ||||||
|             kprintf("Nothing wants to run!\n"); |  | ||||||
|             kprintf("PID    OWNER      STATE  NSCHED  NAME\n"); |  | ||||||
|             for (auto* process = g_processes->head(); process; process = process->next()) { |  | ||||||
|                 kprintf("%w   %w:%w  %b     %w    %s\n", |  | ||||||
|                     process->pid(), |  | ||||||
|                     process->uid(), |  | ||||||
|                     process->gid(), |  | ||||||
|                     process->state(), |  | ||||||
|                     process->timesScheduled(), |  | ||||||
|                     process->name().characters()); |  | ||||||
|             } |  | ||||||
|             kprintf("Switch to kernel process @ %w:%x\n", s_colonel_process->tss().cs, s_colonel_process->tss().eip); |  | ||||||
|             return context_switch(*s_colonel_process); |             return context_switch(*s_colonel_process); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -214,38 +218,34 @@ int sched_yield() | ||||||
|     return Scheduler::yield(); |     return Scheduler::yield(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void redo_colonel_process_tss() | static void initialize_redirection() | ||||||
| { | { | ||||||
|     if (!s_colonel_process->selector()) |     auto& descriptor = getGDTEntry(s_redirection.selector); | ||||||
|         s_colonel_process->setSelector(gdt_alloc_entry()); |     descriptor.setBase(&s_redirection.tss); | ||||||
| 
 |     descriptor.setLimit(0xffff); | ||||||
|     auto& tssDescriptor = getGDTEntry(s_colonel_process->selector()); |     descriptor.dpl = 0; | ||||||
| 
 |     descriptor.segment_present = 1; | ||||||
|     tssDescriptor.setBase(&s_colonel_process->tss()); |     descriptor.granularity = 1; | ||||||
|     tssDescriptor.setLimit(0xffff); |     descriptor.zero = 0; | ||||||
|     tssDescriptor.dpl = 0; |     descriptor.operation_size = 1; | ||||||
|     tssDescriptor.segment_present = 1; |     descriptor.descriptor_type = 0; | ||||||
|     tssDescriptor.granularity = 1; |     descriptor.type = 9; | ||||||
|     tssDescriptor.zero = 0; |  | ||||||
|     tssDescriptor.operation_size = 1; |  | ||||||
|     tssDescriptor.descriptor_type = 0; |  | ||||||
|     tssDescriptor.type = 9; |  | ||||||
| 
 |  | ||||||
|     flushGDT(); |     flushGDT(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Scheduler::prepare_for_iret_to_new_process() | void Scheduler::prepare_for_iret_to_new_process() | ||||||
| { | { | ||||||
|     redo_colonel_process_tss(); |     auto& descriptor = getGDTEntry(s_redirection.selector); | ||||||
|     s_colonel_process->tss().backlink = current->selector(); |     descriptor.type = 9; | ||||||
|     load_task_register(s_colonel_process->selector()); |     s_redirection.tss.backlink = current->selector(); | ||||||
|  |     load_task_register(s_redirection.selector); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Scheduler::prepare_to_modify_own_tss() | void Scheduler::prepare_to_modify_own_tss() | ||||||
| { | { | ||||||
|     // This ensures that a process modifying its own TSS in order to yield()
 |     // This ensures that a process modifying its own TSS in order to yield()
 | ||||||
|     // and end up somewhere else doesn't just end up right after the yield().
 |     // and end up somewhere else doesn't just end up right after the yield().
 | ||||||
|     load_task_register(s_colonel_process->selector()); |     load_task_register(s_redirection.selector); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void hlt_loop() | static void hlt_loop() | ||||||
|  | @ -257,8 +257,10 @@ static void hlt_loop() | ||||||
| 
 | 
 | ||||||
| void Scheduler::initialize() | void Scheduler::initialize() | ||||||
| { | { | ||||||
|  |     memset(&s_redirection, 0, sizeof(s_redirection)); | ||||||
|  |     s_redirection.selector = gdt_alloc_entry(); | ||||||
|  |     initialize_redirection(); | ||||||
|     s_colonel_process = Process::create_kernel_process(hlt_loop, "colonel"); |     s_colonel_process = Process::create_kernel_process(hlt_loop, "colonel"); | ||||||
|     current = nullptr; |     current = nullptr; | ||||||
|     redo_colonel_process_tss(); |     load_task_register(s_redirection.selector); | ||||||
|     load_task_register(s_colonel_process->selector()); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -168,7 +168,6 @@ static void spawn_stress() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| static void init_stage2() NORETURN; | static void init_stage2() NORETURN; | ||||||
| static void init_stage2() | static void init_stage2() | ||||||
| { | { | ||||||
|  | @ -242,21 +241,19 @@ static void init_stage2() | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     int error; |     int error; | ||||||
|     auto* sh0 = Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty0); |     Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty0); | ||||||
| #ifdef SPAWN_MULTIPLE_SHELLS | #ifdef SPAWN_MULTIPLE_SHELLS | ||||||
|     auto* sh1 = Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty1); |     Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty1); | ||||||
|     auto* sh2 = Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty2); |     Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty2); | ||||||
|     auto* sh3 = Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty3); |     Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty3); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef STRESS_TEST_SPAWNING | #ifdef STRESS_TEST_SPAWNING | ||||||
|     Process::createKernelProcess(spawn_stress, "spawn_stress"); |     Process::create_kernel_process(spawn_stress, "spawn_stress"); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     for (;;) { |     current->sys$exit(0); | ||||||
|         //sleep(3600 * TICKS_PER_SECOND);
 |     ASSERT_NOT_REACHED(); | ||||||
|         asm("hlt"); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void init() | void init() | ||||||
|  | @ -310,7 +307,7 @@ void init() | ||||||
|     Process::initialize(); |     Process::initialize(); | ||||||
| 
 | 
 | ||||||
|     Process::create_kernel_process(undertaker_main, "undertaker"); |     Process::create_kernel_process(undertaker_main, "undertaker"); | ||||||
|     Process::create_kernel_process(init_stage2, "init"); |     Process::create_kernel_process(init_stage2, "init_stage2"); | ||||||
| 
 | 
 | ||||||
|     Scheduler::pick_next(); |     Scheduler::pick_next(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling