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

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [conts/] [posix/] [test0/] [src/] [mutextest.c] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Tests for userspace mutexes
3
 *
4
 * Copyright (C) 2007-2009 Bahadir Bilgehan Balban
5
 */
6
#include <l4lib/ipcdefs.h>
7
#include <l4lib/mutex.h>
8
#include <errno.h>
9
#include <sys/mman.h>
10
#include <sys/types.h>
11
#include <unistd.h>
12
#include <tests.h>
13
#include <capability.h>
14
 
15
/*
16
 * This structure is placed at the head of shared memory.
17
 * Tasks lock and write to rest of the page. Indicate that
18
 * they have run, and the later running task tests that both
19
 * processes has run and no data corruption occured on page_rest.
20
 */
21
struct shared_page {
22
        struct l4_mutex mutex;
23
        int shared_var;
24
};
25
 
26
static struct shared_page *shared_page;
27
 
28
/*
29
 * This test forks a parent task, creates a shared memory mapping, and makes two tasks
30
 * lock and write to almost the whole page 10 times with different values, and makes
31
 * the tasks test that the writes are all there without any wrong values. The amount of
32
 * time spent should justify a context switch and demonstrate that lock protects the
33
 * region.
34
 */
35
int user_mutex_test(void)
36
{
37
        pid_t child, parent;
38
        int map_size = PAGE_SIZE;
39
        struct capability cap;
40
        void *base;
41
        int err;
42
 
43
        /* Get parent pid */
44
        parent = getpid();
45
 
46
 
47
        /*
48
         * Create a shared anonymous memory region. This can be
49
         * accessed by both parent and child after a fork.
50
         */
51
        if (IS_ERR(base = mmap(0, map_size, PROT_READ | PROT_WRITE,
52
                              MAP_SHARED | MAP_ANONYMOUS, 0, 0))) {
53
                printf("%s: mmap for extended ipc buffer failed: %x\n",
54
                            __FUNCTION__, (int)base);
55
                goto out_err;
56
        } else
57
                test_printf("mmap: Anonymous shared buffer at %p\n", base);
58
 
59
        shared_page = base;
60
 
61
        /* Initialize the mutex */
62
        l4_mutex_init(&shared_page->mutex);
63
 
64
        /* Initialize the shared variable */
65
        shared_page->shared_var = 0;
66
 
67
        /* Fork the current task */
68
        if ((child = fork()) < 0) {
69
                test_printf("%s: Fork failed with %d\n", __FUNCTION__, errno);
70
                goto out_err;
71
        }
72
 
73
        if (child)
74
                test_printf("%d: Created child with pid %d\n", getpid(), child);
75
        else
76
                test_printf("Child %d running.\n", getpid());
77
 
78
        /*
79
         * Request capability to ipc to each other from pager
80
         * (Actually only the sender needs it)
81
         */
82
        memset(&cap, 0, sizeof(cap));
83
        if (child) {
84
                cap.owner = parent;
85
                cap.resid = child;
86
        } else {
87
                cap.owner = getpid();
88
                cap.resid = parent;
89
        }
90
 
91
        cap.type = CAP_TYPE_IPC | CAP_RTYPE_THREAD;
92
        cap.access = CAP_IPC_SHORT | CAP_IPC_SEND | CAP_IPC_RECV;
93
        if ((err = cap_request_pager(&cap)) < 0) {
94
                printf("Ipc capability request failed. "
95
                       "err = %d\n", err);
96
                goto out_err;
97
        }
98
 
99
        /* Child locks and produces */
100
        if (child == 0) {
101
 
102
                for (int x = 0; x < 2000; x++) {
103
                        int temp;
104
 
105
                        /* Lock page */
106
        //              test_printf("Child locking page.\n");
107
                        l4_mutex_lock(&shared_page->mutex);
108
 
109
                        /* Read variable */
110
        //              test_printf("Child locked page.\n");
111
                        temp = shared_page->shared_var;
112
 
113
                        /* Update local copy */
114
                        temp++;
115
 
116
                        /* Thread switch */
117
                        l4_thread_switch(0);
118
 
119
                        /* Write back the result */
120
                        shared_page->shared_var = temp;
121
 
122
        //              test_printf("Child modified. Unlocking...\n");
123
 
124
                        /* Unlock */
125
                        l4_mutex_unlock(&shared_page->mutex);
126
        //              test_printf("Child unlocked page.\n");
127
 
128
                        /* Thread switch */
129
                        l4_thread_switch(0);
130
 
131
                }
132
                /* Sync with the parent */
133
                if ((err = l4_send(parent, L4_IPC_TAG_SYNC)) < 0) {
134
                        printf("Error: l4_send() failed with %d\n", err);
135
                        goto out_err;
136
                }
137
 
138
 
139
        /* Parent locks and consumes */
140
        } else {
141
                for (int x = 0; x < 2000; x++) {
142
                        int temp;
143
 
144
                        /* Lock page */
145
        //              test_printf("Parent locking page.\n");
146
                        l4_mutex_lock(&shared_page->mutex);
147
 
148
                        /* Read variable */
149
        //              test_printf("Parent locked page.\n");
150
                        temp = shared_page->shared_var;
151
 
152
                        /* Update local copy */
153
                        temp--;
154
 
155
                        /* Thread switch */
156
                        l4_thread_switch(0);
157
 
158
                        /* Write back the result */
159
                        shared_page->shared_var = temp;
160
 
161
        //              test_printf("Parent modified. Unlocking...\n");
162
 
163
                        /* Unlock */
164
                        l4_mutex_unlock(&shared_page->mutex);
165
        //              test_printf("Parent unlocked page.\n");
166
 
167
                        /* Thread switch */
168
                        l4_thread_switch(0);
169
                }
170
                /* Sync with the child */
171
                if ((err = l4_receive(child)) < 0) {
172
                        printf("Error: l4_receive() failed with %d\n", err);
173
                        goto out_err;
174
                }
175
 
176
        //      test_printf("Parent checking validity of value.\n");
177
                if (shared_page->shared_var != 0)
178
                        goto out_err;
179
 
180
                printf("USER MUTEX TEST:    -- PASSED --\n");
181
        }
182
        return 0;
183
 
184
out_err:
185
        printf("USER MUTEX TEST:    -- FAILED --\n");
186
        return -1;
187
}
188
 
189
 
190
 
191
 
192
 

powered by: WebSVN 2.1.0

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