File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -145,11 +145,6 @@ typedef struct thread {
145145
146146 /** Information relative to the current state of the thread */
147147 union {
148- /** For running threads only */
149- struct {
150- /** End of the currently running thread's timeslice */
151- clock_t preempt ;
152- } running ;
153148 /** For sleeping threads only */
154149 struct {
155150 clock_t wakeup ; /*!< Time when it should wakeup (in ticks) */
@@ -160,7 +155,8 @@ typedef struct thread {
160155
161156/** @enum thread_flags */
162157typedef enum thread_flags {
163- THREAD_KERNEL = BIT (0 ), ///< This thread runs in kernel mode
158+ THREAD_KERNEL = BIT (0 ), ///< This is a kernel thread
159+ THREAD_RESCHED = BIT (1 ), ///< Reschedule when exiting interrupt
164160} process_flags_t ;
165161
166162/***/
Original file line number Diff line number Diff line change 88#ifndef KERNEL_TIME_H
99#define KERNEL_TIME_H
1010
11- /* The number of clock ticks in a second (1KHz). */
12- #define CLOCK_PER_SECOND 1000
11+ /*
12+ * The number of clock ticks in a second (100Hz, 1 tick = 100ms).
13+ *
14+ * This is also used as the maximum time a thread is allowed to run for
15+ * before being rescheduled (thread will be forcefully rescheduled
16+ * when a timer interrupt eventually occurs).
17+ */
18+ #define TICKS_PER_SECOND 100
1319
1420/** @brief Used for conversions from seconds to another time unit @{ */
1521#define SEC (_x ) (_x)
Original file line number Diff line number Diff line change 2020#include <kernel/time.h>
2121#include <kernel/types.h>
2222
23- /** The frequency used for the timer (in Hz) */
24- #define HZ CLOCK_PER_SECOND
25-
2623/** @brief Compute the number of ticks in a given time frame @{ */
27- #define SEC_TO_TICKS (_time ) SEC((_time) * HZ )
24+ #define SEC_TO_TICKS (_time ) SEC((_time) * TICKS_PER_SECOND )
2825#define MS_TO_TICKS (_time ) MS_TO_SEC(SEC_TO_TICKS(_time))
2926#define US_TO_TICKS (_time ) US_TO_SEC(SEC_TO_TICKS(_time))
3027#define NS_TO_TICKS (_time ) NS_TO_SEC(SEC_TO_TICKS(_time))
3128/** @} */
3229
3330/** @brief Convert a number of ticks into a regular time unit @{ */
34- #define TICKS_TO_SEC (_ticks ) SEC((_ticks) / HZ )
31+ #define TICKS_TO_SEC (_ticks ) SEC((_ticks) / TICKS_PER_SECOND )
3532#define TICKS_TO_MS (_ticks ) MS(TICKS_TO_SEC(_ticks))
3633#define TICKS_TO_US (_ticks ) US(TICKS_TO_SEC(_ticks))
3734#define TICKS_TO_NS (_ticks ) NS(TICKS_TO_SEC(_ticks))
Original file line number Diff line number Diff line change @@ -783,6 +783,12 @@ static INTERRUPT_HANDLER_FUNCTION(page_fault)
783783
784784 UNUSED (data );
785785
786+ /*
787+ * Starting a new process can generate a lot of page faults. Avoid
788+ * rescheduling for page faults to speed up process startup.
789+ */
790+ current -> flags &= ~THREAD_RESCHED ;
791+
786792 if (!error .present || is_cow ) {
787793 as = IS_KERNEL_ADDRESS (faulty_address ) ? & kernel_address_space
788794 : current -> process -> as ;
Original file line number Diff line number Diff line change 1515
1616#define LOG_DOMAIN "timer"
1717
18- #include <kernel/timer.h>
1918#include <kernel/error.h>
2019#include <kernel/interrupts.h>
2120#include <kernel/logger.h>
2221#include <kernel/sched.h>
22+ #include <kernel/timer.h>
2323
2424#include <kernel/arch/i686/devices/pic.h>
2525#include <kernel/arch/i686/devices/pit.h>
@@ -55,25 +55,11 @@ static INTERRUPT_HANDLER_FUNCTION(irq_timer)
5555
5656 pic_eoi (IRQ_TIMER );
5757
58- if (!scheduler_initialized )
59- return INTERRUPT_HANDLED ;
60-
61- // TODO: Use a separate and more modern timer for scheduler (LAPIC, HPET)
62- //
63- // We could be setting the next timer interrupt dynamically to match the
64- // next due task, but:
65- // * this is our main timekeeping source, and it would make it less accurate
66- // * the PIT is too slow to re-program dynamically like this
67-
68- // TODO: Don't mingle IRQ and scheduling
69-
7058 /*
7159 * Unblock waiting threads whose deadline has been reached, and preempt
7260 * the current thread if we reached the end of its timeslice.
7361 */
7462 sched_unblock_waiting_before (timer_ticks_counter );
75- if (current -> running .preempt <= timer_ticks_counter )
76- schedule ();
7763
7864 return INTERRUPT_HANDLED ;
7965}
Original file line number Diff line number Diff line change @@ -190,7 +190,7 @@ void kernel_main(struct multiboot_info *mbt, unsigned int magic)
190190 * IRQs and controllers are setup, we can safely enable interrupts.
191191 */
192192 interrupts_enable ();
193- timer_start (HZ );
193+ timer_start (TICKS_PER_SECOND );
194194
195195 mbt_info = kmalloc (mbt_tmp .mbt .total_size , KMALLOC_KERNEL );
196196 memcpy (mbt_info , mbt_tmp .raw , mbt_tmp .mbt .total_size );
Original file line number Diff line number Diff line change 55#include <kernel/interrupts.h>
66#include <kernel/kmalloc.h>
77#include <kernel/logger.h>
8+ #include <kernel/sched.h>
89
910#include <libalgo/linked_list.h>
1011
@@ -42,7 +43,22 @@ interrupt_chip_interrupt_handle(const struct interrupt_chip *chip,
4243 */
4344error_t interrupt_handle (unsigned int nr )
4445{
45- return interrupt_chip_interrupt_handle (& interrupt_root_chip , nr );
46+ error_t err ;
47+
48+ current -> flags |= THREAD_RESCHED ;
49+
50+ err = interrupt_chip_interrupt_handle (& interrupt_root_chip , nr );
51+
52+ /*
53+ * Try to reschedule the current thread. This is the best time to do so.
54+ *
55+ * TODO: Make sure that a user thread does not return to userland with
56+ * preemption disabled.
57+ */
58+ if (current -> flags & THREAD_RESCHED )
59+ schedule ();
60+
61+ return err ;
4662}
4763
4864/*
Original file line number Diff line number Diff line change @@ -14,9 +14,6 @@ bool scheduler_initialized = false;
1414
1515static DECLARE_LLIST (sleeping_tasks );
1616
17- /** The maximum timeslice given to a thread by the scheduler */
18- #define SCHED_TIMESLICE MS_TO_TICKS(2ULL) // 2MS
19-
2017typedef struct scheduler {
2118
2219 /** The runqueue
@@ -50,6 +47,9 @@ static void schedule_locked(bool preempt, bool reschedule)
5047{
5148 node_t * next_node ;
5249
50+ if (unlikely (!scheduler_initialized ))
51+ return ;
52+
5353 if (atomic_read (& scheduler .sync .preemption_level ) > 1 && !preempt )
5454 return ;
5555
@@ -79,11 +79,8 @@ static void schedule_locked(bool preempt, bool reschedule)
7979 }
8080 }
8181
82- next -> running .preempt = timer_gettick () + SCHED_TIMESLICE ;
83-
84- if (!thread_switch (next )) {
82+ if (!thread_switch (next ))
8583 schedule_locked (preempt , false);
86- }
8784}
8885
8986void schedule (void )
You can’t perform that action at this time.
0 commit comments