1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
#include "test.h"
#include "utils/fluid_sys.h"
// test threading, conditions, thread private data and atomics
#define THREAD_COUNT 10
#define INCREMENT_COUNT 10000
struct increment_data {
fluid_cond_mutex_t *mutex;
fluid_cond_t *condition;
fluid_private_t local;
int ready;
int done;
int regular;
int atomic;
};
static fluid_thread_return_t increment(void *_data)
{
int i;
char *original = NULL;
char *pointer = NULL;
struct increment_data *data = (struct increment_data *)_data;
TEST_ASSERT(fluid_private_get(data->local) == NULL);
fluid_cond_mutex_lock(data->mutex);
data->ready++;
fluid_cond_broadcast(data->condition);
while (data->ready != THREAD_COUNT)
{
fluid_cond_wait(data->condition, data->mutex);
}
fluid_cond_mutex_unlock(data->mutex);
for (i = 0; i < INCREMENT_COUNT; i++)
{
data->regular++;
fluid_atomic_int_inc(&data->atomic);
pointer = fluid_private_get(data->local);
fluid_private_set(data->local, pointer + 1);
}
fluid_cond_mutex_lock(data->mutex);
data->done++;
fluid_cond_broadcast(data->condition);
while (data->done != THREAD_COUNT)
{
fluid_cond_wait(data->condition, data->mutex);
}
fluid_cond_mutex_unlock(data->mutex);
pointer = fluid_private_get(data->local);
TEST_ASSERT(pointer - original == INCREMENT_COUNT);
return FLUID_THREAD_RETURN_VALUE;
}
void test_atomic_inc(void)
{
int i;
fluid_thread_t *threads[THREAD_COUNT];
struct increment_data data;
data.mutex = new_fluid_cond_mutex();
TEST_ASSERT(data.mutex != NULL);
data.condition = new_fluid_cond();
TEST_ASSERT(data.condition != NULL);
fluid_private_init(data.local);
data.ready = 0;
data.done = 0;
data.regular = 0;
data.atomic = 0;
for (i = 0; i < THREAD_COUNT; i++)
{
threads[i] = new_fluid_thread("increment", increment, &data, 0, FALSE);
}
for (i = 0; i < THREAD_COUNT; i++)
{
fluid_thread_join(threads[i]);
delete_fluid_thread(threads[i]);
}
FLUID_LOG(FLUID_INFO, "incremented %d regular vs. %d atomic", data.regular, data.atomic);
TEST_ASSERT(data.atomic == THREAD_COUNT * INCREMENT_COUNT);
fluid_private_free(data.local);
delete_fluid_cond(data.condition);
delete_fluid_cond_mutex(data.mutex);
}
int main(void)
{
test_atomic_inc();
return EXIT_SUCCESS;
}
|