/branches/network/kernel/test/mm/falloc1.c |
---|
36,12 → 36,13 |
#include <debug.h> |
#include <align.h> |
#define MAX_FRAMES 1024 |
#define MAX_ORDER 8 |
#define TEST_RUNS 2 |
#define MAX_FRAMES 1024 |
#define MAX_ORDER 8 |
#define TEST_RUNS 2 |
char * test_falloc1(bool quiet) { |
uintptr_t * frames = (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), 0); |
char *test_falloc1(void) { |
uintptr_t *frames |
= (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), 0); |
int results[MAX_ORDER + 1]; |
int i, order, run; |
52,11 → 53,10 |
if (frames == NULL) |
return "Unable to allocate frames"; |
for (run = 0; run < TEST_RUNS; run++) { |
for (order = 0; order <= MAX_ORDER; order++) { |
if (!quiet) |
printf("Allocating %d frames blocks ... ", 1 << order); |
TPRINTF("Allocating %d frames blocks ... ", 1 << order); |
allocated = 0; |
for (i = 0; i < MAX_FRAMES >> order; i++) { |
63,8 → 63,7 |
frames[allocated] = (uintptr_t) frame_alloc(order, FRAME_ATOMIC | FRAME_KA); |
if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) != frames[allocated]) { |
if (!quiet) |
printf("Block at address %p (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10); |
TPRINTF("Block at address %p (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10); |
return "Test failed"; |
} |
71,15 → 70,13 |
if (frames[allocated]) |
allocated++; |
else { |
if (!quiet) |
printf("done. "); |
TPRINTF("done. "); |
break; |
} |
} |
if (!quiet) |
printf("%d blocks allocated.\n", allocated); |
TPRINTF("%d blocks allocated.\n", allocated); |
if (run) { |
if (results[order] != allocated) |
return "Possible frame leak"; |
86,17 → 83,15 |
} else |
results[order] = allocated; |
if (!quiet) |
printf("Deallocating ... "); |
TPRINTF("Deallocating ... "); |
for (i = 0; i < allocated; i++) |
frame_free(KA2PA(frames[i])); |
if (!quiet) |
printf("done.\n"); |
TPRINTF("done.\n"); |
} |
} |
free(frames); |
return NULL; |
/branches/network/kernel/test/mm/falloc2.c |
---|
39,17 → 39,16 |
#include <memstr.h> |
#include <arch.h> |
#define MAX_FRAMES 256 |
#define MAX_ORDER 8 |
#define MAX_FRAMES 256 |
#define MAX_ORDER 8 |
#define THREAD_RUNS 1 |
#define THREADS 8 |
#define THREAD_RUNS 1 |
#define THREADS 8 |
static atomic_t thread_count; |
static atomic_t thread_fail; |
static bool sh_quiet; |
static void falloc(void * arg) |
static void falloc(void *arg) |
{ |
int order, run, allocated, i; |
uint8_t val = THREAD->tid % THREADS; |
57,8 → 56,7 |
void **frames = (void **) malloc(MAX_FRAMES * sizeof(void *), FRAME_ATOMIC); |
if (frames == NULL) { |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Unable to allocate frames\n", THREAD->tid, CPU->id); |
TPRINTF("Thread #%" PRIu64 " (cpu%u): Unable to allocate frames\n", THREAD->tid, CPU->id); |
atomic_inc(&thread_fail); |
atomic_dec(&thread_count); |
return; |
65,11 → 63,10 |
} |
thread_detach(THREAD); |
for (run = 0; run < THREAD_RUNS; run++) { |
for (order = 0; order <= MAX_ORDER; order++) { |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order); |
TPRINTF("Thread #%" PRIu64 " (cpu%u): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order); |
allocated = 0; |
for (i = 0; i < (MAX_FRAMES >> order); i++) { |
81,17 → 78,13 |
break; |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated); |
TPRINTF("Thread #%" PRIu64 " (cpu%u): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated); |
TPRINTF("Thread #%" PRIu64 " (cpu%u): Deallocating ... \n", THREAD->tid, CPU->id); |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Deallocating ... \n", THREAD->tid, CPU->id); |
for (i = 0; i < allocated; i++) { |
for (k = 0; k <= (((index_t) FRAME_SIZE << order) - 1); k++) { |
if (((uint8_t *) frames[i])[k] != val) { |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %#" PRIi "\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k); |
TPRINTF("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %#" PRIi "\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k); |
atomic_inc(&thread_fail); |
goto cleanup; |
} |
99,32 → 92,28 |
frame_free(KA2PA(frames[i])); |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Finished run.\n", THREAD->tid, CPU->id); |
TPRINTF("Thread #%" PRIu64 " (cpu%u): Finished run.\n", THREAD->tid, CPU->id); |
} |
} |
cleanup: |
cleanup: |
free(frames); |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Exiting\n", THREAD->tid, CPU->id); |
TPRINTF("Thread #%" PRIu64 " (cpu%u): Exiting\n", THREAD->tid, CPU->id); |
atomic_dec(&thread_count); |
} |
char * test_falloc2(bool quiet) |
char *test_falloc2(void) |
{ |
unsigned int i; |
sh_quiet = quiet; |
atomic_set(&thread_count, THREADS); |
atomic_set(&thread_fail, 0); |
for (i = 0; i < THREADS; i++) { |
thread_t * thrd = thread_create(falloc, NULL, TASK, 0, "falloc", false); |
if (!thrd) { |
if (!quiet) |
printf("Could not create thread %u\n", i); |
TPRINTF("Could not create thread %u\n", i); |
break; |
} |
thread_ready(thrd); |
131,8 → 120,7 |
} |
while (atomic_get(&thread_count) > 0) { |
if (!quiet) |
printf("Threads left: %ld\n", atomic_get(&thread_count)); |
TPRINTF("Threads left: %ld\n", atomic_get(&thread_count)); |
thread_sleep(1); |
} |
/branches/network/kernel/test/mm/slab1.c |
---|
33,23 → 33,21 |
#include <arch.h> |
#include <memstr.h> |
#define VAL_COUNT 1024 |
#define VAL_COUNT 1024 |
static void * data[VAL_COUNT]; |
static void *data[VAL_COUNT]; |
static void testit(int size, int count, bool quiet) |
static void testit(int size, int count) |
{ |
slab_cache_t *cache; |
int i; |
if (!quiet) |
printf("Creating cache, object size: %d.\n", size); |
TPRINTF("Creating cache, object size: %d.\n", size); |
cache = slab_cache_create("test_cache", size, 0, NULL, NULL, |
SLAB_CACHE_NOMAGAZINE); |
SLAB_CACHE_NOMAGAZINE); |
if (!quiet) |
printf("Allocating %d items...", count); |
TPRINTF("Allocating %d items...", count); |
for (i = 0; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
56,78 → 54,71 |
memsetb(data[i], size, 0); |
} |
if (!quiet) { |
printf("done.\n"); |
printf("Freeing %d items...", count); |
} |
TPRINTF("done.\n"); |
TPRINTF("Freeing %d items...", count); |
for (i = 0; i < count; i++) |
slab_free(cache, data[i]); |
if (!quiet) { |
printf("done.\n"); |
printf("Allocating %d items...", count); |
} |
TPRINTF("done.\n"); |
TPRINTF("Allocating %d items...", count); |
for (i = 0; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
memsetb(data[i], size, 0); |
} |
if (!quiet) { |
printf("done.\n"); |
printf("Freeing %d items...", count / 2); |
} |
TPRINTF("done.\n"); |
TPRINTF("Freeing %d items...", count / 2); |
for (i = count - 1; i >= count / 2; i--) |
slab_free(cache, data[i]); |
if (!quiet) { |
printf("done.\n"); |
printf("Allocating %d items...", count / 2); |
} |
TPRINTF("done.\n"); |
TPRINTF("Allocating %d items...", count / 2); |
for (i = count / 2; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
memsetb(data[i], size, 0); |
} |
if (!quiet) { |
printf("done.\n"); |
printf("Freeing %d items...", count); |
} |
TPRINTF("done.\n"); |
TPRINTF("Freeing %d items...", count); |
for (i = 0; i < count; i++) |
slab_free(cache, data[i]); |
if (!quiet) |
printf("done.\n"); |
TPRINTF("done.\n"); |
slab_cache_destroy(cache); |
if (!quiet) |
printf("Test complete.\n"); |
TPRINTF("Test complete.\n"); |
} |
static void testsimple(bool quiet) |
static void testsimple(void) |
{ |
testit(100, VAL_COUNT, quiet); |
testit(200, VAL_COUNT, quiet); |
testit(1024, VAL_COUNT, quiet); |
testit(2048, 512, quiet); |
testit(4000, 128, quiet); |
testit(8192, 128, quiet); |
testit(16384, 128, quiet); |
testit(16385, 128, quiet); |
testit(100, VAL_COUNT); |
testit(200, VAL_COUNT); |
testit(1024, VAL_COUNT); |
testit(2048, 512); |
testit(4000, 128); |
testit(8192, 128); |
testit(16384, 128); |
testit(16385, 128); |
} |
#define THREADS 6 |
#define THR_MEM_COUNT 1024 |
#define THR_MEM_SIZE 128 |
#define THREADS 6 |
#define THR_MEM_COUNT 1024 |
#define THR_MEM_SIZE 128 |
static void * thr_data[THREADS][THR_MEM_COUNT]; |
static void *thr_data[THREADS][THR_MEM_COUNT]; |
static slab_cache_t *thr_cache; |
static semaphore_t thr_sem; |
static bool sh_quiet; |
static void slabtest(void *data) |
{ |
136,8 → 127,7 |
thread_detach(THREAD); |
if (!sh_quiet) |
printf("Starting thread #%" PRIu64 "...\n", THREAD->tid); |
TPRINTF("Starting thread #%" PRIu64 "...\n", THREAD->tid); |
for (j = 0; j < 10; j++) { |
for (i = 0; i < THR_MEM_COUNT; i++) |
150,24 → 140,23 |
slab_free(thr_cache, thr_data[offs][i]); |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " finished\n", THREAD->tid); |
TPRINTF("Thread #%" PRIu64 " finished\n", THREAD->tid); |
semaphore_up(&thr_sem); |
} |
static void testthreads(bool quiet) |
static void testthreads(void) |
{ |
thread_t *t; |
int i; |
thr_cache = slab_cache_create("thread_cache", THR_MEM_SIZE, 0, NULL, NULL, |
SLAB_CACHE_NOMAGAZINE); |
SLAB_CACHE_NOMAGAZINE); |
semaphore_initialize(&thr_sem, 0); |
for (i = 0; i < THREADS; i++) { |
if (!(t = thread_create(slabtest, (void *) (unative_t) i, TASK, 0, "slabtest", false))) { |
if (!quiet) |
printf("Could not create thread %d\n", i); |
TPRINTF("Could not create thread %d\n", i); |
} else |
thread_ready(t); |
} |
177,16 → 166,13 |
slab_cache_destroy(thr_cache); |
if (!quiet) |
printf("Test complete.\n"); |
TPRINTF("Test complete.\n"); |
} |
char * test_slab1(bool quiet) |
char *test_slab1(void) |
{ |
sh_quiet = quiet; |
testsimple(); |
testthreads(); |
testsimple(quiet); |
testthreads(quiet); |
return NULL; |
} |
/branches/network/kernel/test/mm/purge1.c |
---|
39,7 → 39,7 |
extern void tlb_invalidate_all(void); |
extern void tlb_invalidate_pages(asid_t asid, uintptr_t va, count_t cnt); |
char * test_purge1(bool quiet) |
char *test_purge1(void) |
{ |
tlb_entry_t entryi; |
tlb_entry_t entryd; |
/branches/network/kernel/test/mm/slab2.c |
---|
36,18 → 36,18 |
#include <synch/condvar.h> |
#include <synch/mutex.h> |
#define ITEM_SIZE 256 |
#define ITEM_SIZE 256 |
/** Fill memory with 2 caches, when allocation fails, |
* free one of the caches. We should have everything in magazines, |
* now allocation should clean magazines and allow for full allocation. |
*/ |
static void totalmemtest(bool quiet) |
static void totalmemtest(void) |
{ |
slab_cache_t *cache1; |
slab_cache_t *cache2; |
int i; |
void *data1, *data2; |
void *olddata1 = NULL, *olddata2 = NULL; |
54,8 → 54,7 |
cache1 = slab_cache_create("cache1_tst", ITEM_SIZE, 0, NULL, NULL, 0); |
cache2 = slab_cache_create("cache2_tst", ITEM_SIZE, 0, NULL, NULL, 0); |
if (!quiet) |
printf("Allocating..."); |
TPRINTF("Allocating..."); |
/* Use atomic alloc, so that we find end of memory */ |
do { |
74,13 → 73,12 |
*((void **) data2) = olddata2; |
olddata1 = data1; |
olddata2 = data2; |
} while (1); |
} while (true); |
if (!quiet) { |
printf("done.\n"); |
printf("Deallocating cache2..."); |
} |
TPRINTF("done.\n"); |
TPRINTF("Deallocating cache2..."); |
/* We do not have memory - now deallocate cache2 */ |
while (olddata2) { |
data2 = *((void **) olddata2); |
88,16 → 86,14 |
olddata2 = data2; |
} |
if (!quiet) { |
printf("done.\n"); |
printf("Allocating to cache1...\n"); |
} |
TPRINTF("done.\n"); |
TPRINTF("Allocating to cache1...\n"); |
for (i = 0; i < 30; i++) { |
data1 = slab_alloc(cache1, FRAME_ATOMIC); |
if (!data1) { |
if (!quiet) |
printf("Incorrect memory size - use another test."); |
TPRINTF("Incorrect memory size - use another test."); |
return; |
} |
memsetb(data1, ITEM_SIZE, 0); |
104,7 → 100,7 |
*((void **) data1) = olddata1; |
olddata1 = data1; |
} |
while (1) { |
while (true) { |
data1 = slab_alloc(cache1, FRAME_ATOMIC); |
if (!data1) |
break; |
113,8 → 109,7 |
olddata1 = data1; |
} |
if (!quiet) |
printf("Deallocating cache1..."); |
TPRINTF("Deallocating cache1..."); |
while (olddata1) { |
data1 = *((void **) olddata1); |
122,10 → 117,10 |
olddata1 = data1; |
} |
if (!quiet) { |
printf("done.\n"); |
TPRINTF("done.\n"); |
if (!test_quiet) |
slab_print_list(); |
} |
slab_cache_destroy(cache1); |
slab_cache_destroy(cache2); |
135,9 → 130,8 |
static semaphore_t thr_sem; |
static condvar_t thread_starter; |
static mutex_t starter_mutex; |
static bool sh_quiet; |
#define THREADS 8 |
#define THREADS 8 |
static void slabtest(void *priv) |
{ |
149,14 → 143,12 |
condvar_wait(&thread_starter,&starter_mutex); |
mutex_unlock(&starter_mutex); |
if (!sh_quiet) |
printf("Starting thread #%" PRIu64 "...\n", THREAD->tid); |
TPRINTF("Starting thread #%" PRIu64 "...\n", THREAD->tid); |
/* Alloc all */ |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " allocating...\n", THREAD->tid); |
TPRINTF("Thread #%" PRIu64 " allocating...\n", THREAD->tid); |
while (1) { |
while (true) { |
/* Call with atomic to detect end of memory */ |
new = slab_alloc(thr_cache, FRAME_ATOMIC); |
if (!new) |
165,8 → 157,7 |
data = new; |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " releasing...\n", THREAD->tid); |
TPRINTF("Thread #%" PRIu64 " releasing...\n", THREAD->tid); |
while (data) { |
new = *((void **)data); |
175,10 → 166,9 |
data = new; |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " allocating...\n", THREAD->tid); |
TPRINTF("Thread #%" PRIu64 " allocating...\n", THREAD->tid); |
while (1) { |
while (true) { |
/* Call with atomic to detect end of memory */ |
new = slab_alloc(thr_cache, FRAME_ATOMIC); |
if (!new) |
187,8 → 177,7 |
data = new; |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " releasing...\n", THREAD->tid); |
TPRINTF("Thread #%" PRIu64 " releasing...\n", THREAD->tid); |
while (data) { |
new = *((void **)data); |
197,14 → 186,15 |
data = new; |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " finished\n", THREAD->tid); |
TPRINTF("Thread #%" PRIu64 " finished\n", THREAD->tid); |
slab_print_list(); |
if (!test_quiet) |
slab_print_list(); |
semaphore_up(&thr_sem); |
} |
static void multitest(int size, bool quiet) |
static void multitest(int size) |
{ |
/* Start 8 threads that just allocate as much as possible, |
* then release everything, then again allocate, then release |
212,48 → 202,42 |
thread_t *t; |
int i; |
if (!quiet) |
printf("Running stress test with size %d\n", size); |
TPRINTF("Running stress test with size %d\n", size); |
condvar_initialize(&thread_starter); |
mutex_initialize(&starter_mutex, MUTEX_PASSIVE); |
thr_cache = slab_cache_create("thread_cache", size, 0, NULL, NULL, 0); |
semaphore_initialize(&thr_sem,0); |
for (i = 0; i < THREADS; i++) { |
if (!(t = thread_create(slabtest, NULL, TASK, 0, "slabtest", false))) { |
if (!quiet) |
printf("Could not create thread %d\n", i); |
TPRINTF("Could not create thread %d\n", i); |
} else |
thread_ready(t); |
} |
thread_sleep(1); |
condvar_broadcast(&thread_starter); |
for (i = 0; i < THREADS; i++) |
semaphore_down(&thr_sem); |
slab_cache_destroy(thr_cache); |
if (!quiet) |
printf("Stress test complete.\n"); |
TPRINTF("Stress test complete.\n"); |
} |
char * test_slab2(bool quiet) |
char *test_slab2(void) |
{ |
sh_quiet = quiet; |
TPRINTF("Running reclaim single-thread test .. pass 1\n"); |
totalmemtest(); |
if (!quiet) |
printf("Running reclaim single-thread test .. pass 1\n"); |
totalmemtest(quiet); |
if (!quiet) |
printf("Running reclaim single-thread test .. pass 2\n"); |
totalmemtest(quiet); |
if (!quiet) |
printf("Reclaim test OK.\n"); |
TPRINTF("Running reclaim single-thread test .. pass 2\n"); |
totalmemtest(); |
multitest(128, quiet); |
multitest(2048, quiet); |
multitest(8192, quiet); |
TPRINTF("Reclaim test OK.\n"); |
multitest(128); |
multitest(2048); |
multitest(8192); |
return NULL; |
} |
/branches/network/kernel/test/mm/purge1_skip.c |
---|
28,7 → 28,7 |
#include <test.h> |
char *test_purge1(bool quiet) |
char *test_purge1(void) |
{ |
return NULL; |
} |
/branches/network/kernel/test/mm/mapping1.c |
---|
35,40 → 35,36 |
#include <arch/types.h> |
#include <debug.h> |
#define PAGE0 0x10000000 |
#define PAGE1 (PAGE0+PAGE_SIZE) |
#define PAGE0 0x10000000 |
#define PAGE1 (PAGE0 + PAGE_SIZE) |
#define VALUE0 0x01234567 |
#define VALUE1 0x89abcdef |
#define VALUE0 0x01234567 |
#define VALUE1 0x89abcdef |
char * test_mapping1(bool quiet) |
char *test_mapping1(void) |
{ |
uintptr_t frame0, frame1; |
uint32_t v0, v1; |
frame0 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA); |
frame1 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA); |
if (!quiet) |
printf("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0)); |
TPRINTF("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0)); |
*((uint32_t *) frame0) = VALUE0; |
if (!quiet) |
printf("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1)); |
TPRINTF("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1)); |
*((uint32_t *) frame1) = VALUE1; |
if (!quiet) |
printf("Mapping virtual address %p to physical address %p.\n", PAGE0, KA2PA(frame0)); |
TPRINTF("Mapping virtual address %p to physical address %p.\n", PAGE0, KA2PA(frame0)); |
page_mapping_insert(AS_KERNEL, PAGE0, KA2PA(frame0), PAGE_PRESENT | PAGE_WRITE); |
if (!quiet) |
printf("Mapping virtual address %p to physical address %p.\n", PAGE1, KA2PA(frame1)); |
TPRINTF("Mapping virtual address %p to physical address %p.\n", PAGE1, KA2PA(frame1)); |
page_mapping_insert(AS_KERNEL, PAGE1, KA2PA(frame1), PAGE_PRESENT | PAGE_WRITE); |
v0 = *((uint32_t *) PAGE0); |
v1 = *((uint32_t *) PAGE1); |
if (!quiet) { |
printf("Value at virtual address %p is %#x.\n", PAGE0, v0); |
printf("Value at virtual address %p is %#x.\n", PAGE1, v1); |
} |
TPRINTF("Value at virtual address %p is %#x.\n", PAGE0, v0); |
TPRINTF("Value at virtual address %p is %#x.\n", PAGE1, v1); |
if (v0 != VALUE0) |
return "Value at v0 not equal to VALUE0"; |
75,25 → 71,22 |
if (v1 != VALUE1) |
return "Value at v1 not equal to VALUE1"; |
if (!quiet) |
printf("Writing %#x to virtual address %p.\n", 0, PAGE0); |
TPRINTF("Writing %#x to virtual address %p.\n", 0, PAGE0); |
*((uint32_t *) PAGE0) = 0; |
if (!quiet) |
printf("Writing %#x to virtual address %p.\n", 0, PAGE1); |
*((uint32_t *) PAGE1) = 0; |
TPRINTF("Writing %#x to virtual address %p.\n", 0, PAGE1); |
*((uint32_t *) PAGE1) = 0; |
v0 = *((uint32_t *) PAGE0); |
v1 = *((uint32_t *) PAGE1); |
if (!quiet) { |
printf("Value at virtual address %p is %#x.\n", PAGE0, *((uint32_t *) PAGE0)); |
printf("Value at virtual address %p is %#x.\n", PAGE1, *((uint32_t *) PAGE1)); |
} |
TPRINTF("Value at virtual address %p is %#x.\n", PAGE0, *((uint32_t *) PAGE0)); |
TPRINTF("Value at virtual address %p is %#x.\n", PAGE1, *((uint32_t *) PAGE1)); |
if (v0 != 0) |
return "Value at v0 not equal to 0"; |
if (v1 != 0) |
return "Value at v1 not equal to 0"; |
return NULL; |
return NULL; |
} |