File: test_threading.c

package info (click to toggle)
fluidsynth 2.5.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,292 kB
  • sloc: ansic: 45,503; cpp: 4,974; xml: 877; sh: 200; makefile: 74
file content (107 lines) | stat: -rw-r--r-- 2,482 bytes parent folder | download
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;
}