2
* Copyright (c) 2006 Ondrej Palkovsky
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
#include <proc/thread.h>
36
#include <synch/condvar.h>
37
#include <synch/mutex.h>
41
/** Fill memory with 2 caches, when allocation fails,
42
* free one of the caches. We should have everything in magazines,
43
* now allocation should clean magazines and allow for full allocation.
45
static void totalmemtest(void)
52
void *olddata1 = NULL, *olddata2 = NULL;
54
cache1 = slab_cache_create("cache1_tst", ITEM_SIZE, 0, NULL, NULL, 0);
55
cache2 = slab_cache_create("cache2_tst", ITEM_SIZE, 0, NULL, NULL, 0);
57
TPRINTF("Allocating...");
59
/* Use atomic alloc, so that we find end of memory */
61
data1 = slab_alloc(cache1, FRAME_ATOMIC);
62
data2 = slab_alloc(cache2, FRAME_ATOMIC);
63
if ((!data1) || (!data2)) {
65
slab_free(cache1, data1);
67
slab_free(cache2, data2);
70
memsetb(data1, ITEM_SIZE, 0);
71
memsetb(data2, ITEM_SIZE, 0);
72
*((void **) data1) = olddata1;
73
*((void **) data2) = olddata2;
80
TPRINTF("Deallocating cache2...");
82
/* We do not have memory - now deallocate cache2 */
84
data2 = *((void **) olddata2);
85
slab_free(cache2, olddata2);
91
TPRINTF("Allocating to cache1...\n");
93
for (i = 0; i < 30; i++) {
94
data1 = slab_alloc(cache1, FRAME_ATOMIC);
96
TPRINTF("Incorrect memory size - use another test.");
99
memsetb(data1, ITEM_SIZE, 0);
100
*((void **) data1) = olddata1;
104
data1 = slab_alloc(cache1, FRAME_ATOMIC);
107
memsetb(data1, ITEM_SIZE, 0);
108
*((void **) data1) = olddata1;
112
TPRINTF("Deallocating cache1...");
115
data1 = *((void **) olddata1);
116
slab_free(cache1, olddata1);
125
slab_cache_destroy(cache1);
126
slab_cache_destroy(cache2);
129
static slab_cache_t *thr_cache;
130
static semaphore_t thr_sem;
131
static condvar_t thread_starter;
132
static mutex_t starter_mutex;
136
static void slabtest(void *priv)
138
void *data = NULL, *new;
140
thread_detach(THREAD);
142
mutex_lock(&starter_mutex);
143
condvar_wait(&thread_starter,&starter_mutex);
144
mutex_unlock(&starter_mutex);
146
TPRINTF("Starting thread #%" PRIu64 "...\n", THREAD->tid);
149
TPRINTF("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
152
/* Call with atomic to detect end of memory */
153
new = slab_alloc(thr_cache, FRAME_ATOMIC);
156
*((void **) new) = data;
160
TPRINTF("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
163
new = *((void **)data);
164
*((void **) data) = NULL;
165
slab_free(thr_cache, data);
169
TPRINTF("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
172
/* Call with atomic to detect end of memory */
173
new = slab_alloc(thr_cache, FRAME_ATOMIC);
176
*((void **) new) = data;
180
TPRINTF("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
183
new = *((void **)data);
184
*((void **) data) = NULL;
185
slab_free(thr_cache, data);
189
TPRINTF("Thread #%" PRIu64 " finished\n", THREAD->tid);
194
semaphore_up(&thr_sem);
197
static void multitest(int size)
199
/* Start 8 threads that just allocate as much as possible,
200
* then release everything, then again allocate, then release
205
TPRINTF("Running stress test with size %d\n", size);
207
condvar_initialize(&thread_starter);
208
mutex_initialize(&starter_mutex, MUTEX_PASSIVE);
210
thr_cache = slab_cache_create("thread_cache", size, 0, NULL, NULL, 0);
211
semaphore_initialize(&thr_sem,0);
212
for (i = 0; i < THREADS; i++) {
213
if (!(t = thread_create(slabtest, NULL, TASK, 0, "slabtest", false))) {
214
TPRINTF("Could not create thread %d\n", i);
219
condvar_broadcast(&thread_starter);
221
for (i = 0; i < THREADS; i++)
222
semaphore_down(&thr_sem);
224
slab_cache_destroy(thr_cache);
225
TPRINTF("Stress test complete.\n");
228
char *test_slab2(void)
230
TPRINTF("Running reclaim single-thread test .. pass 1\n");
233
TPRINTF("Running reclaim single-thread test .. pass 2\n");
236
TPRINTF("Reclaim test OK.\n");