352 lines
7.1 KiB
C
352 lines
7.1 KiB
C
#include "ks.h"
|
|
#include "tap.h"
|
|
#define MAX_STUFF 200
|
|
|
|
static ks_thread_t *threads[MAX_STUFF];
|
|
static ks_thread_t *thread_p;
|
|
|
|
static ks_pool_t *pool;
|
|
static ks_mutex_t *mutex;
|
|
static ks_mutex_t *mutex_non_recursive;
|
|
static ks_rwl_t *rwlock;
|
|
static ks_cond_t *cond;
|
|
static int counter1 = 0;
|
|
static int counter2 = 0;
|
|
static int counter3 = 0;
|
|
static int counter4 = 0;
|
|
static int counter5 = 0;
|
|
static int counter6 = 0;
|
|
static int threadscount = 0;
|
|
static int cpu_count = 0;
|
|
|
|
#define LOOP_COUNT 10000
|
|
|
|
static void *thread_priority(ks_thread_t *thread, void *data)
|
|
{
|
|
while (thread->running) {
|
|
ks_sleep(1000000);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void *thread_test_cond_producer_func(ks_thread_t *thread, void *data)
|
|
{
|
|
for (;;) {
|
|
ks_cond_lock(cond);
|
|
if (counter5 >= LOOP_COUNT) {
|
|
ks_cond_unlock(cond);
|
|
break;
|
|
}
|
|
counter5++;
|
|
if (counter6 == 0) {
|
|
ks_cond_signal(cond);
|
|
}
|
|
counter6++;
|
|
ks_cond_unlock(cond);
|
|
*((int *) data) += 1;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void *thread_test_cond_consumer_func(ks_thread_t *thread, void *data)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < LOOP_COUNT; i++) {
|
|
ks_cond_lock(cond);
|
|
while (counter6 == 0) {
|
|
ks_cond_wait(cond);
|
|
}
|
|
counter6--;
|
|
ks_cond_unlock(cond);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void check_cond(void)
|
|
{
|
|
int count[MAX_STUFF] = { 0 };
|
|
int ttl = 0;
|
|
|
|
ok( (ks_pool_open(&pool) == KS_STATUS_SUCCESS) );
|
|
ok( (ks_cond_create(&cond, pool) == KS_STATUS_SUCCESS) );
|
|
|
|
int i;
|
|
for(i = 0; i < cpu_count; i++) {
|
|
ok( (ks_thread_create(&threads[i], thread_test_cond_producer_func, &count[i], pool) == KS_STATUS_SUCCESS) );
|
|
}
|
|
ok( (ks_thread_create(&thread_p, thread_test_cond_consumer_func, NULL, pool) == KS_STATUS_SUCCESS) );
|
|
ok( (ks_pool_close(&pool) == KS_STATUS_SUCCESS) );
|
|
for(i = 0; i < cpu_count; i++) {
|
|
ttl += count[i];
|
|
}
|
|
|
|
ok( (ttl == LOOP_COUNT) );
|
|
}
|
|
|
|
|
|
static void *thread_test_rwlock_func(ks_thread_t *thread, void *data)
|
|
{
|
|
int loop = 1;
|
|
|
|
while (1)
|
|
{
|
|
ks_rwl_read_lock(rwlock);
|
|
if (counter4 == LOOP_COUNT) {
|
|
loop = 0;
|
|
}
|
|
ks_rwl_read_unlock(rwlock);
|
|
|
|
if (!loop) {
|
|
break;
|
|
}
|
|
|
|
ks_rwl_write_lock(rwlock);
|
|
if (counter4 != LOOP_COUNT) {
|
|
counter4++;
|
|
}
|
|
ks_rwl_write_unlock(rwlock);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void check_rwl(void)
|
|
{
|
|
ks_status_t status;
|
|
|
|
ok( (ks_pool_open(&pool) == KS_STATUS_SUCCESS) );
|
|
ok( (ks_rwl_create(&rwlock, pool) == KS_STATUS_SUCCESS) );
|
|
ks_rwl_read_lock(rwlock);
|
|
status = ks_rwl_try_read_lock(rwlock);
|
|
ok( status == KS_STATUS_SUCCESS );
|
|
if ( status == KS_STATUS_SUCCESS ) {
|
|
ks_rwl_read_unlock(rwlock);
|
|
}
|
|
ks_rwl_read_unlock(rwlock);
|
|
|
|
int i;
|
|
for(i = 0; i < cpu_count; i++) {
|
|
ok( (ks_thread_create(&threads[i], thread_test_rwlock_func, NULL, pool) == KS_STATUS_SUCCESS) );
|
|
}
|
|
|
|
|
|
for(i = 0; i < cpu_count; i++) {
|
|
ks_thread_join(threads[i]);
|
|
}
|
|
|
|
ok( (ks_pool_close(&pool) == KS_STATUS_SUCCESS) );
|
|
ok( (counter4 == LOOP_COUNT) );
|
|
|
|
}
|
|
|
|
static void *thread_test_function_cleanup(ks_thread_t *thread, void *data)
|
|
{
|
|
int d = (int)(intptr_t)data;
|
|
|
|
while (thread->running) {
|
|
ks_sleep(1000000);
|
|
}
|
|
|
|
if ( d == 1 ) {
|
|
ks_mutex_lock(mutex);
|
|
counter3++;
|
|
ks_mutex_unlock(mutex);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void *thread_test_function_detatched(ks_thread_t *thread, void *data)
|
|
{
|
|
int i;
|
|
int d = (int)(intptr_t)data;
|
|
|
|
for (i = 0; i < LOOP_COUNT; i++) {
|
|
ks_mutex_lock(mutex);
|
|
if (d == 1) {
|
|
counter2++;
|
|
}
|
|
ks_mutex_unlock(mutex);
|
|
}
|
|
ks_mutex_lock(mutex);
|
|
threadscount++;
|
|
ks_mutex_unlock(mutex);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void *thread_test_function_atatched(ks_thread_t *thread, void *data)
|
|
{
|
|
int i;
|
|
int d = (int)(intptr_t)data;
|
|
void *mem, *last_mem = NULL;
|
|
|
|
for (i = 0; i < LOOP_COUNT; i++) {
|
|
if (last_mem) {
|
|
ks_pool_free(thread->pool, &last_mem);
|
|
}
|
|
mem = ks_pool_alloc(thread->pool, 1024);
|
|
last_mem = mem;
|
|
}
|
|
|
|
for (i = 0; i < LOOP_COUNT; i++) {
|
|
ks_mutex_lock(mutex);
|
|
if (d == 1) {
|
|
counter1++;
|
|
}
|
|
ks_mutex_unlock(mutex);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void create_threads_cleanup(void)
|
|
{
|
|
void *d = (void *)(intptr_t)1;
|
|
int i;
|
|
for(i = 0; i < cpu_count; i++) {
|
|
ok( (ks_thread_create(&threads[i], thread_test_function_cleanup, d, pool) == KS_STATUS_SUCCESS) );
|
|
}
|
|
|
|
}
|
|
|
|
static void create_threads_atatched(void)
|
|
{
|
|
void *d = (void *)(intptr_t)1;
|
|
|
|
int i;
|
|
for(i = 0; i < cpu_count; i++) {
|
|
ok( (ks_thread_create(&threads[i], thread_test_function_atatched, d, pool) == KS_STATUS_SUCCESS) );
|
|
}
|
|
}
|
|
|
|
static void create_threads_detatched(void)
|
|
{
|
|
ks_status_t status;
|
|
void *d = (void *)(intptr_t)1;
|
|
|
|
int i;
|
|
for(i = 0; i < cpu_count; i++) {
|
|
status = ks_thread_create_ex(&threads[i], thread_test_function_detatched, d, KS_THREAD_FLAG_DETATCHED, KS_THREAD_DEFAULT_STACK, KS_PRI_NORMAL, pool);
|
|
ok( status == KS_STATUS_SUCCESS );
|
|
}
|
|
}
|
|
|
|
static void check_thread_priority(void)
|
|
{
|
|
ks_status_t status;
|
|
void *d = (void *)(intptr_t)1;
|
|
|
|
status = ks_thread_create_ex(&thread_p, thread_priority, d, KS_THREAD_FLAG_DETATCHED, KS_THREAD_DEFAULT_STACK, KS_PRI_IMPORTANT, pool);
|
|
ok( status == KS_STATUS_SUCCESS );
|
|
ks_sleep(1000000);
|
|
todo("Add check to see if has permission to set thread priority\n");
|
|
ok( ks_thread_priority(thread_p) == KS_PRI_IMPORTANT );
|
|
end_todo;
|
|
|
|
ks_pool_free(pool, &thread_p);
|
|
}
|
|
|
|
static void join_threads(void)
|
|
{
|
|
int i;
|
|
for(i = 0; i < cpu_count; i++) {
|
|
ok( (KS_STATUS_SUCCESS == ks_thread_join(threads[i])) );
|
|
}
|
|
}
|
|
|
|
static void check_atatched(void)
|
|
{
|
|
ok( counter1 == (LOOP_COUNT * cpu_count) );
|
|
}
|
|
|
|
static void check_detached(void)
|
|
{
|
|
ok( counter2 == (LOOP_COUNT * cpu_count) );
|
|
}
|
|
|
|
static void create_pool(void)
|
|
{
|
|
ok( (ks_pool_open(&pool) == KS_STATUS_SUCCESS) );
|
|
}
|
|
|
|
static void check_cleanup(void)
|
|
{
|
|
ok( (counter3 == cpu_count) );
|
|
}
|
|
|
|
static void check_pool_close(void)
|
|
{
|
|
ok( (ks_pool_close(&pool) == KS_STATUS_SUCCESS) );
|
|
}
|
|
|
|
static void create_mutex(void)
|
|
{
|
|
ok( (ks_mutex_create(&mutex, KS_MUTEX_FLAG_DEFAULT, pool) == KS_STATUS_SUCCESS) );
|
|
}
|
|
|
|
static void create_mutex_non_recursive(void)
|
|
{
|
|
ok( (ks_mutex_create(&mutex_non_recursive, KS_MUTEX_FLAG_NON_RECURSIVE, pool) == KS_STATUS_SUCCESS) );
|
|
}
|
|
|
|
static void test_recursive_mutex(void)
|
|
{
|
|
ks_status_t status;
|
|
|
|
ks_mutex_lock(mutex);
|
|
status = ks_mutex_trylock(mutex);
|
|
if (status == KS_STATUS_SUCCESS) {
|
|
ks_mutex_unlock(mutex);
|
|
}
|
|
ok(status == KS_STATUS_SUCCESS);
|
|
ks_mutex_unlock(mutex);
|
|
}
|
|
|
|
static void test_non_recursive_mutex(void)
|
|
{
|
|
ks_status_t status;
|
|
ks_mutex_lock(mutex_non_recursive);
|
|
status = ks_mutex_trylock(mutex_non_recursive);
|
|
if (status == KS_STATUS_SUCCESS) {
|
|
ks_mutex_unlock(mutex_non_recursive);
|
|
}
|
|
ok(status != KS_STATUS_SUCCESS);
|
|
ks_mutex_unlock(mutex_non_recursive);
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
ks_init();
|
|
cpu_count = ks_cpu_count() * 4;
|
|
|
|
plan(21 + cpu_count * 6);
|
|
|
|
|
|
diag("Starting testing for %d tests\n", 44);
|
|
|
|
create_pool();
|
|
create_mutex();
|
|
create_mutex_non_recursive();
|
|
test_recursive_mutex();
|
|
test_non_recursive_mutex();
|
|
check_thread_priority();
|
|
create_threads_atatched();
|
|
join_threads();
|
|
check_atatched();
|
|
create_threads_detatched();
|
|
while (threadscount != cpu_count) ks_sleep(1000000);
|
|
check_detached();
|
|
create_threads_cleanup();
|
|
check_pool_close();
|
|
check_cleanup();
|
|
check_rwl();
|
|
check_cond();
|
|
|
|
ks_shutdown();
|
|
done_testing();
|
|
}
|