Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 451 → Rev 452

//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