OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [conts/] [test_suite0/] [src/] [api/] [mutex.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Test l4_mutex_control system call.
3
 *
4
 * Copyright (C) 2010 B Labs Ltd.
5
 *
6
 * Author: Bahadir Balban
7
 */
8
 
9
#include <l4lib/macros.h>
10
#include L4LIB_INC_ARCH(syslib.h)
11
#include L4LIB_INC_ARCH(syscalls.h)
12
#include <l4lib/lib/thread.h>
13
#include <l4lib/mutex.h>
14
#include <tests.h>
15
 
16
#define MUTEX_NTHREADS                  8
17
#define MUTEX_INCREMENTS                200
18
#define MUTEX_VALUE_TOTAL               (MUTEX_NTHREADS * MUTEX_INCREMENTS)
19
 
20
struct mutex_test_data {
21
        struct l4_mutex lock;
22
        int val;
23
};
24
 
25
static struct mutex_test_data tdata;
26
 
27
static void init_test_data(struct mutex_test_data *tdata)
28
{
29
        l4_mutex_init(&tdata->lock);
30
        tdata->val = 0;
31
}
32
 
33
 
34
int mutex_thread_non_contending(void *arg)
35
{
36
        struct mutex_test_data *data =
37
                (struct mutex_test_data *)arg;
38
        l4id_t tid = self_tid();
39
        int err = tid;
40
 
41
        for (int i = 0; i < MUTEX_INCREMENTS; i++) {
42
                /* Lock the data structure */
43
                if ((err = l4_mutex_lock(&data->lock)) < 0) {
44
                        dbg_printf("Thread %d: Acquiring mutex failed. "
45
                                   "err = %d\n", tid, err);
46
                        return -err;
47
                }
48
 
49
                /*
50
                 * Increment and release lock
51
                 */
52
                data->val++;
53
 
54
                /* Unlock the data structure */
55
                if ((err = l4_mutex_unlock(&data->lock)) < 0) {
56
                        dbg_printf("Thread %d: Releasing the mutex failed. "
57
                                   "err = %d\n", tid, err);
58
                        return -err;
59
                }
60
        }
61
 
62
        return 0;
63
}
64
 
65
 
66
 
67
int mutex_thread_contending(void *arg)
68
{
69
        struct mutex_test_data *data =
70
                (struct mutex_test_data *)arg;
71
        l4id_t tid = self_tid();
72
        int err = tid;
73
 
74
        for (int i = 0; i < MUTEX_INCREMENTS; i++) {
75
                /* Lock the data structure */
76
                if ((err = l4_mutex_lock(&data->lock)) < 0) {
77
                        dbg_printf("Thread %d: Acquiring mutex failed. "
78
                                   "err = %d\n", tid, err);
79
                        return -err;
80
                }
81
 
82
                /*
83
                 * Sleep some time to have some
84
                 * threads blocked on the mutex
85
                 */
86
                for (int j = 0; j < 3; j++)
87
                        l4_thread_switch(0);
88
 
89
                /*
90
                 * Increment and release lock
91
                 */
92
                data->val++;
93
 
94
                /* Unlock the data structure */
95
                if ((err = l4_mutex_unlock(&data->lock)) < 0) {
96
                        dbg_printf("Thread %d: Releasing the mutex failed. "
97
                                   "err = %d\n", tid, err);
98
                        return -err;
99
                }
100
        }
101
 
102
        return 0;
103
}
104
 
105
 
106
int test_mutex(int (*mutex_thread)(void *))
107
{
108
        struct l4_thread *thread[MUTEX_NTHREADS];
109
        int err;
110
 
111
        /* Init mutex data */
112
        init_test_data(&tdata);
113
 
114
        /*
115
         * Lock the mutex so nobody starts working
116
         */
117
        if ((err = l4_mutex_lock(&tdata.lock)) < 0) {
118
                dbg_printf("Acquiring mutex failed. "
119
                           "err = %d\n", err);
120
                return err;
121
        }
122
 
123
        /* Create threads */
124
        for (int i = 0; i < MUTEX_NTHREADS; i++) {
125
                if ((err = thread_create(mutex_thread,
126
                                         &tdata,
127
                                         TC_SHARE_SPACE,
128
                                         &thread[i])) < 0) {
129
                        dbg_printf("Thread create failed. "
130
                                   "err=%d\n", err);
131
                        return err;
132
                }
133
        }
134
 
135
        /* Unlock the mutex and initiate all workers */
136
        if ((err = l4_mutex_unlock(&tdata.lock)) < 0) {
137
                dbg_printf("Releasing the mutex failed. "
138
                           "err = %d\n", err);
139
                return -err;
140
        }
141
 
142
        /*
143
         * Wait for all threads to exit successfully
144
         */
145
        for (int i = 0; i < MUTEX_NTHREADS; i++) {
146
                if ((err = thread_wait(thread[i])) < 0) {
147
                        dbg_printf("THREAD_WAIT failed. "
148
                                   "err=%d\n", err);
149
                        return err;
150
                }
151
        }
152
 
153
        /*
154
         * Test that lock is in correct state
155
         */
156
        if (tdata.lock.lock != L4_MUTEX_UNLOCKED) {
157
                dbg_printf("MUTEX is not in unlocked condition "
158
                           "after tests. lockval = %d, expected = %d\n",
159
                           tdata.lock.lock, L4_MUTEX_UNLOCKED);
160
                return -1;
161
        }
162
 
163
        /*
164
         * Test that increments have occured correctly
165
         */
166
        if (tdata.val != MUTEX_VALUE_TOTAL) {
167
                dbg_printf("Lock-protected value incremented incorrectly "
168
                           "after mutex worker threads.\n"
169
                           "val = %d, expected = %d\n",
170
                           tdata.val,
171
                           MUTEX_VALUE_TOTAL);
172
                return -1;
173
        }
174
        if (tdata.val != MUTEX_VALUE_TOTAL) {
175
                dbg_printf("Lock-protected value incremented incorrectly "
176
                           "after mutex worker threads.\n"
177
                           "val = %d, expected = %d\n",
178
                           tdata.val,
179
                           MUTEX_VALUE_TOTAL);
180
                return -1;
181
        }
182
 
183
        dbg_printf("Mutex test successful.\n");
184
        return 0;
185
}
186
 
187
int test_api_mutexctrl(void)
188
{
189
        int err;
190
 
191
        if ((err = test_mutex(mutex_thread_contending)) < 0)
192
                goto out_err;
193
 
194
        if ((err = test_mutex(mutex_thread_non_contending)) < 0)
195
                goto out_err;
196
 
197
        printf("USERSPACE MUTEX:               -- PASSED --\n");
198
        return 0;
199
 
200
out_err:
201
        printf("USERSPACE MUTEX:               -- FAILED --\n");
202
        return err;
203
}
204
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.