clang-format

This commit is contained in:
2024-09-10 13:03:02 -04:00
parent 53c617d779
commit d66450e427
381 changed files with 28864 additions and 34170 deletions

View File

@@ -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;
}

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}