47 |
; |
; |
48 |
} |
} |
49 |
|
|
|
static struct thread_lock simple_lock; |
|
|
|
|
|
static void |
|
|
tm_fn (void *arg) |
|
|
{ |
|
|
extern unsigned int timestamp_count; |
|
|
|
|
|
trace_printf ("tm fn arg %p %d", arg, timestamp_count); |
|
|
} |
|
|
|
|
|
static void |
|
|
test_fn (void *aux) |
|
|
{ |
|
|
#if 0 |
|
|
extern unsigned int timestamp_count; |
|
|
struct thread *thread = THREAD_CURRENT (); |
|
|
bool err; |
|
|
int i; |
|
|
unsigned int now; |
|
|
|
|
|
trace_printf ("starting thread %d", (int) thread->scratch_area [3]); |
|
|
|
|
|
for (;;) |
|
|
{ |
|
|
trace_printf ("thread %d trying lock", (int) thread->scratch_area [3]); |
|
|
|
|
|
now = timestamp_count; |
|
|
thread_lock_write (&simple_lock); |
|
|
|
|
|
trace_printf ("thread %d got lock (%d)", (int) thread->scratch_area [3], |
|
|
(timestamp_count - now)); |
|
|
|
|
|
for (i = 0; i < 6000000; i++) |
|
|
; |
|
|
|
|
|
|
|
|
trace_printf ("thread %d unlock", (int) thread->scratch_area [3]); |
|
|
thread_lock_unlock (&simple_lock); |
|
|
|
|
|
for (i = 0; i < 600000; i++) |
|
|
; |
|
|
|
|
|
|
|
|
#if 0 |
|
|
thread_lock_read (&simple_lock); |
|
|
|
|
|
for (i = 0; i < 600000; i++) |
|
|
; |
|
|
|
|
|
err = thread_lock_read_to_write (&simple_lock); |
|
|
if (err == true) |
|
|
trace_printf ("thread %d failed upgrading lock", (int) thread->scratch_area [3]); |
|
|
else |
|
|
trace_printf ("thread %d upgraded lock", (int) thread->scratch_area [3]); |
|
|
|
|
|
for (i = 0; i < 600000; i++) |
|
|
; |
|
|
|
|
|
if (err == false) |
|
|
{ |
|
|
trace_printf ("thread %d downgrading lock", (int) thread->scratch_area [3]); |
|
|
thread_lock_write_to_read (&simple_lock); |
|
|
|
|
|
for (i = 0; i < 60000; i++) |
|
|
; |
|
|
} |
|
|
|
|
|
thread_lock_unlock (&simple_lock); |
|
|
|
|
|
for (i = 0; i < 600000; i++) |
|
|
; |
|
|
#endif |
|
|
} |
|
|
#else |
|
|
timeout (10*2000, tm_fn, 0xdeadbeef); |
|
|
for (;;) |
|
|
; |
|
|
#endif |
|
|
} |
|
|
|
|
|
struct thread_lock lock_a, lock_b; |
|
|
struct thread_lock mutex; |
|
|
|
|
|
volatile int mid_test = 0; |
|
|
|
|
|
void |
|
|
low_prio_thread (void *arg) |
|
|
{ |
|
|
int i; |
|
|
|
|
|
for (i = 0; i < 11000; i++) |
|
|
{ |
|
|
mid_test = 1; |
|
|
|
|
|
thread_lock_write (&mutex); |
|
|
thread_lock_unlock (&lock_b); |
|
|
|
|
|
outb (0x9000, 0); |
|
|
|
|
|
thread_lock_unlock (&mutex); |
|
|
} |
|
|
} |
|
|
|
|
|
void |
|
|
middle_prio_thread (void *arg) |
|
|
{ |
|
|
for (;;) |
|
|
{ |
|
|
thread_lock_write (&lock_b); |
|
|
thread_lock_unlock (&lock_a); |
|
|
|
|
|
while (mid_test) |
|
|
; |
|
|
} |
|
|
} |
|
|
|
|
|
void |
|
|
high_prio_thread (void *arg) |
|
|
{ |
|
|
for (;;) |
|
|
{ |
|
|
thread_lock_write (&lock_a); |
|
|
outb (0x9000, 1); |
|
|
|
|
|
thread_lock_write (&mutex); |
|
|
|
|
|
outb (0x9000, 2); |
|
|
|
|
|
mid_test = 0; |
|
|
thread_lock_unlock (&mutex); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
/* Copyright string. */ |
/* Copyright string. */ |
51 |
|
|
52 |
static char copyright_string [] = |
static char copyright_string [] = |
59 |
void |
void |
60 |
init_main (void) |
init_main (void) |
61 |
{ |
{ |
62 |
struct thread *launch_thread, *threads[5]; |
struct thread *launch_thread; |
63 |
int err, i; |
int err; |
64 |
|
|
65 |
/* Print version information and copyright string. */ |
/* Print version information and copyright string. */ |
66 |
|
|
70 |
callout_init (); |
callout_init (); |
71 |
|
|
72 |
/* Initialize bootstrap. */ |
/* Initialize bootstrap. */ |
73 |
#if 0 |
|
74 |
bootstrap_init (); |
bootstrap_init (); |
75 |
|
|
76 |
/* Create the launch thread and start it. */ |
/* Create the launch thread and start it. */ |
79 |
assert (err == KERN_SUCCESS); |
assert (err == KERN_SUCCESS); |
80 |
thread_start (launch_thread, launch_the_system, 0); |
thread_start (launch_thread, launch_the_system, 0); |
81 |
|
|
|
LOAD_CONTEXT (launch_thread); |
|
|
#else |
|
|
thread_lock_init (&simple_lock, true, false); |
|
|
|
|
|
thread_lock_init (&mutex, true, true); |
|
|
thread_lock_init (&lock_a, true, false); |
|
|
thread_lock_init (&lock_b, true, false); |
|
|
|
|
|
err = thread_create (TASK_KERNEL (), &launch_thread); |
|
|
assert (err == KERN_SUCCESS); |
|
|
launch_thread->scratch_area[3] = 777; |
|
|
thread_start (launch_thread, launch_the_system, 0); |
|
|
|
|
|
for (i = 0; i < 3; i++) |
|
|
{ |
|
|
err = thread_create (TASK_KERNEL (), &threads [i]); |
|
|
assert (err == KERN_SUCCESS); |
|
|
|
|
|
threads[i]->scratch_area[3] = (void *) i + 10; |
|
|
|
|
|
thread_set_priority (threads[i], THREAD_POLICY_FIFO, 20+i*20); |
|
|
|
|
|
if (i == 0) |
|
|
thread_start (threads[i], low_prio_thread, 0); |
|
|
else if (i == 1) |
|
|
thread_start (threads[i], middle_prio_thread, 0); |
|
|
else if (i == 2) |
|
|
thread_start (threads[i], high_prio_thread, 0); |
|
|
|
|
|
thread_setrun (threads[i], false); |
|
|
} |
|
|
|
|
|
thread_lock_write (&lock_a); |
|
|
thread_lock_write (&lock_b); |
|
|
#endif |
|
|
|
|
82 |
thread_system_running = true; |
thread_system_running = true; |
83 |
LOAD_CONTEXT (launch_thread); |
LOAD_CONTEXT (launch_thread); |
84 |
} |
} |