13using namespace MaxOS::processes;
14using namespace MaxOS::memory;
15using namespace MaxOS::hardwarecommunication;
16using namespace MaxOS::system;
65 if(!s_instance || !s_instance->m_active)
69 ASSERT(s->rip != 0,
"Cant run a empty state\n");
94 delete core->scheduler;
103 s_instance -> m_active =
true;
105 core->scheduler->activate();
114 s_instance -> m_active =
false;
116 core->scheduler->deactivate();
143 if (tag->type != MULTIBOOT_TAG_TYPE_MODULE)
147 auto*
module = (struct multiboot_tag_module*) tag;
152 Logger::DEBUG() <<
"Creating process from multiboot module for " <<
module->cmdline << " (at 0x" << (uint64_t) module->mod_start << ")\n";
155 char* args[1] = {
module->cmdline};
158 auto* process =
new Process(module->cmdline, args, 1, &elf);
161 Logger::DEBUG() <<
"ELF loaded to pid " << process->pid() <<
"\n";
171 if(!s_instance || !s_instance->m_active)
193 uint64_t core_id = 0;
205 m_core_pids.
insert(pid,core_id);
207 Logger::DEBUG() <<
"Adding process " << pid <<
": " << process->
name <<
" to core " << core_id <<
"\n";
224 uint64_t core_id = 0;
236 m_core_tids.
insert(tid,core_id);
238 Logger::DEBUG() <<
"Adding thread " << tid <<
" to core " << core_id <<
"\n";
254 auto core = s_instance -> m_core_pids[process->
pid()];
255 return CPU::cores[core]->scheduler->remove_process(process);
270 auto core = s_instance -> m_core_pids[process->
pid()];
271 return CPU::cores[core]->scheduler->force_remove_process(process);
281 if(!s_instance || !s_instance ->m_active)
299 auto core = s_instance -> m_core_pids[pid];
300 return CPU::cores[core]->scheduler->get_process(pid);
308 return s_instance -> m_next_pid++;
332 auto core = s_instance -> m_core_tids[tid];
333 return CPU::cores[core]->scheduler->get_thread(tid);
341 return s_instance->m_next_tid++;
359 return s_instance->m_active;
366: m_next_thread_index(0),
372 auto* idle =
new Process(
"Idle",
nullptr,
nullptr, 0,
true);
378Scheduler::~Scheduler() =
default;
390 if (m_threads.empty() || !m_active)
421 auto old_tid = m_next_thread_index;
430 while ((++m_next_thread_index) != old_tid){
431 m_next_thread_index %= m_threads.size();
440 case ThreadState::SLEEPING:
450 case ThreadState::STOPPED:
453 for (
auto thread: owner_process->
threads()) {
461 m_threads.erase(m_threads.begin() + m_next_thread_index);
462 if(owner_process->
threads().empty())
466 case ThreadState::WAITING:
512 m_processes.push_back(process);
515 for(
const auto& thread : process->
threads())
534 m_threads.push_back(thread);
558 if (m_threads.size() <= 1)
587 if (!process->
threads().empty()) {
590 for (
auto thread: process->
threads())
599 for (uint32_t i = 0; i < m_processes.size(); i++) {
600 if (m_processes[i] == process) {
601 m_processes.erase(m_processes.begin() + i);
626 for (
auto thread: process->
threads()) {
629 size_t index = m_threads.find(thread) - m_threads.begin();
630 m_threads.erase(m_threads.begin() + index);
652 for (
auto process: m_processes)
670 for (
auto process: m_processes)
671 if (process->
pid() == pid)
683 return m_processes.size();
693 return m_threads[m_next_thread_index];
701 return m_threads.size();
721 for (
auto thread: m_threads)
722 if (thread->
tid == tid)
static Logger DEBUG()
Gets active logger set to DEBUG level.
static Logger & Out()
Gets the active logger.
static Logger INFO()
Gets active logger set to info level.
void insert(Key, Value)
Updates the value of an element, or adds a new element if it does not exist.
Stores the left, top, width and height of a rectangle.
Handles a certain interrupt number.
virtual void handle_interrupt()
Handles an interrupt.
static MemoryManager * s_kernel_memory_manager
The memory manager for any kernel processes and all kernel allocations.
static void switch_active_memory_manager(MemoryManager *manager)
Switches the active memory manager.
static void * to_dm_region(uintptr_t physical_address)
Converts a physical address to a direct map region address if it is in the lower region using the hig...
Handles the loading and parsing of 64-bit ELF files.
bool is_valid() const
Checks if the elf file is valid for MaxOS runtime.
The global scheduler that manages all processes and threads across all cores.
static uint64_t next_pid()
Gets the next usable global PID.
static Scheduler * core_scheduler()
Gets the scheduler for the currently executing core.
static Process * get_process(uint64_t pid)
Gets a process on the currently executing core by its PID.
static uint64_t remove_process(Process *process)
Removes a process from the scheduler if the process has no threads, if it does then the threads are s...
static system::cpu_status_t * yield(system::cpu_status_t *current)
Pass execution to the next thread.
static void print_running_header()
Print the header for the running processes in the form ({name}:t{tid}c{core})
static uint64_t next_tid()
Gets the next usable global TID.
~GlobalScheduler()
Destroys the global scheduler and frees the per core schedulers.
static GlobalScheduler * system_scheduler()
Gets the system scheduler.
static Process * current_process()
Gets the process on the currently executing core.
static Thread * get_thread(uint64_t tid)
Gets a thread on the currently executing core by its TID.
GlobalScheduler(system::Multiboot &multiboot)
Constructs a new Global Scheduler object. Registers as the interrupt handler for interrupt 0x20 and s...
static void activate()
Activates each core's scheduler.
static void deactivate()
Deactivates each core's scheduler.
static bool is_active()
Checks if the global scheduler is active.
void balance()
Moves processes and threads between cores to balance the load so that each core has a similar amount ...
static Thread * current_thread()
Gets the thread on the currently executing core.
uint64_t add_process(Process *process)
Adds a process to the least busy core.
uint64_t add_thread(Thread *thread)
Adds a thread to the least busy core.
static void load_multiboot_elfs(system::Multiboot *multiboot)
Loads any valid ELF files from the multiboot structure.
static system::cpu_status_t * force_remove_process(Process *process)
Removes a process from the scheduler and deletes all threads, begins running the next process.
A process that can be scheduled by the Scheduler, wraps & manages threads as well as its own address ...
uint64_t pid() const
Gets the pid of the process.
string name
The name of the process.
common::Vector< Thread * > threads()
Gets the threads of the process.
void set_pid(uint64_t pid)
Sets the pid of the process once added to the queue.
void remove_thread(uint64_t tid)
Remove a thread by its tid (NOTE: this will not remove it from the scheduler)
memory::MemoryManager * memory_manager
The manager for memory used by this process.
Schedules processes to run on the core via their threads.
uint64_t remove_process(Process *process)
Removes a process from the scheduler if the process has no threads, if it does then the threads are s...
uint64_t ticks() const
Gets how long the system has been running for.
Scheduler()
Constructs a new Scheduler object and creates the idle process.
uint64_t thread_amount()
Gets how many threads are running on this scheduler.
Thread * current_thread()
Gets the currently executing thread.
system::cpu_status_t * yield()
Pass execution to the next thread.
system::cpu_status_t * force_remove_process(Process *process)
Removes a process from the scheduler and deletes all threads, begins running the next process.
Process * get_process(uint64_t pid)
Gets a process by its PID.
uint64_t add_process(Process *process)
Adds a process to the scheduler.
Thread * get_thread(uint64_t tid)
Gets a thread by its TID.
uint64_t add_thread(Thread *thread)
Adds a thread to the scheduler.
system::cpu_status_t * schedule(system::cpu_status_t *cpu_state)
Schedules the next thread to run.
uint64_t process_amount()
Gets how processes are running on this scheduler.
void activate()
Activates the scheduler.
Process * current_process()
Gets the current process.
system::cpu_status_t * schedule_next(system::cpu_status_t *status)
Schedules the next thread to run.
void deactivate()
Deactivates the scheduler.
The execution context of a sub-process thread.
thread_state_t thread_state
The current state of the thread.
uint64_t parent_pid
The parent process ID.
void save_sse_state()
Saves the SSE, x87 FPU, and MMX states from memory to the thread.
uint64_t tid
The thread ID.
size_t wakeup_time
The time at which the thread should wake up (if sleeping)
system::cpu_status_t execution_state
The CPU state of the thread.
uintptr_t tss_pointer() const
Gets the stack pointer to use for the TSS when switching to this thread.
void restore_sse_state()
Restores the SSE, x87 FPU, and MMX states from the thread to memory.
size_t ticks
The number of ticks the thread has run for.
static common::Vector< Core * > cores
The list of CPU cores in the system (populated during initialization, includes the BSP and cores that...
static Core * executing_core()
Gets the core that is currently executing.
uint8_t id
The ID of this core.
processes::Scheduler * scheduler
The scheduler for this core.
Parses and provides access to Multiboot 2 information.
multiboot_tag * start_tag() const
struct PACKED MaxOS::system::CPUStatus cpu_status_t
Alias for CPUStatus struct.
Defines a Logger class for logging messages with different severity levels to multiple output streams...
#define ASSERT(condition, format,...)
If the specified condition is not met then the kernel will crash with the specified message.
::syscore::ResourceType resource_type_t
Alias to make the libsyscore ResourceType accessible here.
Defines a GlobalScheduler and Scheduler for managing processes and threads.
constexpr size_t TICKS_PER_EVENT
Number of times the clock has to interrupt before switching to the next process/thread.
Common header for all multiboot info tags.