- kdevelop3 project files
[lightOS.git] / kernel / scheduler.cpp
blobdb900241a7b85b95ef2d8d353c8296381b2345ae
1 /*
2 lightOS kernel
3 Copyright (C) 2006-2009 Jörg Pfähler
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <kernel/scheduler.hpp>
20 #include <kernel/processor.hpp>
21 using namespace std;
22 using namespace kernel;
24 #ifdef _LIGHTOS_V86
25 #include <kernel/x86/v86.hpp>
26 #endif
28 // TODO: Use a list for the threads
29 #include <kernel/log.hpp>
31 vector<thread*> scheduler::mList;
32 vector<thread*> scheduler::mExecList;
33 #ifdef _LIGHTOS_SMP
34 lightOS::spinlock scheduler::mLock;
35 #endif
37 void scheduler::add(thread *Thread)
39 LOCK(mLock);
40 mList.push_back(Thread);
41 UNLOCK(mLock);
43 void scheduler::remove(thread *Thread)
45 LOCK(mLock);
46 for (std::vector<thread*>::iterator i=mList.begin();i != mList.end();)
47 if (*i == Thread){i = mList.erase(i);}
48 else ++i;
49 for (std::vector<thread*>::iterator i=mExecList.begin();i != mExecList.end();)
50 if (*i == Thread){i = mExecList.erase(i);}
51 else ++i;
52 UNLOCK(mLock);
54 process *scheduler::get_process()
56 thread *Thread = get_thread();
58 if (Thread == 0)return 0;
59 return &Thread->getProcess();
61 thread *scheduler::get_thread()
63 // TODO: Bad if we have not yet initialized processor::
64 processor &Processor = *processor::get();
65 return Processor.get_thread();
67 void scheduler::schedule(interrupt_stackframe *stackframe)
69 /* Get the processor object for the processor we are currently running on */
70 processor &Processor = *processor::get();
72 /* Save the thread state and add the thread to the queue again */
73 thread *thisThread = Processor.get_thread();
74 if (stackframe != 0 && thisThread != 0)
75 thisThread->set_cpu_state(*stackframe);
77 /* Erase the thread from the exec list and add it to the normal non-blocking list */
78 LOCK(mLock);
79 if (thisThread != 0)
80 for (std::vector<thread*>::iterator i=mExecList.begin();i != mExecList.end();i++)
81 if (*i == thisThread)
83 mList.push_back(thisThread);
84 mExecList.erase(i);
85 break;
87 UNLOCK(mLock);
89 #ifdef _LIGHTOS_V86
90 if (v86::instance().is_v86_mode() == true)
92 #ifdef _LIGHTOS_SMP
93 if (v86::instance().processor_id() != processor::id())
94 while (v86::instance().is_v86_mode() == true);
95 else
96 #endif
98 executeV8086Thread();
100 #endif
102 /* Get the next thread */
103 LOCK(mLock);
104 thread *Thread = 0;
105 if (mList.size() != 0)
107 Thread = mList.front();
108 mList.erase(mList.begin());
109 mExecList.push_back(Thread);
111 UNLOCK(mLock);
113 /* Set the thread this processor is currently executing */
114 Processor.set_thread(Thread);
116 /* Execute the thread or idle */
117 if (Thread != 0)
119 //LOG("#" << dec << processor::id() << ": " << Thread->getProcess().getName().c_str() << endl);
120 executeThread( Thread->get_cpu_state(),
121 Thread->getProcess().getContext().get_handle());
123 else executeIdleThread();