[merge] merge back from smp branch
This commit is contained in:
@@ -41,12 +41,15 @@ static int fibo_thread(void *argv)
|
||||
if (fibo == 1)
|
||||
return 1;
|
||||
|
||||
t[0] = thread_create("fibo", &fibo_thread, (void *)(fibo - 1), DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "fibo %lu", fibo - 1);
|
||||
t[0] = thread_create(name, &fibo_thread, (void *)(fibo - 1), DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
|
||||
if (!t[0]) {
|
||||
printf("error creating thread for fibo %d\n", fibo-1);
|
||||
return 0;
|
||||
}
|
||||
t[1] = thread_create("fibo", &fibo_thread, (void *)(fibo - 2), DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
|
||||
snprintf(name, sizeof(name), "fibo %lu", fibo - 2);
|
||||
t[1] = thread_create(name, &fibo_thread, (void *)(fibo - 2), DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
|
||||
if (!t[1]) {
|
||||
printf("error creating thread for fibo %d\n", fibo-2);
|
||||
thread_resume(t[0]);
|
||||
@@ -89,4 +92,5 @@ int fibo(int argc, const cmd_args *argv)
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
// vim: set noexpandtab:
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ void clock_tests(void);
|
||||
void float_tests(void);
|
||||
void benchmarks(void);
|
||||
int fibo(int argc, const cmd_args *argv);
|
||||
int spinner(int argc, const cmd_args *argv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ STATIC_COMMAND("float_tests", "floating point test", (console_cmd)&float_tests)
|
||||
#endif
|
||||
STATIC_COMMAND("bench", "miscellaneous benchmarks", (console_cmd)&benchmarks)
|
||||
STATIC_COMMAND("fibo", "threaded fibonacci", (console_cmd)&fibo)
|
||||
STATIC_COMMAND("spinner", "create a spinning thread", (console_cmd)&spinner)
|
||||
STATIC_COMMAND_END(tests);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <trace.h>
|
||||
#include <rand.h>
|
||||
#include <err.h>
|
||||
#include <assert.h>
|
||||
#include <app/tests.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/mutex.h>
|
||||
@@ -130,7 +131,7 @@ static int semaphore_test(void)
|
||||
static int mutex_thread(void *arg)
|
||||
{
|
||||
int i;
|
||||
const int iterations = 50000;
|
||||
const int iterations = 1000000;
|
||||
|
||||
static volatile int shared = 0;
|
||||
|
||||
@@ -405,9 +406,11 @@ static int atomic_tester(void *arg)
|
||||
int add = (intptr_t)arg;
|
||||
int i;
|
||||
|
||||
TRACEF("add %d\n", add);
|
||||
const int iter = 10000000;
|
||||
|
||||
for (i=0; i < 1000000; i++) {
|
||||
TRACEF("add %d, %d iterations\n", add, iter);
|
||||
|
||||
for (i=0; i < iter; i++) {
|
||||
atomic_add(&atomic, add);
|
||||
}
|
||||
|
||||
@@ -455,6 +458,7 @@ static int preempt_tester(void *arg)
|
||||
printf("exiting ts %lld\n", current_time_hires());
|
||||
|
||||
atomic_add(&preempt_count, -1);
|
||||
#undef COUNT
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -571,12 +575,53 @@ static void join_test(void)
|
||||
printf("thread_join returns err %d, retval %d (should be 0 and 55)\n", err, ret);
|
||||
}
|
||||
|
||||
static void spinlock_test(void)
|
||||
{
|
||||
spin_lock_saved_state_t state;
|
||||
spin_lock_t lock;
|
||||
|
||||
spin_lock_init(&lock);
|
||||
|
||||
// verify basic functionality (single core)
|
||||
printf("testing spinlock:\n");
|
||||
ASSERT(!spin_lock_held(&lock));
|
||||
ASSERT(!arch_ints_disabled());
|
||||
spin_lock_irqsave(&lock, state);
|
||||
ASSERT(arch_ints_disabled());
|
||||
ASSERT(spin_lock_held(&lock));
|
||||
spin_unlock_irqrestore(&lock, state);
|
||||
ASSERT(!spin_lock_held(&lock));
|
||||
ASSERT(!arch_ints_disabled());
|
||||
printf("seems to work\n");
|
||||
|
||||
#define COUNT (1024*1024)
|
||||
uint32_t c = arch_cycle_count();
|
||||
for (uint i = 0; i < COUNT; i++) {
|
||||
spin_lock(&lock);
|
||||
spin_unlock(&lock);
|
||||
}
|
||||
c = arch_cycle_count() - c;
|
||||
|
||||
printf("%u cycles to acquire/release lock %u times (%u cycles per)\n", c, COUNT, c / COUNT);
|
||||
|
||||
c = arch_cycle_count();
|
||||
for (uint i = 0; i < COUNT; i++) {
|
||||
spin_lock_irqsave(&lock, state);
|
||||
spin_unlock_irqrestore(&lock, state);
|
||||
}
|
||||
c = arch_cycle_count() - c;
|
||||
|
||||
printf("%u cycles to acquire/release lock w/irqsave %u times (%u cycles per)\n", c, COUNT, c / COUNT);
|
||||
#undef COUNT
|
||||
}
|
||||
|
||||
int thread_tests(void)
|
||||
{
|
||||
mutex_test();
|
||||
semaphore_test();
|
||||
event_test();
|
||||
|
||||
spinlock_test();
|
||||
atomic_test();
|
||||
|
||||
thread_sleep(200);
|
||||
@@ -589,4 +634,27 @@ int thread_tests(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spinner_thread(void *arg)
|
||||
{
|
||||
for (;;)
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spinner(int argc, const cmd_args *argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("not enough args\n");
|
||||
printf("usage: %s <priority>\n", argv[0].str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
thread_t *t = thread_create("spinner", spinner_thread, NULL, argv[1].u, DEFAULT_STACK_SIZE);
|
||||
if (t)
|
||||
thread_resume(t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 noexpandtab: */
|
||||
|
||||
Reference in New Issue
Block a user