/SPARTAN/trunk/generic/include/print.h |
---|
36,11 → 36,6 |
#define INT32 4 |
#define INT64 8 |
static void print_double(double num, __u8 modifier, __u16 precision) ; |
static void print_str(const char *str); |
static void print_fixed_hex(const __u64 num, const int width); |
static void print_number(const __native num, const unsigned int base); |
extern void putchar(const char c); |
extern void printf(const char *fmt, ...); |
/SPARTAN/trunk/generic/include/proc/scheduler.h |
---|
44,11 → 44,6 |
}; |
extern volatile count_t nrdy; |
static thread_t *find_best_thread(void); |
static void relink_rq(int start); |
static void scheduler_separated_stack(void); |
extern void scheduler_init(void); |
extern void scheduler_fpu_lazy_request(void); |
/SPARTAN/trunk/generic/include/proc/thread.h |
---|
112,8 → 112,6 |
extern spinlock_t threads_lock; /**< Lock protecting threads_head list. */ |
extern link_t threads_head; /**< List of all threads in the system. */ |
static void cushion(void); |
extern void thread_init(void); |
extern thread_t *thread_create(void (* func)(void *), void *arg, task_t *task, int flags); |
extern void thread_ready(thread_t *t); |
/SPARTAN/trunk/generic/src/proc/scheduler.c |
---|
116,7 → 116,7 |
* @return Thread to be scheduled. |
* |
*/ |
struct thread *find_best_thread(void) |
static struct thread *find_best_thread(void) |
{ |
thread_t *t; |
runq_t *r; |
222,7 → 222,7 |
* @param start Threshold priority. |
* |
*/ |
void relink_rq(int start) |
static void relink_rq(int start) |
{ |
link_t head; |
runq_t *r; |
254,71 → 254,6 |
} |
/** The scheduler |
* |
* The thread scheduling procedure. |
* |
*/ |
void scheduler(void) |
{ |
volatile ipl_t ipl; |
ASSERT(CPU != NULL); |
ipl = interrupts_disable(); |
if (haltstate) |
halt(); |
if (THREAD) { |
spinlock_lock(&THREAD->lock); |
#ifndef FPU_LAZY |
fpu_context_save(&(THREAD->saved_fpu_context)); |
#endif |
if (!context_save(&THREAD->saved_context)) { |
/* |
* This is the place where threads leave scheduler(); |
*/ |
before_thread_runs(); |
spinlock_unlock(&THREAD->lock); |
interrupts_restore(THREAD->saved_context.ipl); |
return; |
} |
/* |
* Interrupt priority level of preempted thread is recorded here |
* to facilitate scheduler() invocations from interrupts_disable()'d |
* code (e.g. waitq_sleep_timeout()). |
*/ |
THREAD->saved_context.ipl = ipl; |
} |
/* |
* Through the 'THE' structure, we keep track of THREAD, TASK, CPU |
* and preemption counter. At this point THE could be coming either |
* from THREAD's or CPU's stack. |
*/ |
the_copy(THE, (the_t *) CPU->stack); |
/* |
* We may not keep the old stack. |
* Reason: If we kept the old stack and got blocked, for instance, in |
* find_best_thread(), the old thread could get rescheduled by another |
* CPU and overwrite the part of its own stack that was also used by |
* the scheduler on this CPU. |
* |
* Moreover, we have to bypass the compiler-generated POP sequence |
* which is fooled by SP being set to the very top of the stack. |
* Therefore the scheduler() function continues in |
* scheduler_separated_stack(). |
*/ |
context_save(&CPU->saved_context); |
context_set(&CPU->saved_context, FADDR(scheduler_separated_stack), (__address) CPU->stack, CPU_STACK_SIZE); |
context_restore(&CPU->saved_context); |
/* not reached */ |
} |
/** Scheduler stack switch wrapper |
* |
* Second part of the scheduler() function |
326,7 → 261,7 |
* switch to a new thread. |
* |
*/ |
void scheduler_separated_stack(void) |
static void scheduler_separated_stack(void) |
{ |
int priority; |
459,6 → 394,74 |
} |
/** The scheduler |
* |
* The thread scheduling procedure. |
* |
*/ |
void scheduler(void) |
{ |
volatile ipl_t ipl; |
ASSERT(CPU != NULL); |
ipl = interrupts_disable(); |
if (haltstate) |
halt(); |
if (THREAD) { |
spinlock_lock(&THREAD->lock); |
#ifndef FPU_LAZY |
fpu_context_save(&(THREAD->saved_fpu_context)); |
#endif |
if (!context_save(&THREAD->saved_context)) { |
/* |
* This is the place where threads leave scheduler(); |
*/ |
before_thread_runs(); |
spinlock_unlock(&THREAD->lock); |
interrupts_restore(THREAD->saved_context.ipl); |
return; |
} |
/* |
* Interrupt priority level of preempted thread is recorded here |
* to facilitate scheduler() invocations from interrupts_disable()'d |
* code (e.g. waitq_sleep_timeout()). |
*/ |
THREAD->saved_context.ipl = ipl; |
} |
/* |
* Through the 'THE' structure, we keep track of THREAD, TASK, CPU |
* and preemption counter. At this point THE could be coming either |
* from THREAD's or CPU's stack. |
*/ |
the_copy(THE, (the_t *) CPU->stack); |
/* |
* We may not keep the old stack. |
* Reason: If we kept the old stack and got blocked, for instance, in |
* find_best_thread(), the old thread could get rescheduled by another |
* CPU and overwrite the part of its own stack that was also used by |
* the scheduler on this CPU. |
* |
* Moreover, we have to bypass the compiler-generated POP sequence |
* which is fooled by SP being set to the very top of the stack. |
* Therefore the scheduler() function continues in |
* scheduler_separated_stack(). |
*/ |
context_save(&CPU->saved_context); |
context_set(&CPU->saved_context, FADDR(scheduler_separated_stack), (__address) CPU->stack, CPU_STACK_SIZE); |
context_restore(&CPU->saved_context); |
/* not reached */ |
} |
#ifdef __SMP__ |
/** Load balancing thread |
* |
/SPARTAN/trunk/generic/src/proc/thread.c |
---|
70,7 → 70,7 |
* interrupts_disable() is assumed. |
* |
*/ |
void cushion(void) |
static void cushion(void) |
{ |
void (*f)(void *) = THREAD->thread_code; |
void *arg = THREAD->thread_arg; |
/SPARTAN/trunk/generic/src/main/kinit.c |
---|
122,17 → 122,21 |
* Create the first user task. |
*/ |
m = vm_create(NULL); |
if (!m) panic("vm_create"); |
if (!m) |
panic("vm_create"); |
u = task_create(m); |
if (!u) panic("task_create"); |
if (!u) |
panic("task_create"); |
t = thread_create(uinit, NULL, u, THREAD_USER_STACK); |
if (!t) panic("thread_create"); |
if (!t) |
panic("thread_create"); |
/* |
* Create the text vm_area and copy the userspace code there. |
*/ |
a = vm_area_create(m, VMA_TEXT, 1, UTEXT_ADDRESS); |
if (!a) panic("vm_area_create: vm_text"); |
if (!a) |
panic("vm_area_create: vm_text"); |
vm_area_map(a, m); |
memcpy((void *) PA2KA(a->mapping[0]), (void *) utext, utext_size < PAGE_SIZE ? utext_size : PAGE_SIZE); |
140,7 → 144,8 |
* Create the data vm_area. |
*/ |
a = vm_area_create(m, VMA_STACK, 1, USTACK_ADDRESS); |
if (!a) panic("vm_area_create: vm_stack"); |
if (!a) |
panic("vm_area_create: vm_stack"); |
vm_area_map(a, m); |
thread_ready(t); |
/SPARTAN/trunk/generic/src/debug/print.c |
---|
41,8 → 41,72 |
#define DEFAULT_DOUBLE_PRECISION 16 |
#define DEFAULT_DOUBLE_BUFFER_SIZE 128 |
void print_double(double num, __u8 modifier, __u16 precision) |
/** Print NULL terminated string |
* |
* Print characters from str using putchar() until |
* \\0 character is reached. |
* |
* @param str Characters to print. |
* |
*/ |
static void print_str(const char *str) |
{ |
int i = 0; |
char c; |
while (c = str[i++]) |
putchar(c); |
} |
/** Print hexadecimal digits |
* |
* Print fixed count of hexadecimal digits from |
* the number num. The digits are printed in |
* natural left-to-right order starting with |
* the width-th digit. |
* |
* @param num Number containing digits. |
* @param width Count of digits to print. |
* |
*/ |
static void print_fixed_hex(const __u64 num, const int width) |
{ |
int i; |
for (i = width*8 - 4; i >= 0; i -= 4) |
putchar(digits[(num>>i) & 0xf]); |
} |
/** Print number in given base |
* |
* Print significant digits of a number in given |
* base. |
* |
* @param num Number to print. |
* @param base Base to print the number in (should |
* be in range 2 .. 16). |
* |
*/ |
static void print_number(const __native num, const unsigned int base) |
{ |
int val = num; |
char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */ |
int i = sizeof(__native)*8-1; |
do { |
d[i--] = digits[val % base]; |
} while (val /= base); |
d[sizeof(__native)*8] = 0; |
print_str(&d[i + 1]); |
} |
static void print_double(double num, __u8 modifier, __u16 precision) |
{ |
double intval,intval2; |
int counter; |
int exponent,exponenttmp; |
142,69 → 206,7 |
return; |
} |
/** Print NULL terminated string |
* |
* Print characters from str using putchar() until |
* \\0 character is reached. |
* |
* @param str Characters to print. |
* |
*/ |
void print_str(const char *str) |
{ |
int i = 0; |
char c; |
while (c = str[i++]) |
putchar(c); |
} |
/** Print hexadecimal digits |
* |
* Print fixed count of hexadecimal digits from |
* the number num. The digits are printed in |
* natural left-to-right order starting with |
* the width-th digit. |
* |
* @param num Number containing digits. |
* @param width Count of digits to print. |
* |
*/ |
void print_fixed_hex(const __u64 num, const int width) |
{ |
int i; |
for (i = width*8 - 4; i >= 0; i -= 4) |
putchar(digits[(num>>i) & 0xf]); |
} |
/** Print number in given base |
* |
* Print significant digits of a number in given |
* base. |
* |
* @param num Number to print. |
* @param base Base to print the number in (should |
* be in range 2 .. 16). |
* |
*/ |
void print_number(const __native num, const unsigned int base) |
{ |
int val = num; |
char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */ |
int i = sizeof(__native)*8-1; |
do { |
d[i--] = digits[val % base]; |
} while (val /= base); |
d[sizeof(__native)*8] = 0; |
print_str(&d[i + 1]); |
} |
/** General formatted text print |
* |
* Print text formatted according the fmt parameter |