clang-format
This commit is contained in:
@@ -33,188 +33,181 @@
|
||||
#include <test.h>
|
||||
|
||||
#define TESTSIZE 73
|
||||
#define BIGTESTSIZE 3000 /* more than one page of pointers */
|
||||
#define NTH(i) ((void *)(0xb007 + 3*(i)))
|
||||
#define BIGTESTSIZE 3000 /* more than one page of pointers */
|
||||
#define NTH(i) ((void *)(0xb007 + 3 * (i)))
|
||||
|
||||
static
|
||||
void
|
||||
testa(struct array *a)
|
||||
{
|
||||
int testarray[TESTSIZE];
|
||||
int i, j, n, r, *p;
|
||||
static void testa(struct array *a) {
|
||||
int testarray[TESTSIZE];
|
||||
int i, j, n, r, *p;
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
testarray[i]=i;
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
testarray[i] = i;
|
||||
}
|
||||
|
||||
n = array_num(a);
|
||||
KASSERT(n==0);
|
||||
n = array_num(a);
|
||||
KASSERT(n == 0);
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
r = array_add(a, &testarray[i], NULL);
|
||||
KASSERT(r==0);
|
||||
n = array_num(a);
|
||||
KASSERT(n==i+1);
|
||||
}
|
||||
n = array_num(a);
|
||||
KASSERT(n==TESTSIZE);
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
r = array_add(a, &testarray[i], NULL);
|
||||
KASSERT(r == 0);
|
||||
n = array_num(a);
|
||||
KASSERT(n == i + 1);
|
||||
}
|
||||
n = array_num(a);
|
||||
KASSERT(n == TESTSIZE);
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == i);
|
||||
}
|
||||
n = array_num(a);
|
||||
KASSERT(n==TESTSIZE);
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == i);
|
||||
}
|
||||
n = array_num(a);
|
||||
KASSERT(n == TESTSIZE);
|
||||
|
||||
for (j=0; j<TESTSIZE*4; j++) {
|
||||
i = random()%TESTSIZE;
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == i);
|
||||
}
|
||||
n = array_num(a);
|
||||
KASSERT(n==TESTSIZE);
|
||||
for (j = 0; j < TESTSIZE * 4; j++) {
|
||||
i = random() % TESTSIZE;
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == i);
|
||||
}
|
||||
n = array_num(a);
|
||||
KASSERT(n == TESTSIZE);
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
array_set(a, i, &testarray[TESTSIZE-i-1]);
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
array_set(a, i, &testarray[TESTSIZE - i - 1]);
|
||||
}
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == TESTSIZE-i-1);
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == TESTSIZE - i - 1);
|
||||
}
|
||||
|
||||
r = array_setsize(a, TESTSIZE/2);
|
||||
KASSERT(r==0);
|
||||
r = array_setsize(a, TESTSIZE / 2);
|
||||
KASSERT(r == 0);
|
||||
|
||||
for (i=0; i<TESTSIZE/2; i++) {
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == TESTSIZE-i-1);
|
||||
}
|
||||
for (i = 0; i < TESTSIZE / 2; i++) {
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == TESTSIZE - i - 1);
|
||||
}
|
||||
|
||||
array_remove(a, 1);
|
||||
array_remove(a, 1);
|
||||
|
||||
for (i=1; i<TESTSIZE/2 - 1; i++) {
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == TESTSIZE-i-2);
|
||||
}
|
||||
p = array_get(a, 0);
|
||||
KASSERT(*p == TESTSIZE-1);
|
||||
for (i = 1; i < TESTSIZE / 2 - 1; i++) {
|
||||
p = array_get(a, i);
|
||||
KASSERT(*p == TESTSIZE - i - 2);
|
||||
}
|
||||
p = array_get(a, 0);
|
||||
KASSERT(*p == TESTSIZE - 1);
|
||||
|
||||
array_setsize(a, 2);
|
||||
p = array_get(a, 0);
|
||||
KASSERT(*p == TESTSIZE-1);
|
||||
p = array_get(a, 1);
|
||||
KASSERT(*p == TESTSIZE-3);
|
||||
array_setsize(a, 2);
|
||||
p = array_get(a, 0);
|
||||
KASSERT(*p == TESTSIZE - 1);
|
||||
p = array_get(a, 1);
|
||||
KASSERT(*p == TESTSIZE - 3);
|
||||
|
||||
array_set(a, 1, NULL);
|
||||
array_setsize(a, 2);
|
||||
p = array_get(a, 0);
|
||||
KASSERT(*p == TESTSIZE-1);
|
||||
p = array_get(a, 1);
|
||||
KASSERT(p==NULL);
|
||||
array_set(a, 1, NULL);
|
||||
array_setsize(a, 2);
|
||||
p = array_get(a, 0);
|
||||
KASSERT(*p == TESTSIZE - 1);
|
||||
p = array_get(a, 1);
|
||||
KASSERT(p == NULL);
|
||||
|
||||
array_setsize(a, TESTSIZE*10);
|
||||
p = array_get(a, 0);
|
||||
KASSERT(*p == TESTSIZE-1);
|
||||
p = array_get(a, 1);
|
||||
KASSERT(p==NULL);
|
||||
array_setsize(a, TESTSIZE * 10);
|
||||
p = array_get(a, 0);
|
||||
KASSERT(*p == TESTSIZE - 1);
|
||||
p = array_get(a, 1);
|
||||
KASSERT(p == NULL);
|
||||
}
|
||||
|
||||
int
|
||||
arraytest(int nargs, char **args)
|
||||
{
|
||||
struct array *a;
|
||||
int arraytest(int nargs, char **args) {
|
||||
struct array *a;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
kprintf("Beginning array test...\n");
|
||||
a = array_create();
|
||||
KASSERT(a != NULL);
|
||||
kprintf("Beginning array test...\n");
|
||||
a = array_create();
|
||||
KASSERT(a != NULL);
|
||||
|
||||
testa(a);
|
||||
testa(a);
|
||||
|
||||
array_setsize(a, 0);
|
||||
array_setsize(a, 0);
|
||||
|
||||
testa(a);
|
||||
testa(a);
|
||||
|
||||
array_setsize(a, 0);
|
||||
array_destroy(a);
|
||||
array_setsize(a, 0);
|
||||
array_destroy(a);
|
||||
|
||||
kprintf("Array test complete\n");
|
||||
return 0;
|
||||
kprintf("Array test complete\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
arraytest2(int nargs, char **args)
|
||||
{
|
||||
struct array *a;
|
||||
void *p;
|
||||
unsigned i, x;
|
||||
int result;
|
||||
int arraytest2(int nargs, char **args) {
|
||||
struct array *a;
|
||||
void *p;
|
||||
unsigned i, x;
|
||||
int result;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
/* Silence warning with gcc 4.8 -Og (but not -O2) */
|
||||
x = 0;
|
||||
/* Silence warning with gcc 4.8 -Og (but not -O2) */
|
||||
x = 0;
|
||||
|
||||
kprintf("Beginning large array test...\n");
|
||||
a = array_create();
|
||||
KASSERT(a != NULL);
|
||||
kprintf("Beginning large array test...\n");
|
||||
a = array_create();
|
||||
KASSERT(a != NULL);
|
||||
|
||||
/* 1. Fill it one at a time. */
|
||||
p = (void *)0xc0ffee;
|
||||
for (i=0; i<BIGTESTSIZE; i++) {
|
||||
result = array_add(a, p, &x);
|
||||
KASSERT(result == 0);
|
||||
KASSERT(x == i);
|
||||
}
|
||||
KASSERT(array_num(a) == BIGTESTSIZE);
|
||||
/* 1. Fill it one at a time. */
|
||||
p = (void *)0xc0ffee;
|
||||
for (i = 0; i < BIGTESTSIZE; i++) {
|
||||
result = array_add(a, p, &x);
|
||||
KASSERT(result == 0);
|
||||
KASSERT(x == i);
|
||||
}
|
||||
KASSERT(array_num(a) == BIGTESTSIZE);
|
||||
|
||||
/* 2. Check the contents */
|
||||
for (i=0; i<BIGTESTSIZE; i++) {
|
||||
KASSERT(array_get(a, i) == p);
|
||||
}
|
||||
/* 2. Check the contents */
|
||||
for (i = 0; i < BIGTESTSIZE; i++) {
|
||||
KASSERT(array_get(a, i) == p);
|
||||
}
|
||||
|
||||
/* 3. Clear it */
|
||||
result = array_setsize(a, 0);
|
||||
KASSERT(result == 0);
|
||||
/* 3. Clear it */
|
||||
result = array_setsize(a, 0);
|
||||
KASSERT(result == 0);
|
||||
|
||||
/* 4. Set the size and initialize with array_set */
|
||||
result = array_setsize(a, BIGTESTSIZE);
|
||||
KASSERT(result == 0);
|
||||
for (i=0; i<BIGTESTSIZE; i++) {
|
||||
array_set(a, i, NTH(i));
|
||||
}
|
||||
/* 4. Set the size and initialize with array_set */
|
||||
result = array_setsize(a, BIGTESTSIZE);
|
||||
KASSERT(result == 0);
|
||||
for (i = 0; i < BIGTESTSIZE; i++) {
|
||||
array_set(a, i, NTH(i));
|
||||
}
|
||||
|
||||
/* 5. Check the contents again */
|
||||
for (i=0; i<BIGTESTSIZE; i++) {
|
||||
KASSERT(array_get(a, i) == NTH(i));
|
||||
}
|
||||
/* 5. Check the contents again */
|
||||
for (i = 0; i < BIGTESTSIZE; i++) {
|
||||
KASSERT(array_get(a, i) == NTH(i));
|
||||
}
|
||||
|
||||
/* 6. Zot an entry and check the contents */
|
||||
array_remove(a, 1);
|
||||
KASSERT(array_get(a, 0) == NTH(0));
|
||||
KASSERT(array_num(a) == BIGTESTSIZE-1);
|
||||
for (i=1; i<BIGTESTSIZE-1; i++) {
|
||||
KASSERT(array_get(a, i) == NTH(i+1));
|
||||
}
|
||||
/* 6. Zot an entry and check the contents */
|
||||
array_remove(a, 1);
|
||||
KASSERT(array_get(a, 0) == NTH(0));
|
||||
KASSERT(array_num(a) == BIGTESTSIZE - 1);
|
||||
for (i = 1; i < BIGTESTSIZE - 1; i++) {
|
||||
KASSERT(array_get(a, i) == NTH(i + 1));
|
||||
}
|
||||
|
||||
/* 7. Double the size and check the preexisting contents */
|
||||
result = array_setsize(a, BIGTESTSIZE*2);
|
||||
KASSERT(result == 0);
|
||||
KASSERT(array_get(a, 0) == NTH(0));
|
||||
for (i=1; i<BIGTESTSIZE-1; i++) {
|
||||
KASSERT(array_get(a, i) == NTH(i+1));
|
||||
}
|
||||
/* 7. Double the size and check the preexisting contents */
|
||||
result = array_setsize(a, BIGTESTSIZE * 2);
|
||||
KASSERT(result == 0);
|
||||
KASSERT(array_get(a, 0) == NTH(0));
|
||||
for (i = 1; i < BIGTESTSIZE - 1; i++) {
|
||||
KASSERT(array_get(a, i) == NTH(i + 1));
|
||||
}
|
||||
|
||||
/* done */
|
||||
result = array_setsize(a, 0);
|
||||
KASSERT(result == 0);
|
||||
array_destroy(a);
|
||||
/* done */
|
||||
result = array_setsize(a, 0);
|
||||
KASSERT(result == 0);
|
||||
array_destroy(a);
|
||||
|
||||
kprintf("Done.\n");
|
||||
kprintf("Done.\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,73 +34,68 @@
|
||||
|
||||
#define TESTSIZE 533
|
||||
|
||||
int
|
||||
bitmaptest(int nargs, char **args)
|
||||
{
|
||||
struct bitmap *b;
|
||||
char data[TESTSIZE];
|
||||
uint32_t x;
|
||||
int i;
|
||||
int bitmaptest(int nargs, char **args) {
|
||||
struct bitmap *b;
|
||||
char data[TESTSIZE];
|
||||
uint32_t x;
|
||||
int i;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
kprintf("Starting bitmap test...\n");
|
||||
kprintf("Starting bitmap test...\n");
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
data[i] = random()%2;
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
data[i] = random() % 2;
|
||||
}
|
||||
|
||||
b = bitmap_create(TESTSIZE);
|
||||
KASSERT(b != NULL);
|
||||
b = bitmap_create(TESTSIZE);
|
||||
KASSERT(b != NULL);
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
KASSERT(bitmap_isset(b, i)==0);
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
KASSERT(bitmap_isset(b, i) == 0);
|
||||
}
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
if (data[i]) {
|
||||
bitmap_mark(b, i);
|
||||
}
|
||||
}
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
if (data[i]) {
|
||||
KASSERT(bitmap_isset(b, i));
|
||||
}
|
||||
else {
|
||||
KASSERT(bitmap_isset(b, i)==0);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
if (data[i]) {
|
||||
bitmap_mark(b, i);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
if (data[i]) {
|
||||
KASSERT(bitmap_isset(b, i));
|
||||
} else {
|
||||
KASSERT(bitmap_isset(b, i) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
if (data[i]) {
|
||||
bitmap_unmark(b, i);
|
||||
}
|
||||
else {
|
||||
bitmap_mark(b, i);
|
||||
}
|
||||
}
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
if (data[i]) {
|
||||
KASSERT(bitmap_isset(b, i)==0);
|
||||
}
|
||||
else {
|
||||
KASSERT(bitmap_isset(b, i));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
if (data[i]) {
|
||||
bitmap_unmark(b, i);
|
||||
} else {
|
||||
bitmap_mark(b, i);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
if (data[i]) {
|
||||
KASSERT(bitmap_isset(b, i) == 0);
|
||||
} else {
|
||||
KASSERT(bitmap_isset(b, i));
|
||||
}
|
||||
}
|
||||
|
||||
while (bitmap_alloc(b, &x)==0) {
|
||||
KASSERT(x < TESTSIZE);
|
||||
KASSERT(bitmap_isset(b, x));
|
||||
KASSERT(data[x]==1);
|
||||
data[x] = 0;
|
||||
}
|
||||
while (bitmap_alloc(b, &x) == 0) {
|
||||
KASSERT(x < TESTSIZE);
|
||||
KASSERT(bitmap_isset(b, x));
|
||||
KASSERT(data[x] == 1);
|
||||
data[x] = 0;
|
||||
}
|
||||
|
||||
for (i=0; i<TESTSIZE; i++) {
|
||||
KASSERT(bitmap_isset(b, i));
|
||||
KASSERT(data[i]==0);
|
||||
}
|
||||
for (i = 0; i < TESTSIZE; i++) {
|
||||
KASSERT(bitmap_isset(b, i));
|
||||
KASSERT(data[i] == 0);
|
||||
}
|
||||
|
||||
kprintf("Bitmap test complete\n");
|
||||
return 0;
|
||||
kprintf("Bitmap test complete\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
1046
kern/test/fstest.c
1046
kern/test/fstest.c
File diff suppressed because it is too large
Load Diff
@@ -54,95 +54,85 @@
|
||||
* threads at once.
|
||||
*/
|
||||
|
||||
#define NTRIES 1200
|
||||
#define ITEMSIZE 997
|
||||
#define NTHREADS 8
|
||||
#define NTRIES 1200
|
||||
#define ITEMSIZE 997
|
||||
#define NTHREADS 8
|
||||
|
||||
static
|
||||
void
|
||||
kmallocthread(void *sm, unsigned long num)
|
||||
{
|
||||
struct semaphore *sem = sm;
|
||||
void *ptr;
|
||||
void *oldptr=NULL;
|
||||
void *oldptr2=NULL;
|
||||
int i;
|
||||
static void kmallocthread(void *sm, unsigned long num) {
|
||||
struct semaphore *sem = sm;
|
||||
void *ptr;
|
||||
void *oldptr = NULL;
|
||||
void *oldptr2 = NULL;
|
||||
int i;
|
||||
|
||||
for (i=0; i<NTRIES; i++) {
|
||||
ptr = kmalloc(ITEMSIZE);
|
||||
if (ptr==NULL) {
|
||||
if (sem) {
|
||||
kprintf("thread %lu: kmalloc returned NULL\n",
|
||||
num);
|
||||
goto done;
|
||||
}
|
||||
kprintf("kmalloc returned null; test failed.\n");
|
||||
goto done;
|
||||
}
|
||||
if (oldptr2) {
|
||||
kfree(oldptr2);
|
||||
}
|
||||
oldptr2 = oldptr;
|
||||
oldptr = ptr;
|
||||
}
|
||||
for (i = 0; i < NTRIES; i++) {
|
||||
ptr = kmalloc(ITEMSIZE);
|
||||
if (ptr == NULL) {
|
||||
if (sem) {
|
||||
kprintf("thread %lu: kmalloc returned NULL\n", num);
|
||||
goto done;
|
||||
}
|
||||
kprintf("kmalloc returned null; test failed.\n");
|
||||
goto done;
|
||||
}
|
||||
if (oldptr2) {
|
||||
kfree(oldptr2);
|
||||
}
|
||||
oldptr2 = oldptr;
|
||||
oldptr = ptr;
|
||||
}
|
||||
done:
|
||||
if (oldptr2) {
|
||||
kfree(oldptr2);
|
||||
}
|
||||
if (oldptr) {
|
||||
kfree(oldptr);
|
||||
}
|
||||
if (sem) {
|
||||
V(sem);
|
||||
}
|
||||
if (oldptr2) {
|
||||
kfree(oldptr2);
|
||||
}
|
||||
if (oldptr) {
|
||||
kfree(oldptr);
|
||||
}
|
||||
if (sem) {
|
||||
V(sem);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kmalloctest(int nargs, char **args)
|
||||
{
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
int kmalloctest(int nargs, char **args) {
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
kprintf("Starting kmalloc test...\n");
|
||||
kmallocthread(NULL, 0);
|
||||
kprintf("kmalloc test done\n");
|
||||
kprintf("Starting kmalloc test...\n");
|
||||
kmallocthread(NULL, 0);
|
||||
kprintf("kmalloc test done\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kmallocstress(int nargs, char **args)
|
||||
{
|
||||
struct semaphore *sem;
|
||||
int i, result;
|
||||
int kmallocstress(int nargs, char **args) {
|
||||
struct semaphore *sem;
|
||||
int i, result;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
sem = sem_create("kmallocstress", 0);
|
||||
if (sem == NULL) {
|
||||
panic("kmallocstress: sem_create failed\n");
|
||||
}
|
||||
sem = sem_create("kmallocstress", 0);
|
||||
if (sem == NULL) {
|
||||
panic("kmallocstress: sem_create failed\n");
|
||||
}
|
||||
|
||||
kprintf("Starting kmalloc stress test...\n");
|
||||
kprintf("Starting kmalloc stress test...\n");
|
||||
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
result = thread_fork("kmallocstress", NULL,
|
||||
kmallocthread, sem, i);
|
||||
if (result) {
|
||||
panic("kmallocstress: thread_fork failed: %s\n",
|
||||
strerror(result));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
result = thread_fork("kmallocstress", NULL, kmallocthread, sem, i);
|
||||
if (result) {
|
||||
panic("kmallocstress: thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
P(sem);
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
P(sem);
|
||||
}
|
||||
|
||||
sem_destroy(sem);
|
||||
kprintf("kmalloc stress test done\n");
|
||||
sem_destroy(sem);
|
||||
kprintf("kmalloc stress test done\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@@ -169,212 +159,199 @@ kmallocstress(int nargs, char **args)
|
||||
* Having set this up, the test just allocates and then frees all the
|
||||
* pointers in order, setting and checking the contents.
|
||||
*/
|
||||
int
|
||||
kmalloctest3(int nargs, char **args)
|
||||
{
|
||||
int kmalloctest3(int nargs, char **args) {
|
||||
#define NUM_KM3_SIZES 5
|
||||
static const unsigned sizes[NUM_KM3_SIZES] = { 32, 41, 109, 86, 9 };
|
||||
unsigned numptrs;
|
||||
size_t ptrspace;
|
||||
size_t blocksize;
|
||||
unsigned numptrblocks;
|
||||
void ***ptrblocks;
|
||||
unsigned curblock, curpos, cursizeindex, cursize;
|
||||
size_t totalsize;
|
||||
unsigned i, j;
|
||||
unsigned char *ptr;
|
||||
static const unsigned sizes[NUM_KM3_SIZES] = {32, 41, 109, 86, 9};
|
||||
unsigned numptrs;
|
||||
size_t ptrspace;
|
||||
size_t blocksize;
|
||||
unsigned numptrblocks;
|
||||
void ***ptrblocks;
|
||||
unsigned curblock, curpos, cursizeindex, cursize;
|
||||
size_t totalsize;
|
||||
unsigned i, j;
|
||||
unsigned char *ptr;
|
||||
|
||||
if (nargs != 2) {
|
||||
kprintf("kmalloctest3: usage: km3 numobjects\n");
|
||||
return EINVAL;
|
||||
}
|
||||
if (nargs != 2) {
|
||||
kprintf("kmalloctest3: usage: km3 numobjects\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Figure out how many pointers we'll get and the space they need. */
|
||||
numptrs = atoi(args[1]);
|
||||
ptrspace = numptrs * sizeof(void *);
|
||||
/* Figure out how many pointers we'll get and the space they need. */
|
||||
numptrs = atoi(args[1]);
|
||||
ptrspace = numptrs * sizeof(void *);
|
||||
|
||||
/* Figure out how many blocks in the lower tier. */
|
||||
blocksize = PAGE_SIZE / 4;
|
||||
numptrblocks = DIVROUNDUP(ptrspace, blocksize);
|
||||
/* Figure out how many blocks in the lower tier. */
|
||||
blocksize = PAGE_SIZE / 4;
|
||||
numptrblocks = DIVROUNDUP(ptrspace, blocksize);
|
||||
|
||||
kprintf("kmalloctest3: %u objects, %u pointer blocks\n",
|
||||
numptrs, numptrblocks);
|
||||
kprintf("kmalloctest3: %u objects, %u pointer blocks\n", numptrs,
|
||||
numptrblocks);
|
||||
|
||||
/* Allocate the upper tier. */
|
||||
ptrblocks = kmalloc(numptrblocks * sizeof(ptrblocks[0]));
|
||||
if (ptrblocks == NULL) {
|
||||
panic("kmalloctest3: failed on pointer block array\n");
|
||||
}
|
||||
/* Allocate the lower tier. */
|
||||
for (i=0; i<numptrblocks; i++) {
|
||||
ptrblocks[i] = kmalloc(blocksize);
|
||||
if (ptrblocks[i] == NULL) {
|
||||
panic("kmalloctest3: failed on pointer block %u\n", i);
|
||||
}
|
||||
}
|
||||
/* Allocate the upper tier. */
|
||||
ptrblocks = kmalloc(numptrblocks * sizeof(ptrblocks[0]));
|
||||
if (ptrblocks == NULL) {
|
||||
panic("kmalloctest3: failed on pointer block array\n");
|
||||
}
|
||||
/* Allocate the lower tier. */
|
||||
for (i = 0; i < numptrblocks; i++) {
|
||||
ptrblocks[i] = kmalloc(blocksize);
|
||||
if (ptrblocks[i] == NULL) {
|
||||
panic("kmalloctest3: failed on pointer block %u\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the objects. */
|
||||
curblock = 0;
|
||||
curpos = 0;
|
||||
cursizeindex = 0;
|
||||
totalsize = 0;
|
||||
for (i=0; i<numptrs; i++) {
|
||||
cursize = sizes[cursizeindex];
|
||||
ptr = kmalloc(cursize);
|
||||
if (ptr == NULL) {
|
||||
kprintf("kmalloctest3: failed on object %u size %u\n",
|
||||
i, cursize);
|
||||
kprintf("kmalloctest3: pos %u in pointer block %u\n",
|
||||
curpos, curblock);
|
||||
kprintf("kmalloctest3: total so far %zu\n", totalsize);
|
||||
panic("kmalloctest3: failed.\n");
|
||||
}
|
||||
/* Fill the object with its number. */
|
||||
for (j=0; j<cursize; j++) {
|
||||
ptr[j] = (unsigned char) i;
|
||||
}
|
||||
/* Move to the next slot in the tree. */
|
||||
ptrblocks[curblock][curpos] = ptr;
|
||||
curpos++;
|
||||
if (curpos >= blocksize / sizeof(void *)) {
|
||||
curblock++;
|
||||
curpos = 0;
|
||||
}
|
||||
/* Update the running total, and rotate the size. */
|
||||
totalsize += cursize;
|
||||
cursizeindex = (cursizeindex + 1) % NUM_KM3_SIZES;
|
||||
}
|
||||
/* Allocate the objects. */
|
||||
curblock = 0;
|
||||
curpos = 0;
|
||||
cursizeindex = 0;
|
||||
totalsize = 0;
|
||||
for (i = 0; i < numptrs; i++) {
|
||||
cursize = sizes[cursizeindex];
|
||||
ptr = kmalloc(cursize);
|
||||
if (ptr == NULL) {
|
||||
kprintf("kmalloctest3: failed on object %u size %u\n", i, cursize);
|
||||
kprintf("kmalloctest3: pos %u in pointer block %u\n", curpos, curblock);
|
||||
kprintf("kmalloctest3: total so far %zu\n", totalsize);
|
||||
panic("kmalloctest3: failed.\n");
|
||||
}
|
||||
/* Fill the object with its number. */
|
||||
for (j = 0; j < cursize; j++) {
|
||||
ptr[j] = (unsigned char)i;
|
||||
}
|
||||
/* Move to the next slot in the tree. */
|
||||
ptrblocks[curblock][curpos] = ptr;
|
||||
curpos++;
|
||||
if (curpos >= blocksize / sizeof(void *)) {
|
||||
curblock++;
|
||||
curpos = 0;
|
||||
}
|
||||
/* Update the running total, and rotate the size. */
|
||||
totalsize += cursize;
|
||||
cursizeindex = (cursizeindex + 1) % NUM_KM3_SIZES;
|
||||
}
|
||||
|
||||
kprintf("kmalloctest3: %zu bytes allocated\n", totalsize);
|
||||
kprintf("kmalloctest3: %zu bytes allocated\n", totalsize);
|
||||
|
||||
/* Free the objects. */
|
||||
curblock = 0;
|
||||
curpos = 0;
|
||||
cursizeindex = 0;
|
||||
for (i=0; i<numptrs; i++) {
|
||||
cursize = sizes[cursizeindex];
|
||||
ptr = ptrblocks[curblock][curpos];
|
||||
KASSERT(ptr != NULL);
|
||||
for (j=0; j<cursize; j++) {
|
||||
if (ptr[j] == (unsigned char) i) {
|
||||
continue;
|
||||
}
|
||||
kprintf("kmalloctest3: failed on object %u size %u\n",
|
||||
i, cursize);
|
||||
kprintf("kmalloctest3: pos %u in pointer block %u\n",
|
||||
curpos, curblock);
|
||||
kprintf("kmalloctest3: at object offset %u\n", j);
|
||||
kprintf("kmalloctest3: expected 0x%x, found 0x%x\n",
|
||||
ptr[j], (unsigned char) i);
|
||||
panic("kmalloctest3: failed.\n");
|
||||
}
|
||||
kfree(ptr);
|
||||
curpos++;
|
||||
if (curpos >= blocksize / sizeof(void *)) {
|
||||
curblock++;
|
||||
curpos = 0;
|
||||
}
|
||||
KASSERT(totalsize > 0);
|
||||
totalsize -= cursize;
|
||||
cursizeindex = (cursizeindex + 1) % NUM_KM3_SIZES;
|
||||
}
|
||||
KASSERT(totalsize == 0);
|
||||
/* Free the objects. */
|
||||
curblock = 0;
|
||||
curpos = 0;
|
||||
cursizeindex = 0;
|
||||
for (i = 0; i < numptrs; i++) {
|
||||
cursize = sizes[cursizeindex];
|
||||
ptr = ptrblocks[curblock][curpos];
|
||||
KASSERT(ptr != NULL);
|
||||
for (j = 0; j < cursize; j++) {
|
||||
if (ptr[j] == (unsigned char)i) {
|
||||
continue;
|
||||
}
|
||||
kprintf("kmalloctest3: failed on object %u size %u\n", i, cursize);
|
||||
kprintf("kmalloctest3: pos %u in pointer block %u\n", curpos, curblock);
|
||||
kprintf("kmalloctest3: at object offset %u\n", j);
|
||||
kprintf("kmalloctest3: expected 0x%x, found 0x%x\n", ptr[j],
|
||||
(unsigned char)i);
|
||||
panic("kmalloctest3: failed.\n");
|
||||
}
|
||||
kfree(ptr);
|
||||
curpos++;
|
||||
if (curpos >= blocksize / sizeof(void *)) {
|
||||
curblock++;
|
||||
curpos = 0;
|
||||
}
|
||||
KASSERT(totalsize > 0);
|
||||
totalsize -= cursize;
|
||||
cursizeindex = (cursizeindex + 1) % NUM_KM3_SIZES;
|
||||
}
|
||||
KASSERT(totalsize == 0);
|
||||
|
||||
/* Free the lower tier. */
|
||||
for (i=0; i<numptrblocks; i++) {
|
||||
KASSERT(ptrblocks[i] != NULL);
|
||||
kfree(ptrblocks[i]);
|
||||
}
|
||||
/* Free the upper tier. */
|
||||
kfree(ptrblocks);
|
||||
/* Free the lower tier. */
|
||||
for (i = 0; i < numptrblocks; i++) {
|
||||
KASSERT(ptrblocks[i] != NULL);
|
||||
kfree(ptrblocks[i]);
|
||||
}
|
||||
/* Free the upper tier. */
|
||||
kfree(ptrblocks);
|
||||
|
||||
kprintf("kmalloctest3: passed\n");
|
||||
return 0;
|
||||
kprintf("kmalloctest3: passed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// km4
|
||||
|
||||
static
|
||||
void
|
||||
kmalloctest4thread(void *sm, unsigned long num)
|
||||
{
|
||||
static void kmalloctest4thread(void *sm, unsigned long num) {
|
||||
#define NUM_KM4_SIZES 5
|
||||
static const unsigned sizes[NUM_KM4_SIZES] = { 1, 3, 5, 2, 4 };
|
||||
static const unsigned sizes[NUM_KM4_SIZES] = {1, 3, 5, 2, 4};
|
||||
|
||||
struct semaphore *sem = sm;
|
||||
void *ptrs[NUM_KM4_SIZES];
|
||||
unsigned p, q;
|
||||
unsigned i;
|
||||
struct semaphore *sem = sm;
|
||||
void *ptrs[NUM_KM4_SIZES];
|
||||
unsigned p, q;
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i<NUM_KM4_SIZES; i++) {
|
||||
ptrs[i] = NULL;
|
||||
}
|
||||
p = 0;
|
||||
q = NUM_KM4_SIZES / 2;
|
||||
for (i = 0; i < NUM_KM4_SIZES; i++) {
|
||||
ptrs[i] = NULL;
|
||||
}
|
||||
p = 0;
|
||||
q = NUM_KM4_SIZES / 2;
|
||||
|
||||
for (i=0; i<NTRIES; i++) {
|
||||
if (ptrs[q] != NULL) {
|
||||
kfree(ptrs[q]);
|
||||
ptrs[q] = NULL;
|
||||
}
|
||||
ptrs[p] = kmalloc(sizes[p] * PAGE_SIZE);
|
||||
if (ptrs[p] == NULL) {
|
||||
panic("kmalloctest4: thread %lu: "
|
||||
"allocating %u pages failed\n",
|
||||
num, sizes[p]);
|
||||
}
|
||||
p = (p + 1) % NUM_KM4_SIZES;
|
||||
q = (q + 1) % NUM_KM4_SIZES;
|
||||
}
|
||||
for (i = 0; i < NTRIES; i++) {
|
||||
if (ptrs[q] != NULL) {
|
||||
kfree(ptrs[q]);
|
||||
ptrs[q] = NULL;
|
||||
}
|
||||
ptrs[p] = kmalloc(sizes[p] * PAGE_SIZE);
|
||||
if (ptrs[p] == NULL) {
|
||||
panic("kmalloctest4: thread %lu: "
|
||||
"allocating %u pages failed\n",
|
||||
num, sizes[p]);
|
||||
}
|
||||
p = (p + 1) % NUM_KM4_SIZES;
|
||||
q = (q + 1) % NUM_KM4_SIZES;
|
||||
}
|
||||
|
||||
for (i=0; i<NUM_KM4_SIZES; i++) {
|
||||
if (ptrs[i] != NULL) {
|
||||
kfree(ptrs[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUM_KM4_SIZES; i++) {
|
||||
if (ptrs[i] != NULL) {
|
||||
kfree(ptrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
V(sem);
|
||||
V(sem);
|
||||
}
|
||||
|
||||
int
|
||||
kmalloctest4(int nargs, char **args)
|
||||
{
|
||||
struct semaphore *sem;
|
||||
unsigned nthreads;
|
||||
unsigned i;
|
||||
int result;
|
||||
int kmalloctest4(int nargs, char **args) {
|
||||
struct semaphore *sem;
|
||||
unsigned nthreads;
|
||||
unsigned i;
|
||||
int result;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
kprintf("Starting multipage kmalloc test...\n");
|
||||
kprintf("Starting multipage kmalloc test...\n");
|
||||
#if OPT_DUMBVM
|
||||
kprintf("(This test will not work with dumbvm)\n");
|
||||
kprintf("(This test will not work with dumbvm)\n");
|
||||
#endif
|
||||
|
||||
sem = sem_create("kmalloctest4", 0);
|
||||
if (sem == NULL) {
|
||||
panic("kmalloctest4: sem_create failed\n");
|
||||
}
|
||||
sem = sem_create("kmalloctest4", 0);
|
||||
if (sem == NULL) {
|
||||
panic("kmalloctest4: sem_create failed\n");
|
||||
}
|
||||
|
||||
/* use 6 instead of 8 threads */
|
||||
nthreads = (3*NTHREADS)/4;
|
||||
/* use 6 instead of 8 threads */
|
||||
nthreads = (3 * NTHREADS) / 4;
|
||||
|
||||
for (i=0; i<nthreads; i++) {
|
||||
result = thread_fork("kmalloctest4", NULL,
|
||||
kmalloctest4thread, sem, i);
|
||||
if (result) {
|
||||
panic("kmallocstress: thread_fork failed: %s\n",
|
||||
strerror(result));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
result = thread_fork("kmalloctest4", NULL, kmalloctest4thread, sem, i);
|
||||
if (result) {
|
||||
panic("kmallocstress: thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<nthreads; i++) {
|
||||
P(sem);
|
||||
}
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
P(sem);
|
||||
}
|
||||
|
||||
sem_destroy(sem);
|
||||
kprintf("Multipage kmalloc test done\n");
|
||||
return 0;
|
||||
sem_destroy(sem);
|
||||
kprintf("Multipage kmalloc test done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,11 +34,9 @@
|
||||
#include <lib.h>
|
||||
#include <test.h>
|
||||
|
||||
int
|
||||
nettest(int nargs, char **args)
|
||||
{
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
kprintf("No network support available\n");
|
||||
return 1;
|
||||
int nettest(int nargs, char **args) {
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
kprintf("No network support available\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,10 +38,10 @@
|
||||
#include <synch.h>
|
||||
#include <test.h>
|
||||
|
||||
#define NSEMLOOPS 63
|
||||
#define NLOCKLOOPS 120
|
||||
#define NCVLOOPS 5
|
||||
#define NTHREADS 32
|
||||
#define NSEMLOOPS 63
|
||||
#define NLOCKLOOPS 120
|
||||
#define NCVLOOPS 5
|
||||
#define NTHREADS 32
|
||||
|
||||
static volatile unsigned long testval1;
|
||||
static volatile unsigned long testval2;
|
||||
@@ -51,250 +51,223 @@ static struct lock *testlock;
|
||||
static struct cv *testcv;
|
||||
static struct semaphore *donesem;
|
||||
|
||||
static
|
||||
void
|
||||
inititems(void)
|
||||
{
|
||||
if (testsem==NULL) {
|
||||
testsem = sem_create("testsem", 2);
|
||||
if (testsem == NULL) {
|
||||
panic("synchtest: sem_create failed\n");
|
||||
}
|
||||
}
|
||||
if (testlock==NULL) {
|
||||
testlock = lock_create("testlock");
|
||||
if (testlock == NULL) {
|
||||
panic("synchtest: lock_create failed\n");
|
||||
}
|
||||
}
|
||||
if (testcv==NULL) {
|
||||
testcv = cv_create("testlock");
|
||||
if (testcv == NULL) {
|
||||
panic("synchtest: cv_create failed\n");
|
||||
}
|
||||
}
|
||||
if (donesem==NULL) {
|
||||
donesem = sem_create("donesem", 0);
|
||||
if (donesem == NULL) {
|
||||
panic("synchtest: sem_create failed\n");
|
||||
}
|
||||
}
|
||||
static void inititems(void) {
|
||||
if (testsem == NULL) {
|
||||
testsem = sem_create("testsem", 2);
|
||||
if (testsem == NULL) {
|
||||
panic("synchtest: sem_create failed\n");
|
||||
}
|
||||
}
|
||||
if (testlock == NULL) {
|
||||
testlock = lock_create("testlock");
|
||||
if (testlock == NULL) {
|
||||
panic("synchtest: lock_create failed\n");
|
||||
}
|
||||
}
|
||||
if (testcv == NULL) {
|
||||
testcv = cv_create("testlock");
|
||||
if (testcv == NULL) {
|
||||
panic("synchtest: cv_create failed\n");
|
||||
}
|
||||
}
|
||||
if (donesem == NULL) {
|
||||
donesem = sem_create("donesem", 0);
|
||||
if (donesem == NULL) {
|
||||
panic("synchtest: sem_create failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
semtestthread(void *junk, unsigned long num)
|
||||
{
|
||||
int i;
|
||||
(void)junk;
|
||||
static void semtestthread(void *junk, unsigned long num) {
|
||||
int i;
|
||||
(void)junk;
|
||||
|
||||
/*
|
||||
* Only one of these should print at a time.
|
||||
*/
|
||||
P(testsem);
|
||||
kprintf("Thread %2lu: ", num);
|
||||
for (i=0; i<NSEMLOOPS; i++) {
|
||||
kprintf("%c", (int)num+64);
|
||||
}
|
||||
kprintf("\n");
|
||||
V(donesem);
|
||||
/*
|
||||
* Only one of these should print at a time.
|
||||
*/
|
||||
P(testsem);
|
||||
kprintf("Thread %2lu: ", num);
|
||||
for (i = 0; i < NSEMLOOPS; i++) {
|
||||
kprintf("%c", (int)num + 64);
|
||||
}
|
||||
kprintf("\n");
|
||||
V(donesem);
|
||||
}
|
||||
|
||||
int
|
||||
semtest(int nargs, char **args)
|
||||
{
|
||||
int i, result;
|
||||
int semtest(int nargs, char **args) {
|
||||
int i, result;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
inititems();
|
||||
kprintf("Starting semaphore test...\n");
|
||||
kprintf("If this hangs, it's broken: ");
|
||||
P(testsem);
|
||||
P(testsem);
|
||||
kprintf("ok\n");
|
||||
inititems();
|
||||
kprintf("Starting semaphore test...\n");
|
||||
kprintf("If this hangs, it's broken: ");
|
||||
P(testsem);
|
||||
P(testsem);
|
||||
kprintf("ok\n");
|
||||
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
result = thread_fork("semtest", NULL, semtestthread, NULL, i);
|
||||
if (result) {
|
||||
panic("semtest: thread_fork failed: %s\n",
|
||||
strerror(result));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
result = thread_fork("semtest", NULL, semtestthread, NULL, i);
|
||||
if (result) {
|
||||
panic("semtest: thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
V(testsem);
|
||||
P(donesem);
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
V(testsem);
|
||||
P(donesem);
|
||||
}
|
||||
|
||||
/* so we can run it again */
|
||||
V(testsem);
|
||||
V(testsem);
|
||||
/* so we can run it again */
|
||||
V(testsem);
|
||||
V(testsem);
|
||||
|
||||
kprintf("Semaphore test done.\n");
|
||||
return 0;
|
||||
kprintf("Semaphore test done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
fail(unsigned long num, const char *msg)
|
||||
{
|
||||
kprintf("thread %lu: Mismatch on %s\n", num, msg);
|
||||
kprintf("Test failed\n");
|
||||
static void fail(unsigned long num, const char *msg) {
|
||||
kprintf("thread %lu: Mismatch on %s\n", num, msg);
|
||||
kprintf("Test failed\n");
|
||||
|
||||
lock_release(testlock);
|
||||
lock_release(testlock);
|
||||
|
||||
V(donesem);
|
||||
thread_exit();
|
||||
V(donesem);
|
||||
thread_exit();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
locktestthread(void *junk, unsigned long num)
|
||||
{
|
||||
int i;
|
||||
(void)junk;
|
||||
static void locktestthread(void *junk, unsigned long num) {
|
||||
int i;
|
||||
(void)junk;
|
||||
|
||||
for (i=0; i<NLOCKLOOPS; i++) {
|
||||
lock_acquire(testlock);
|
||||
testval1 = num;
|
||||
testval2 = num*num;
|
||||
testval3 = num%3;
|
||||
for (i = 0; i < NLOCKLOOPS; i++) {
|
||||
lock_acquire(testlock);
|
||||
testval1 = num;
|
||||
testval2 = num * num;
|
||||
testval3 = num % 3;
|
||||
|
||||
if (testval2 != testval1*testval1) {
|
||||
fail(num, "testval2/testval1");
|
||||
}
|
||||
if (testval2 != testval1 * testval1) {
|
||||
fail(num, "testval2/testval1");
|
||||
}
|
||||
|
||||
if (testval2%3 != (testval3*testval3)%3) {
|
||||
fail(num, "testval2/testval3");
|
||||
}
|
||||
if (testval2 % 3 != (testval3 * testval3) % 3) {
|
||||
fail(num, "testval2/testval3");
|
||||
}
|
||||
|
||||
if (testval3 != testval1%3) {
|
||||
fail(num, "testval3/testval1");
|
||||
}
|
||||
if (testval3 != testval1 % 3) {
|
||||
fail(num, "testval3/testval1");
|
||||
}
|
||||
|
||||
if (testval1 != num) {
|
||||
fail(num, "testval1/num");
|
||||
}
|
||||
if (testval1 != num) {
|
||||
fail(num, "testval1/num");
|
||||
}
|
||||
|
||||
if (testval2 != num*num) {
|
||||
fail(num, "testval2/num");
|
||||
}
|
||||
if (testval2 != num * num) {
|
||||
fail(num, "testval2/num");
|
||||
}
|
||||
|
||||
if (testval3 != num%3) {
|
||||
fail(num, "testval3/num");
|
||||
}
|
||||
if (testval3 != num % 3) {
|
||||
fail(num, "testval3/num");
|
||||
}
|
||||
|
||||
lock_release(testlock);
|
||||
}
|
||||
V(donesem);
|
||||
lock_release(testlock);
|
||||
}
|
||||
V(donesem);
|
||||
}
|
||||
|
||||
int locktest(int nargs, char **args) {
|
||||
int i, result;
|
||||
|
||||
int
|
||||
locktest(int nargs, char **args)
|
||||
{
|
||||
int i, result;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
inititems();
|
||||
kprintf("Starting lock test...\n");
|
||||
|
||||
inititems();
|
||||
kprintf("Starting lock test...\n");
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
result = thread_fork("synchtest", NULL, locktestthread, NULL, i);
|
||||
if (result) {
|
||||
panic("locktest: thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
P(donesem);
|
||||
}
|
||||
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
result = thread_fork("synchtest", NULL, locktestthread,
|
||||
NULL, i);
|
||||
if (result) {
|
||||
panic("locktest: thread_fork failed: %s\n",
|
||||
strerror(result));
|
||||
}
|
||||
}
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
P(donesem);
|
||||
}
|
||||
kprintf("Lock test done.\n");
|
||||
|
||||
kprintf("Lock test done.\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
cvtestthread(void *junk, unsigned long num)
|
||||
{
|
||||
int i;
|
||||
volatile int j;
|
||||
struct timespec ts1, ts2;
|
||||
static void cvtestthread(void *junk, unsigned long num) {
|
||||
int i;
|
||||
volatile int j;
|
||||
struct timespec ts1, ts2;
|
||||
|
||||
(void)junk;
|
||||
(void)junk;
|
||||
|
||||
for (i=0; i<NCVLOOPS; i++) {
|
||||
lock_acquire(testlock);
|
||||
while (testval1 != num) {
|
||||
gettime(&ts1);
|
||||
cv_wait(testcv, testlock);
|
||||
gettime(&ts2);
|
||||
for (i = 0; i < NCVLOOPS; i++) {
|
||||
lock_acquire(testlock);
|
||||
while (testval1 != num) {
|
||||
gettime(&ts1);
|
||||
cv_wait(testcv, testlock);
|
||||
gettime(&ts2);
|
||||
|
||||
/* ts2 -= ts1 */
|
||||
timespec_sub(&ts2, &ts1, &ts2);
|
||||
/* ts2 -= ts1 */
|
||||
timespec_sub(&ts2, &ts1, &ts2);
|
||||
|
||||
/* Require at least 2000 cpu cycles (we're 25mhz) */
|
||||
if (ts2.tv_sec == 0 && ts2.tv_nsec < 40*2000) {
|
||||
kprintf("cv_wait took only %u ns\n",
|
||||
ts2.tv_nsec);
|
||||
kprintf("That's too fast... you must be "
|
||||
"busy-looping\n");
|
||||
V(donesem);
|
||||
thread_exit();
|
||||
}
|
||||
/* Require at least 2000 cpu cycles (we're 25mhz) */
|
||||
if (ts2.tv_sec == 0 && ts2.tv_nsec < 40 * 2000) {
|
||||
kprintf("cv_wait took only %u ns\n", ts2.tv_nsec);
|
||||
kprintf("That's too fast... you must be "
|
||||
"busy-looping\n");
|
||||
V(donesem);
|
||||
thread_exit();
|
||||
}
|
||||
}
|
||||
kprintf("Thread %lu\n", num);
|
||||
testval1 = (testval1 + NTHREADS - 1) % NTHREADS;
|
||||
|
||||
}
|
||||
kprintf("Thread %lu\n", num);
|
||||
testval1 = (testval1 + NTHREADS - 1)%NTHREADS;
|
||||
/*
|
||||
* loop a little while to make sure we can measure the
|
||||
* time waiting on the cv.
|
||||
*/
|
||||
for (j = 0; j < 3000; j++)
|
||||
;
|
||||
|
||||
/*
|
||||
* loop a little while to make sure we can measure the
|
||||
* time waiting on the cv.
|
||||
*/
|
||||
for (j=0; j<3000; j++);
|
||||
|
||||
cv_broadcast(testcv, testlock);
|
||||
lock_release(testlock);
|
||||
}
|
||||
V(donesem);
|
||||
cv_broadcast(testcv, testlock);
|
||||
lock_release(testlock);
|
||||
}
|
||||
V(donesem);
|
||||
}
|
||||
|
||||
int
|
||||
cvtest(int nargs, char **args)
|
||||
{
|
||||
int cvtest(int nargs, char **args) {
|
||||
|
||||
int i, result;
|
||||
int i, result;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
inititems();
|
||||
kprintf("Starting CV test...\n");
|
||||
kprintf("Threads should print out in reverse order.\n");
|
||||
inititems();
|
||||
kprintf("Starting CV test...\n");
|
||||
kprintf("Threads should print out in reverse order.\n");
|
||||
|
||||
testval1 = NTHREADS-1;
|
||||
testval1 = NTHREADS - 1;
|
||||
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
result = thread_fork("synchtest", NULL, cvtestthread, NULL, i);
|
||||
if (result) {
|
||||
panic("cvtest: thread_fork failed: %s\n",
|
||||
strerror(result));
|
||||
}
|
||||
}
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
P(donesem);
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
result = thread_fork("synchtest", NULL, cvtestthread, NULL, i);
|
||||
if (result) {
|
||||
panic("cvtest: thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
P(donesem);
|
||||
}
|
||||
|
||||
kprintf("CV test done\n");
|
||||
kprintf("CV test done\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@@ -314,88 +287,80 @@ static struct lock *testlocks[NCVS];
|
||||
static struct semaphore *gatesem;
|
||||
static struct semaphore *exitsem;
|
||||
|
||||
static
|
||||
void
|
||||
sleepthread(void *junk1, unsigned long junk2)
|
||||
{
|
||||
unsigned i, j;
|
||||
static void sleepthread(void *junk1, unsigned long junk2) {
|
||||
unsigned i, j;
|
||||
|
||||
(void)junk1;
|
||||
(void)junk2;
|
||||
(void)junk1;
|
||||
(void)junk2;
|
||||
|
||||
for (j=0; j<NLOOPS; j++) {
|
||||
for (i=0; i<NCVS; i++) {
|
||||
lock_acquire(testlocks[i]);
|
||||
V(gatesem);
|
||||
cv_wait(testcvs[i], testlocks[i]);
|
||||
lock_release(testlocks[i]);
|
||||
}
|
||||
kprintf("sleepthread: %u\n", j);
|
||||
}
|
||||
V(exitsem);
|
||||
for (j = 0; j < NLOOPS; j++) {
|
||||
for (i = 0; i < NCVS; i++) {
|
||||
lock_acquire(testlocks[i]);
|
||||
V(gatesem);
|
||||
cv_wait(testcvs[i], testlocks[i]);
|
||||
lock_release(testlocks[i]);
|
||||
}
|
||||
kprintf("sleepthread: %u\n", j);
|
||||
}
|
||||
V(exitsem);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wakethread(void *junk1, unsigned long junk2)
|
||||
{
|
||||
unsigned i, j;
|
||||
static void wakethread(void *junk1, unsigned long junk2) {
|
||||
unsigned i, j;
|
||||
|
||||
(void)junk1;
|
||||
(void)junk2;
|
||||
(void)junk1;
|
||||
(void)junk2;
|
||||
|
||||
for (j=0; j<NLOOPS; j++) {
|
||||
for (i=0; i<NCVS; i++) {
|
||||
P(gatesem);
|
||||
lock_acquire(testlocks[i]);
|
||||
cv_signal(testcvs[i], testlocks[i]);
|
||||
lock_release(testlocks[i]);
|
||||
}
|
||||
kprintf("wakethread: %u\n", j);
|
||||
}
|
||||
V(exitsem);
|
||||
for (j = 0; j < NLOOPS; j++) {
|
||||
for (i = 0; i < NCVS; i++) {
|
||||
P(gatesem);
|
||||
lock_acquire(testlocks[i]);
|
||||
cv_signal(testcvs[i], testlocks[i]);
|
||||
lock_release(testlocks[i]);
|
||||
}
|
||||
kprintf("wakethread: %u\n", j);
|
||||
}
|
||||
V(exitsem);
|
||||
}
|
||||
|
||||
int
|
||||
cvtest2(int nargs, char **args)
|
||||
{
|
||||
unsigned i;
|
||||
int result;
|
||||
int cvtest2(int nargs, char **args) {
|
||||
unsigned i;
|
||||
int result;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
for (i=0; i<NCVS; i++) {
|
||||
testlocks[i] = lock_create("cvtest2 lock");
|
||||
testcvs[i] = cv_create("cvtest2 cv");
|
||||
}
|
||||
gatesem = sem_create("gatesem", 0);
|
||||
exitsem = sem_create("exitsem", 0);
|
||||
for (i = 0; i < NCVS; i++) {
|
||||
testlocks[i] = lock_create("cvtest2 lock");
|
||||
testcvs[i] = cv_create("cvtest2 cv");
|
||||
}
|
||||
gatesem = sem_create("gatesem", 0);
|
||||
exitsem = sem_create("exitsem", 0);
|
||||
|
||||
kprintf("cvtest2...\n");
|
||||
kprintf("cvtest2...\n");
|
||||
|
||||
result = thread_fork("cvtest2", NULL, sleepthread, NULL, 0);
|
||||
if (result) {
|
||||
panic("cvtest2: thread_fork failed\n");
|
||||
}
|
||||
result = thread_fork("cvtest2", NULL, wakethread, NULL, 0);
|
||||
if (result) {
|
||||
panic("cvtest2: thread_fork failed\n");
|
||||
}
|
||||
result = thread_fork("cvtest2", NULL, sleepthread, NULL, 0);
|
||||
if (result) {
|
||||
panic("cvtest2: thread_fork failed\n");
|
||||
}
|
||||
result = thread_fork("cvtest2", NULL, wakethread, NULL, 0);
|
||||
if (result) {
|
||||
panic("cvtest2: thread_fork failed\n");
|
||||
}
|
||||
|
||||
P(exitsem);
|
||||
P(exitsem);
|
||||
P(exitsem);
|
||||
P(exitsem);
|
||||
|
||||
sem_destroy(exitsem);
|
||||
sem_destroy(gatesem);
|
||||
exitsem = gatesem = NULL;
|
||||
for (i=0; i<NCVS; i++) {
|
||||
lock_destroy(testlocks[i]);
|
||||
cv_destroy(testcvs[i]);
|
||||
testlocks[i] = NULL;
|
||||
testcvs[i] = NULL;
|
||||
}
|
||||
sem_destroy(exitsem);
|
||||
sem_destroy(gatesem);
|
||||
exitsem = gatesem = NULL;
|
||||
for (i = 0; i < NCVS; i++) {
|
||||
lock_destroy(testlocks[i]);
|
||||
cv_destroy(testcvs[i]);
|
||||
testlocks[i] = NULL;
|
||||
testcvs[i] = NULL;
|
||||
}
|
||||
|
||||
kprintf("cvtest2 done\n");
|
||||
return 0;
|
||||
kprintf("cvtest2 done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -35,13 +35,7 @@
|
||||
|
||||
#define NUMNAMES 7
|
||||
static const char *const names[NUMNAMES] = {
|
||||
"Aillard",
|
||||
"Aldaran",
|
||||
"Alton",
|
||||
"Ardais",
|
||||
"Elhalyn",
|
||||
"Hastur",
|
||||
"Ridenow",
|
||||
"Aillard", "Aldaran", "Alton", "Ardais", "Elhalyn", "Hastur", "Ridenow",
|
||||
};
|
||||
|
||||
static struct thread *fakethreads[NUMNAMES];
|
||||
@@ -54,290 +48,257 @@ static struct thread *fakethreads[NUMNAMES];
|
||||
/*
|
||||
* Create a dummy struct thread that we can put on lists for testing.
|
||||
*/
|
||||
static
|
||||
struct thread *
|
||||
fakethread_create(const char *name)
|
||||
{
|
||||
struct thread *t;
|
||||
static struct thread *fakethread_create(const char *name) {
|
||||
struct thread *t;
|
||||
|
||||
t = kmalloc(sizeof(*t));
|
||||
if (t == NULL) {
|
||||
panic("threadlisttest: Out of memory\n");
|
||||
}
|
||||
/* ignore most of the fields, zero everything for tidiness */
|
||||
bzero(t, sizeof(*t));
|
||||
t->t_name = kstrdup(name);
|
||||
if (t->t_name == NULL) {
|
||||
panic("threadlisttest: Out of memory\n");
|
||||
}
|
||||
t->t_stack = FAKE_MAGIC;
|
||||
threadlistnode_init(&t->t_listnode, t);
|
||||
return t;
|
||||
t = kmalloc(sizeof(*t));
|
||||
if (t == NULL) {
|
||||
panic("threadlisttest: Out of memory\n");
|
||||
}
|
||||
/* ignore most of the fields, zero everything for tidiness */
|
||||
bzero(t, sizeof(*t));
|
||||
t->t_name = kstrdup(name);
|
||||
if (t->t_name == NULL) {
|
||||
panic("threadlisttest: Out of memory\n");
|
||||
}
|
||||
t->t_stack = FAKE_MAGIC;
|
||||
threadlistnode_init(&t->t_listnode, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a fake thread.
|
||||
*/
|
||||
static
|
||||
void
|
||||
fakethread_destroy(struct thread *t)
|
||||
{
|
||||
KASSERT(t->t_stack == FAKE_MAGIC);
|
||||
threadlistnode_cleanup(&t->t_listnode);
|
||||
kfree(t->t_name);
|
||||
kfree(t);
|
||||
static void fakethread_destroy(struct thread *t) {
|
||||
KASSERT(t->t_stack == FAKE_MAGIC);
|
||||
threadlistnode_cleanup(&t->t_listnode);
|
||||
kfree(t->t_name);
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// support stuff
|
||||
|
||||
static
|
||||
void
|
||||
check_order(struct threadlist *tl, bool rev)
|
||||
{
|
||||
const char string0[] = "...";
|
||||
const char stringN[] = "~~~";
|
||||
static void check_order(struct threadlist *tl, bool rev) {
|
||||
const char string0[] = "...";
|
||||
const char stringN[] = "~~~";
|
||||
|
||||
struct thread *t;
|
||||
const char *first = rev ? stringN : string0;
|
||||
const char *last = rev ? string0 : stringN;
|
||||
const char *prev;
|
||||
int cmp;
|
||||
struct thread *t;
|
||||
const char *first = rev ? stringN : string0;
|
||||
const char *last = rev ? string0 : stringN;
|
||||
const char *prev;
|
||||
int cmp;
|
||||
|
||||
prev = first;
|
||||
THREADLIST_FORALL(t, *tl) {
|
||||
cmp = strcmp(prev, t->t_name);
|
||||
KASSERT(rev ? (cmp > 0) : (cmp < 0));
|
||||
prev = t->t_name;
|
||||
}
|
||||
cmp = strcmp(prev, last);
|
||||
KASSERT(rev ? (cmp > 0) : (cmp < 0));
|
||||
prev = first;
|
||||
THREADLIST_FORALL(t, *tl) {
|
||||
cmp = strcmp(prev, t->t_name);
|
||||
KASSERT(rev ? (cmp > 0) : (cmp < 0));
|
||||
prev = t->t_name;
|
||||
}
|
||||
cmp = strcmp(prev, last);
|
||||
KASSERT(rev ? (cmp > 0) : (cmp < 0));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// tests
|
||||
|
||||
static
|
||||
void
|
||||
threadlisttest_a(void)
|
||||
{
|
||||
struct threadlist tl;
|
||||
static void threadlisttest_a(void) {
|
||||
struct threadlist tl;
|
||||
|
||||
threadlist_init(&tl);
|
||||
KASSERT(threadlist_isempty(&tl));
|
||||
threadlist_cleanup(&tl);
|
||||
threadlist_init(&tl);
|
||||
KASSERT(threadlist_isempty(&tl));
|
||||
threadlist_cleanup(&tl);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
threadlisttest_b(void)
|
||||
{
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
static void threadlisttest_b(void) {
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
|
||||
threadlist_init(&tl);
|
||||
threadlist_init(&tl);
|
||||
|
||||
threadlist_addhead(&tl, fakethreads[0]);
|
||||
check_order(&tl, false);
|
||||
check_order(&tl, true);
|
||||
KASSERT(tl.tl_count == 1);
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
threadlist_addhead(&tl, fakethreads[0]);
|
||||
check_order(&tl, false);
|
||||
check_order(&tl, true);
|
||||
KASSERT(tl.tl_count == 1);
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
|
||||
threadlist_addtail(&tl, fakethreads[0]);
|
||||
check_order(&tl, false);
|
||||
check_order(&tl, true);
|
||||
KASSERT(tl.tl_count == 1);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
threadlist_addtail(&tl, fakethreads[0]);
|
||||
check_order(&tl, false);
|
||||
check_order(&tl, true);
|
||||
KASSERT(tl.tl_count == 1);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
|
||||
threadlist_cleanup(&tl);
|
||||
threadlist_cleanup(&tl);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
threadlisttest_c(void)
|
||||
{
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
static void threadlisttest_c(void) {
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
|
||||
threadlist_init(&tl);
|
||||
threadlist_init(&tl);
|
||||
|
||||
threadlist_addhead(&tl, fakethreads[0]);
|
||||
threadlist_addhead(&tl, fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
threadlist_addhead(&tl, fakethreads[0]);
|
||||
threadlist_addhead(&tl, fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
|
||||
check_order(&tl, true);
|
||||
check_order(&tl, true);
|
||||
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[1]);
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[1]);
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
|
||||
threadlist_addtail(&tl, fakethreads[0]);
|
||||
threadlist_addtail(&tl, fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
threadlist_addtail(&tl, fakethreads[0]);
|
||||
threadlist_addtail(&tl, fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
|
||||
check_order(&tl, false);
|
||||
check_order(&tl, false);
|
||||
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[1]);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[1]);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
|
||||
threadlist_cleanup(&tl);
|
||||
threadlist_cleanup(&tl);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
threadlisttest_d(void)
|
||||
{
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
static void threadlisttest_d(void) {
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
|
||||
threadlist_init(&tl);
|
||||
threadlist_init(&tl);
|
||||
|
||||
threadlist_addhead(&tl, fakethreads[0]);
|
||||
threadlist_addtail(&tl, fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
threadlist_addhead(&tl, fakethreads[0]);
|
||||
threadlist_addtail(&tl, fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
|
||||
check_order(&tl, false);
|
||||
check_order(&tl, false);
|
||||
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
|
||||
threadlist_addhead(&tl, fakethreads[0]);
|
||||
threadlist_addtail(&tl, fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
threadlist_addhead(&tl, fakethreads[0]);
|
||||
threadlist_addtail(&tl, fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
|
||||
check_order(&tl, false);
|
||||
check_order(&tl, false);
|
||||
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[1]);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[1]);
|
||||
t = threadlist_remtail(&tl);
|
||||
KASSERT(t == fakethreads[0]);
|
||||
KASSERT(tl.tl_count == 0);
|
||||
|
||||
threadlist_cleanup(&tl);
|
||||
threadlist_cleanup(&tl);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
threadlisttest_e(void)
|
||||
{
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
unsigned i;
|
||||
static void threadlisttest_e(void) {
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
unsigned i;
|
||||
|
||||
threadlist_init(&tl);
|
||||
threadlist_init(&tl);
|
||||
|
||||
threadlist_addhead(&tl, fakethreads[1]);
|
||||
threadlist_addtail(&tl, fakethreads[3]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
check_order(&tl, false);
|
||||
threadlist_addhead(&tl, fakethreads[1]);
|
||||
threadlist_addtail(&tl, fakethreads[3]);
|
||||
KASSERT(tl.tl_count == 2);
|
||||
check_order(&tl, false);
|
||||
|
||||
threadlist_insertafter(&tl, fakethreads[3], fakethreads[4]);
|
||||
KASSERT(tl.tl_count == 3);
|
||||
check_order(&tl, false);
|
||||
threadlist_insertafter(&tl, fakethreads[3], fakethreads[4]);
|
||||
KASSERT(tl.tl_count == 3);
|
||||
check_order(&tl, false);
|
||||
|
||||
threadlist_insertbefore(&tl, fakethreads[0], fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 4);
|
||||
check_order(&tl, false);
|
||||
threadlist_insertbefore(&tl, fakethreads[0], fakethreads[1]);
|
||||
KASSERT(tl.tl_count == 4);
|
||||
check_order(&tl, false);
|
||||
|
||||
threadlist_insertafter(&tl, fakethreads[1], fakethreads[2]);
|
||||
KASSERT(tl.tl_count == 5);
|
||||
check_order(&tl, false);
|
||||
threadlist_insertafter(&tl, fakethreads[1], fakethreads[2]);
|
||||
KASSERT(tl.tl_count == 5);
|
||||
check_order(&tl, false);
|
||||
|
||||
KASSERT(fakethreads[4]->t_listnode.tln_prev->tln_self ==
|
||||
fakethreads[3]);
|
||||
KASSERT(fakethreads[3]->t_listnode.tln_prev->tln_self ==
|
||||
fakethreads[2]);
|
||||
KASSERT(fakethreads[2]->t_listnode.tln_prev->tln_self ==
|
||||
fakethreads[1]);
|
||||
KASSERT(fakethreads[1]->t_listnode.tln_prev->tln_self ==
|
||||
fakethreads[0]);
|
||||
KASSERT(fakethreads[4]->t_listnode.tln_prev->tln_self == fakethreads[3]);
|
||||
KASSERT(fakethreads[3]->t_listnode.tln_prev->tln_self == fakethreads[2]);
|
||||
KASSERT(fakethreads[2]->t_listnode.tln_prev->tln_self == fakethreads[1]);
|
||||
KASSERT(fakethreads[1]->t_listnode.tln_prev->tln_self == fakethreads[0]);
|
||||
|
||||
for (i=0; i<5; i++) {
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[i]);
|
||||
}
|
||||
KASSERT(tl.tl_count == 0);
|
||||
for (i = 0; i < 5; i++) {
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[i]);
|
||||
}
|
||||
KASSERT(tl.tl_count == 0);
|
||||
|
||||
threadlist_cleanup(&tl);
|
||||
threadlist_cleanup(&tl);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
threadlisttest_f(void)
|
||||
{
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
unsigned i;
|
||||
static void threadlisttest_f(void) {
|
||||
struct threadlist tl;
|
||||
struct thread *t;
|
||||
unsigned i;
|
||||
|
||||
threadlist_init(&tl);
|
||||
threadlist_init(&tl);
|
||||
|
||||
for (i=0; i<NUMNAMES; i++) {
|
||||
threadlist_addtail(&tl, fakethreads[i]);
|
||||
}
|
||||
KASSERT(tl.tl_count == NUMNAMES);
|
||||
for (i = 0; i < NUMNAMES; i++) {
|
||||
threadlist_addtail(&tl, fakethreads[i]);
|
||||
}
|
||||
KASSERT(tl.tl_count == NUMNAMES);
|
||||
|
||||
i=0;
|
||||
THREADLIST_FORALL(t, tl) {
|
||||
KASSERT(t == fakethreads[i]);
|
||||
i++;
|
||||
}
|
||||
KASSERT(i == NUMNAMES);
|
||||
i = 0;
|
||||
THREADLIST_FORALL(t, tl) {
|
||||
KASSERT(t == fakethreads[i]);
|
||||
i++;
|
||||
}
|
||||
KASSERT(i == NUMNAMES);
|
||||
|
||||
i=0;
|
||||
THREADLIST_FORALL_REV(t, tl) {
|
||||
KASSERT(t == fakethreads[NUMNAMES - i - 1]);
|
||||
i++;
|
||||
}
|
||||
KASSERT(i == NUMNAMES);
|
||||
i = 0;
|
||||
THREADLIST_FORALL_REV(t, tl) {
|
||||
KASSERT(t == fakethreads[NUMNAMES - i - 1]);
|
||||
i++;
|
||||
}
|
||||
KASSERT(i == NUMNAMES);
|
||||
|
||||
for (i=0; i<NUMNAMES; i++) {
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[i]);
|
||||
}
|
||||
KASSERT(tl.tl_count == 0);
|
||||
for (i = 0; i < NUMNAMES; i++) {
|
||||
t = threadlist_remhead(&tl);
|
||||
KASSERT(t == fakethreads[i]);
|
||||
}
|
||||
KASSERT(tl.tl_count == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// external interface
|
||||
|
||||
int
|
||||
threadlisttest(int nargs, char **args)
|
||||
{
|
||||
unsigned i;
|
||||
int threadlisttest(int nargs, char **args) {
|
||||
unsigned i;
|
||||
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
kprintf("Testing threadlists...\n");
|
||||
kprintf("Testing threadlists...\n");
|
||||
|
||||
for (i=0; i<NUMNAMES; i++) {
|
||||
fakethreads[i] = fakethread_create(names[i]);
|
||||
}
|
||||
for (i = 0; i < NUMNAMES; i++) {
|
||||
fakethreads[i] = fakethread_create(names[i]);
|
||||
}
|
||||
|
||||
threadlisttest_a();
|
||||
threadlisttest_b();
|
||||
threadlisttest_c();
|
||||
threadlisttest_d();
|
||||
threadlisttest_e();
|
||||
threadlisttest_f();
|
||||
threadlisttest_a();
|
||||
threadlisttest_b();
|
||||
threadlisttest_c();
|
||||
threadlisttest_d();
|
||||
threadlisttest_e();
|
||||
threadlisttest_f();
|
||||
|
||||
for (i=0; i<NUMNAMES; i++) {
|
||||
fakethread_destroy(fakethreads[i]);
|
||||
fakethreads[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < NUMNAMES; i++) {
|
||||
fakethread_destroy(fakethreads[i]);
|
||||
fakethreads[i] = NULL;
|
||||
}
|
||||
|
||||
kprintf("Done.\n");
|
||||
return 0;
|
||||
kprintf("Done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,35 +36,29 @@
|
||||
#include <synch.h>
|
||||
#include <test.h>
|
||||
|
||||
#define NTHREADS 8
|
||||
#define NTHREADS 8
|
||||
|
||||
static struct semaphore *tsem = NULL;
|
||||
|
||||
static
|
||||
void
|
||||
init_sem(void)
|
||||
{
|
||||
if (tsem==NULL) {
|
||||
tsem = sem_create("tsem", 0);
|
||||
if (tsem == NULL) {
|
||||
panic("threadtest: sem_create failed\n");
|
||||
}
|
||||
}
|
||||
static void init_sem(void) {
|
||||
if (tsem == NULL) {
|
||||
tsem = sem_create("tsem", 0);
|
||||
if (tsem == NULL) {
|
||||
panic("threadtest: sem_create failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
loudthread(void *junk, unsigned long num)
|
||||
{
|
||||
int ch = '0' + num;
|
||||
int i;
|
||||
static void loudthread(void *junk, unsigned long num) {
|
||||
int ch = '0' + num;
|
||||
int i;
|
||||
|
||||
(void)junk;
|
||||
(void)junk;
|
||||
|
||||
for (i=0; i<120; i++) {
|
||||
putch(ch);
|
||||
}
|
||||
V(tsem);
|
||||
for (i = 0; i < 120; i++) {
|
||||
putch(ch);
|
||||
}
|
||||
V(tsem);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -77,70 +71,58 @@ loudthread(void *junk, unsigned long num)
|
||||
* The delay loop is supposed to be long enough that it should be clear
|
||||
* if either timeslicing or the scheduler is not working right.
|
||||
*/
|
||||
static
|
||||
void
|
||||
quietthread(void *junk, unsigned long num)
|
||||
{
|
||||
int ch = '0' + num;
|
||||
volatile int i;
|
||||
static void quietthread(void *junk, unsigned long num) {
|
||||
int ch = '0' + num;
|
||||
volatile int i;
|
||||
|
||||
(void)junk;
|
||||
(void)junk;
|
||||
|
||||
putch(ch);
|
||||
for (i=0; i<200000; i++);
|
||||
putch(ch);
|
||||
putch(ch);
|
||||
for (i = 0; i < 200000; i++)
|
||||
;
|
||||
putch(ch);
|
||||
|
||||
V(tsem);
|
||||
V(tsem);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
runthreads(int doloud)
|
||||
{
|
||||
char name[16];
|
||||
int i, result;
|
||||
static void runthreads(int doloud) {
|
||||
char name[16];
|
||||
int i, result;
|
||||
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
snprintf(name, sizeof(name), "threadtest%d", i);
|
||||
result = thread_fork(name, NULL,
|
||||
doloud ? loudthread : quietthread,
|
||||
NULL, i);
|
||||
if (result) {
|
||||
panic("threadtest: thread_fork failed %s)\n",
|
||||
strerror(result));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
snprintf(name, sizeof(name), "threadtest%d", i);
|
||||
result =
|
||||
thread_fork(name, NULL, doloud ? loudthread : quietthread, NULL, i);
|
||||
if (result) {
|
||||
panic("threadtest: thread_fork failed %s)\n", strerror(result));
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<NTHREADS; i++) {
|
||||
P(tsem);
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
P(tsem);
|
||||
}
|
||||
}
|
||||
|
||||
int threadtest(int nargs, char **args) {
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
int
|
||||
threadtest(int nargs, char **args)
|
||||
{
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
init_sem();
|
||||
kprintf("Starting thread test...\n");
|
||||
runthreads(1);
|
||||
kprintf("\nThread test done.\n");
|
||||
|
||||
init_sem();
|
||||
kprintf("Starting thread test...\n");
|
||||
runthreads(1);
|
||||
kprintf("\nThread test done.\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
threadtest2(int nargs, char **args)
|
||||
{
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
int threadtest2(int nargs, char **args) {
|
||||
(void)nargs;
|
||||
(void)args;
|
||||
|
||||
init_sem();
|
||||
kprintf("Starting thread test 2...\n");
|
||||
runthreads(0);
|
||||
kprintf("\nThread test 2 done.\n");
|
||||
init_sem();
|
||||
kprintf("Starting thread test 2...\n");
|
||||
runthreads(0);
|
||||
kprintf("\nThread test 2 done.\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
338
kern/test/tt3.c
338
kern/test/tt3.c
@@ -42,12 +42,12 @@
|
||||
#define DIM 70
|
||||
|
||||
/* number of iterations for sleepalot threads */
|
||||
#define SLEEPALOT_PRINTS 20 /* number of printouts */
|
||||
#define SLEEPALOT_ITERS 4 /* iterations per printout */
|
||||
#define SLEEPALOT_PRINTS 20 /* number of printouts */
|
||||
#define SLEEPALOT_ITERS 4 /* iterations per printout */
|
||||
/* polling frequency of waker thread */
|
||||
#define WAKER_WAKES 100
|
||||
#define WAKER_WAKES 100
|
||||
/* number of iterations per compute thread */
|
||||
#define COMPUTE_ITERS 10
|
||||
#define COMPUTE_ITERS 10
|
||||
|
||||
/* N distinct wait channels */
|
||||
#define NWAITCHANS 12
|
||||
@@ -58,219 +58,191 @@ static volatile int wakerdone;
|
||||
static struct semaphore *wakersem;
|
||||
static struct semaphore *donesem;
|
||||
|
||||
static
|
||||
void
|
||||
setup(void)
|
||||
{
|
||||
char tmp[16];
|
||||
int i;
|
||||
static void setup(void) {
|
||||
char tmp[16];
|
||||
int i;
|
||||
|
||||
if (wakersem == NULL) {
|
||||
wakersem = sem_create("wakersem", 1);
|
||||
donesem = sem_create("donesem", 0);
|
||||
for (i=0; i<NWAITCHANS; i++) {
|
||||
spinlock_init(&spinlocks[i]);
|
||||
snprintf(tmp, sizeof(tmp), "wc%d", i);
|
||||
waitchans[i] = wchan_create(kstrdup(tmp));
|
||||
}
|
||||
}
|
||||
wakerdone = 0;
|
||||
if (wakersem == NULL) {
|
||||
wakersem = sem_create("wakersem", 1);
|
||||
donesem = sem_create("donesem", 0);
|
||||
for (i = 0; i < NWAITCHANS; i++) {
|
||||
spinlock_init(&spinlocks[i]);
|
||||
snprintf(tmp, sizeof(tmp), "wc%d", i);
|
||||
waitchans[i] = wchan_create(kstrdup(tmp));
|
||||
}
|
||||
}
|
||||
wakerdone = 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
sleepalot_thread(void *junk, unsigned long num)
|
||||
{
|
||||
int i, j;
|
||||
static void sleepalot_thread(void *junk, unsigned long num) {
|
||||
int i, j;
|
||||
|
||||
(void)junk;
|
||||
(void)junk;
|
||||
|
||||
for (i=0; i<SLEEPALOT_PRINTS; i++) {
|
||||
for (j=0; j<SLEEPALOT_ITERS; j++) {
|
||||
unsigned n;
|
||||
struct spinlock *lk;
|
||||
struct wchan *wc;
|
||||
for (i = 0; i < SLEEPALOT_PRINTS; i++) {
|
||||
for (j = 0; j < SLEEPALOT_ITERS; j++) {
|
||||
unsigned n;
|
||||
struct spinlock *lk;
|
||||
struct wchan *wc;
|
||||
|
||||
n = random() % NWAITCHANS;
|
||||
lk = &spinlocks[n];
|
||||
wc = waitchans[n];
|
||||
spinlock_acquire(lk);
|
||||
wchan_sleep(wc, lk);
|
||||
spinlock_release(lk);
|
||||
}
|
||||
kprintf("[%lu]", num);
|
||||
}
|
||||
V(donesem);
|
||||
n = random() % NWAITCHANS;
|
||||
lk = &spinlocks[n];
|
||||
wc = waitchans[n];
|
||||
spinlock_acquire(lk);
|
||||
wchan_sleep(wc, lk);
|
||||
spinlock_release(lk);
|
||||
}
|
||||
kprintf("[%lu]", num);
|
||||
}
|
||||
V(donesem);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
waker_thread(void *junk1, unsigned long junk2)
|
||||
{
|
||||
int i, done;
|
||||
static void waker_thread(void *junk1, unsigned long junk2) {
|
||||
int i, done;
|
||||
|
||||
(void)junk1;
|
||||
(void)junk2;
|
||||
(void)junk1;
|
||||
(void)junk2;
|
||||
|
||||
while (1) {
|
||||
P(wakersem);
|
||||
done = wakerdone;
|
||||
V(wakersem);
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
P(wakersem);
|
||||
done = wakerdone;
|
||||
V(wakersem);
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (i=0; i<WAKER_WAKES; i++) {
|
||||
unsigned n;
|
||||
struct spinlock *lk;
|
||||
struct wchan *wc;
|
||||
for (i = 0; i < WAKER_WAKES; i++) {
|
||||
unsigned n;
|
||||
struct spinlock *lk;
|
||||
struct wchan *wc;
|
||||
|
||||
n = random() % NWAITCHANS;
|
||||
lk = &spinlocks[n];
|
||||
wc = waitchans[n];
|
||||
spinlock_acquire(lk);
|
||||
wchan_wakeall(wc, lk);
|
||||
spinlock_release(lk);
|
||||
n = random() % NWAITCHANS;
|
||||
lk = &spinlocks[n];
|
||||
wc = waitchans[n];
|
||||
spinlock_acquire(lk);
|
||||
wchan_wakeall(wc, lk);
|
||||
spinlock_release(lk);
|
||||
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
V(donesem);
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
V(donesem);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
make_sleepalots(int howmany)
|
||||
{
|
||||
char name[16];
|
||||
int i, result;
|
||||
static void make_sleepalots(int howmany) {
|
||||
char name[16];
|
||||
int i, result;
|
||||
|
||||
for (i=0; i<howmany; i++) {
|
||||
snprintf(name, sizeof(name), "sleepalot%d", i);
|
||||
result = thread_fork(name, NULL, sleepalot_thread, NULL, i);
|
||||
if (result) {
|
||||
panic("thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
result = thread_fork("waker", NULL, waker_thread, NULL, 0);
|
||||
if (result) {
|
||||
panic("thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
for (i = 0; i < howmany; i++) {
|
||||
snprintf(name, sizeof(name), "sleepalot%d", i);
|
||||
result = thread_fork(name, NULL, sleepalot_thread, NULL, i);
|
||||
if (result) {
|
||||
panic("thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
result = thread_fork("waker", NULL, waker_thread, NULL, 0);
|
||||
if (result) {
|
||||
panic("thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
compute_thread(void *junk1, unsigned long num)
|
||||
{
|
||||
struct matrix {
|
||||
char m[DIM][DIM];
|
||||
};
|
||||
struct matrix *m1, *m2, *m3;
|
||||
unsigned char tot;
|
||||
int i, j, k, m;
|
||||
uint32_t rand;
|
||||
static void compute_thread(void *junk1, unsigned long num) {
|
||||
struct matrix {
|
||||
char m[DIM][DIM];
|
||||
};
|
||||
struct matrix *m1, *m2, *m3;
|
||||
unsigned char tot;
|
||||
int i, j, k, m;
|
||||
uint32_t rand;
|
||||
|
||||
(void)junk1;
|
||||
(void)junk1;
|
||||
|
||||
m1 = kmalloc(sizeof(struct matrix));
|
||||
KASSERT(m1 != NULL);
|
||||
m2 = kmalloc(sizeof(struct matrix));
|
||||
KASSERT(m2 != NULL);
|
||||
m3 = kmalloc(sizeof(struct matrix));
|
||||
KASSERT(m3 != NULL);
|
||||
m1 = kmalloc(sizeof(struct matrix));
|
||||
KASSERT(m1 != NULL);
|
||||
m2 = kmalloc(sizeof(struct matrix));
|
||||
KASSERT(m2 != NULL);
|
||||
m3 = kmalloc(sizeof(struct matrix));
|
||||
KASSERT(m3 != NULL);
|
||||
|
||||
for (m=0; m<COMPUTE_ITERS; m++) {
|
||||
for (m = 0; m < COMPUTE_ITERS; m++) {
|
||||
|
||||
for (i=0; i<DIM; i++) {
|
||||
for (j=0; j<DIM; j++) {
|
||||
rand = random();
|
||||
m1->m[i][j] = rand >> 16;
|
||||
m2->m[i][j] = rand & 0xffff;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < DIM; i++) {
|
||||
for (j = 0; j < DIM; j++) {
|
||||
rand = random();
|
||||
m1->m[i][j] = rand >> 16;
|
||||
m2->m[i][j] = rand & 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<DIM; i++) {
|
||||
for (j=0; j<DIM; j++) {
|
||||
tot = 0;
|
||||
for (k=0; k<DIM; k++) {
|
||||
tot += m1->m[i][k] * m2->m[k][j];
|
||||
}
|
||||
m3->m[i][j] = tot;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < DIM; i++) {
|
||||
for (j = 0; j < DIM; j++) {
|
||||
tot = 0;
|
||||
for (k = 0; k < DIM; k++) {
|
||||
tot += m1->m[i][k] * m2->m[k][j];
|
||||
}
|
||||
m3->m[i][j] = tot;
|
||||
}
|
||||
}
|
||||
|
||||
tot = 0;
|
||||
for (i=0; i<DIM; i++) {
|
||||
tot += m3->m[i][i];
|
||||
}
|
||||
tot = 0;
|
||||
for (i = 0; i < DIM; i++) {
|
||||
tot += m3->m[i][i];
|
||||
}
|
||||
|
||||
kprintf("{%lu: %u}", num, (unsigned) tot);
|
||||
thread_yield();
|
||||
}
|
||||
kprintf("{%lu: %u}", num, (unsigned)tot);
|
||||
thread_yield();
|
||||
}
|
||||
|
||||
kfree(m1);
|
||||
kfree(m2);
|
||||
kfree(m3);
|
||||
kfree(m1);
|
||||
kfree(m2);
|
||||
kfree(m3);
|
||||
|
||||
V(donesem);
|
||||
V(donesem);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
make_computes(int howmany)
|
||||
{
|
||||
char name[16];
|
||||
int i, result;
|
||||
static void make_computes(int howmany) {
|
||||
char name[16];
|
||||
int i, result;
|
||||
|
||||
for (i=0; i<howmany; i++) {
|
||||
snprintf(name, sizeof(name), "compute%d", i);
|
||||
result = thread_fork(name, NULL, compute_thread, NULL, i);
|
||||
if (result) {
|
||||
panic("thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < howmany; i++) {
|
||||
snprintf(name, sizeof(name), "compute%d", i);
|
||||
result = thread_fork(name, NULL, compute_thread, NULL, i);
|
||||
if (result) {
|
||||
panic("thread_fork failed: %s\n", strerror(result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
finish(int howmanytotal)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<howmanytotal; i++) {
|
||||
P(donesem);
|
||||
}
|
||||
P(wakersem);
|
||||
wakerdone = 1;
|
||||
V(wakersem);
|
||||
P(donesem);
|
||||
static void finish(int howmanytotal) {
|
||||
int i;
|
||||
for (i = 0; i < howmanytotal; i++) {
|
||||
P(donesem);
|
||||
}
|
||||
P(wakersem);
|
||||
wakerdone = 1;
|
||||
V(wakersem);
|
||||
P(donesem);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
runtest3(int nsleeps, int ncomputes)
|
||||
{
|
||||
setup();
|
||||
kprintf("Starting thread test 3 (%d [sleepalots], %d {computes}, "
|
||||
"1 waker)\n",
|
||||
nsleeps, ncomputes);
|
||||
make_sleepalots(nsleeps);
|
||||
make_computes(ncomputes);
|
||||
finish(nsleeps+ncomputes);
|
||||
kprintf("\nThread test 3 done\n");
|
||||
static void runtest3(int nsleeps, int ncomputes) {
|
||||
setup();
|
||||
kprintf("Starting thread test 3 (%d [sleepalots], %d {computes}, "
|
||||
"1 waker)\n",
|
||||
nsleeps, ncomputes);
|
||||
make_sleepalots(nsleeps);
|
||||
make_computes(ncomputes);
|
||||
finish(nsleeps + ncomputes);
|
||||
kprintf("\nThread test 3 done\n");
|
||||
}
|
||||
|
||||
int
|
||||
threadtest3(int nargs, char **args)
|
||||
{
|
||||
if (nargs==1) {
|
||||
runtest3(5, 2);
|
||||
}
|
||||
else if (nargs==3) {
|
||||
runtest3(atoi(args[1]), atoi(args[2]));
|
||||
}
|
||||
else {
|
||||
kprintf("Usage: tt3 [sleepthreads computethreads]\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
int threadtest3(int nargs, char **args) {
|
||||
if (nargs == 1) {
|
||||
runtest3(5, 2);
|
||||
} else if (nargs == 3) {
|
||||
runtest3(atoi(args[1]), atoi(args[2]));
|
||||
} else {
|
||||
kprintf("Usage: tt3 [sleepthreads computethreads]\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user