Process reference counting
[akaros.git] / kern / src / testing.c
1
2 #ifdef __SHARC__
3 #pragma nosharc
4 #endif
5
6 #include <arch/mmu.h>
7 #include <arch/arch.h>
8 #include <arch/bitmask.h>
9 #include <smp.h>
10
11 #include <ros/memlayout.h>
12 #include <ros/common.h>
13
14 #include <atomic.h>
15 #include <stdio.h>
16 #include <assert.h>
17 #include <string.h>
18 #include <testing.h>
19 #include <trap.h>
20 #include <arch/trap.h>
21 #include <process.h>
22 #include <syscall.h>
23 #include <timing.h>
24 #include <kfs.h>
25 #include <multiboot.h>
26 #include <pmap.h>
27 #include <page_alloc.h>
28 #include <pmap.h>
29 #include <slab.h>
30 #include <kmalloc.h>
31 #include <hashtable.h>
32
33 #ifdef __i386__
34
35 void test_ipi_sending(void)
36 {
37         extern handler_t (CT(NUM_INTERRUPT_HANDLERS) RO interrupt_handlers)[];
38         int8_t state = 0;
39
40         register_interrupt_handler(interrupt_handlers, I_TESTING,
41                                    test_hello_world_handler, NULL);
42         enable_irqsave(&state);
43         cprintf("\nCORE 0 sending broadcast\n");
44         send_broadcast_ipi(I_TESTING);
45         udelay(3000000);
46         cprintf("\nCORE 0 sending all others\n");
47         send_all_others_ipi(I_TESTING);
48         udelay(3000000);
49         cprintf("\nCORE 0 sending self\n");
50         send_self_ipi(I_TESTING);
51         udelay(3000000);
52         cprintf("\nCORE 0 sending ipi to physical 1\n");
53         send_ipi(0x01, 0, I_TESTING);
54         udelay(3000000);
55         cprintf("\nCORE 0 sending ipi to physical 2\n");
56         send_ipi(0x02, 0, I_TESTING);
57         udelay(3000000);
58         cprintf("\nCORE 0 sending ipi to physical 3\n");
59         send_ipi(0x03, 0, I_TESTING);
60         udelay(3000000);
61         cprintf("\nCORE 0 sending ipi to physical 15\n");
62         send_ipi(0x0f, 0, I_TESTING);
63         udelay(3000000);
64         cprintf("\nCORE 0 sending ipi to logical 2\n");
65         send_ipi(0x02, 1, I_TESTING);
66         udelay(3000000);
67         cprintf("\nCORE 0 sending ipi to logical 1\n");
68         send_ipi(0x01, 1, I_TESTING);
69         udelay(3000000);
70         cprintf("\nDone!\n");
71         disable_irqsave(&state);
72 }
73
74 // Note this never returns and will muck with any other timer work
75 void test_pic_reception(void)
76 {
77         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, NULL);
78         pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
79         pic_unmask_irq(0);
80         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
81         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
82         unmask_lapic_lvt(LAPIC_LVT_LINT0);
83         cprintf("Core %d's LINT0: 0x%08x\n", core_id(), read_mmreg32(LAPIC_LVT_LINT0));
84         enable_irq();
85         while(1);
86 }
87
88 void test_ioapic_pit_reroute(void) 
89 {
90         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, NULL);
91         ioapic_route_irq(0, 3); 
92
93         cprintf("Starting pit on core 3....\n");
94         udelay(3000000);
95         pit_set_timer(0xFFFE,TIMER_RATEGEN); // totally arbitrary time
96         
97         udelay(3000000);
98         ioapic_unroute_irq(0);
99         udelay(300000);
100         cprintf("Masked pit. Waiting before return...\n");
101         udelay(3000000);
102 }
103
104 #endif // __i386__
105
106
107 void test_print_info(void)
108 {
109         cprintf("\nCORE 0 asking all cores to print info:\n");
110         smp_call_function_all(test_print_info_handler, NULL, 0);
111         cprintf("\nDone!\n");
112 }
113
114 void test_page_coloring(void) 
115 {
116         //Print the different cache properties of our machine
117         print_cache_properties("L1", &l1);
118         cprintf("\n");
119         print_cache_properties("L2", &l2);
120         cprintf("\n");
121         print_cache_properties("L3", &l3);
122         cprintf("\n");
123
124         //Print some stats about our memory
125         cprintf("Max Address: %llu\n", MAX_VADDR);
126         cprintf("Num Pages: %u\n", npages);
127
128         //Declare a local variable for allocating pages 
129         page_t* page;
130
131         cprintf("Contents of the page free list:\n");
132         for(int i=0; i<llc_num_colors; i++) {
133                 cprintf("  COLOR %d:\n", i);
134                 LIST_FOREACH(page, &colored_page_free_list[i], page_link) {
135                         cprintf("    Page: %d\n", page2ppn(page));
136                 }
137         }
138
139         //Run through and allocate all pages through l1_page_alloc
140         cprintf("Allocating from L1 page colors:\n");
141         for(int i=0; i<get_cache_num_page_colors(&l1); i++) {
142                 cprintf("  COLOR %d:\n", i);
143                 while(l1_page_alloc(&page, i) != -ENOMEM)
144                         cprintf("    Page: %d\n", page2ppn(page));
145         }
146
147         //Put all the pages back by reinitializing
148         page_init();
149         
150         //Run through and allocate all pages through l2_page_alloc
151         cprintf("Allocating from L2 page colors:\n");
152         for(int i=0; i<get_cache_num_page_colors(&l2); i++) {
153                 cprintf("  COLOR %d:\n", i);
154                 while(l2_page_alloc(&page, i) != -ENOMEM)
155                         cprintf("    Page: %d\n", page2ppn(page));
156         }
157
158         //Put all the pages back by reinitializing
159         page_init();
160         
161         //Run through and allocate all pages through l3_page_alloc
162         cprintf("Allocating from L3 page colors:\n");
163         for(int i=0; i<get_cache_num_page_colors(&l3); i++) {
164                 cprintf("  COLOR %d:\n", i);
165                 while(l3_page_alloc(&page, i) != -ENOMEM)
166                         cprintf("    Page: %d\n", page2ppn(page));
167         }
168         
169         //Put all the pages back by reinitializing
170         page_init();
171         
172         //Run through and allocate all pages through page_alloc
173         cprintf("Allocating from global allocator:\n");
174         while(page_alloc(&page) != -ENOMEM)
175                 cprintf("    Page: %d\n", page2ppn(page));
176         
177         if(l2_page_alloc(&page, 0) != -ENOMEM)
178                 cprintf("Should not get here, all pages should already be gone!\n");
179         cprintf("All pages gone for sure...\n");
180         
181         //Now lets put a few pages back using page_free..
182         cprintf("Reinserting pages via page_free and reallocating them...\n");
183         page_free(&pages[0]);
184         page_free(&pages[15]);
185         page_free(&pages[7]);
186         page_free(&pages[6]);
187         page_free(&pages[4]);
188
189         while(page_alloc(&page) != -ENOMEM)
190                 cprintf("Page: %d\n", page2ppn(page));  
191 }
192
193 barrier_t test_cpu_array;
194
195 void test_barrier(void)
196 {
197         cprintf("Core 0 initializing barrier\n");
198         init_barrier(&test_cpu_array, num_cpus);
199         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
200         smp_call_function_all(test_barrier_handler, NULL, 0);
201 }
202
203 void test_interrupts_irqsave(void)
204 {
205         int8_t state = 0;
206         printd("Testing Nesting Enabling first, turning ints off:\n");
207         disable_irq();
208         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
209         assert(!irq_is_enabled());
210         printd("Enabling IRQSave\n");
211         enable_irqsave(&state);
212         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
213         assert(irq_is_enabled());
214         printd("Enabling IRQSave Again\n");
215         enable_irqsave(&state);
216         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
217         assert(irq_is_enabled());
218         printd("Disabling IRQSave Once\n");
219         disable_irqsave(&state);
220         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
221         assert(irq_is_enabled());
222         printd("Disabling IRQSave Again\n");
223         disable_irqsave(&state);
224         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
225         assert(!irq_is_enabled());
226         printd("Done.  Should have been 0, 200, 200, 200, 0\n");
227
228         printd("Testing Nesting Disabling first, turning ints on:\n");
229         state = 0;
230         enable_irq();
231         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
232         assert(irq_is_enabled());
233         printd("Disabling IRQSave Once\n");
234         disable_irqsave(&state);
235         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
236         assert(!irq_is_enabled());
237         printd("Disabling IRQSave Again\n");
238         disable_irqsave(&state);
239         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
240         assert(!irq_is_enabled());
241         printd("Enabling IRQSave Once\n");
242         enable_irqsave(&state);
243         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
244         assert(!irq_is_enabled());
245         printd("Enabling IRQSave Again\n");
246         enable_irqsave(&state);
247         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
248         assert(irq_is_enabled());
249         printd("Done.  Should have been 200, 0, 0, 0, 200 \n");
250
251         state = 0;
252         disable_irq();
253         printd("Ints are off, enabling then disabling.\n");
254         enable_irqsave(&state);
255         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
256         assert(irq_is_enabled());
257         disable_irqsave(&state);
258         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
259         assert(!irq_is_enabled());
260         printd("Done.  Should have been 200, 0\n");
261
262         state = 0;
263         enable_irq();
264         printd("Ints are on, enabling then disabling.\n");
265         enable_irqsave(&state);
266         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
267         assert(irq_is_enabled());
268         disable_irqsave(&state);
269         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
270         assert(irq_is_enabled());
271         printd("Done.  Should have been 200, 200\n");
272
273         state = 0;
274         disable_irq();
275         printd("Ints are off, disabling then enabling.\n");
276         disable_irqsave(&state);
277         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
278         assert(!irq_is_enabled());
279         enable_irqsave(&state);
280         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
281         assert(!irq_is_enabled());
282         printd("Done.  Should have been 0, 0\n");
283
284         state = 0;
285         enable_irq();
286         printd("Ints are on, disabling then enabling.\n");
287         disable_irqsave(&state);
288         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
289         assert(!irq_is_enabled());
290         enable_irqsave(&state);
291         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
292         assert(irq_is_enabled());
293         printd("Done.  Should have been 0, 200\n");
294
295         disable_irq();
296         cprintf("Passed enable_irqsave tests\n");
297 }
298
299 void test_bitmasks(void)
300 {
301 #define masksize 67
302         DECL_BITMASK(mask, masksize);
303         printk("size of mask %d\n", sizeof(mask));
304         CLR_BITMASK(mask, masksize);
305         PRINT_BITMASK(mask, masksize);
306         printk("cleared\n");
307         SET_BITMASK_BIT(mask, 0);
308         SET_BITMASK_BIT(mask, 11);
309         SET_BITMASK_BIT(mask, 17);
310         SET_BITMASK_BIT(mask, masksize-1);
311         printk("bits set\n");
312         PRINT_BITMASK(mask, masksize);
313         DECL_BITMASK(mask2, masksize);
314         COPY_BITMASK(mask2, mask, masksize);
315         printk("copy of original mask, should be the same as the prev\n");
316         PRINT_BITMASK(mask2, masksize);
317         CLR_BITMASK_BIT(mask, 11);
318         printk("11 cleared\n");
319         PRINT_BITMASK(mask, masksize);
320         printk("bit 17 is %d (should be 1)\n", GET_BITMASK_BIT(mask, 17));
321         printk("bit 11 is %d (should be 0)\n", GET_BITMASK_BIT(mask, 11));
322         FILL_BITMASK(mask, masksize);
323         PRINT_BITMASK(mask, masksize);
324         printk("should be all 1's, except for a few at the end\n");
325         printk("Is Clear?: %d (should be 0)\n", BITMASK_IS_CLEAR(mask,masksize));
326         CLR_BITMASK(mask, masksize);
327         PRINT_BITMASK(mask, masksize);
328         printk("Is Clear?: %d (should be 1)\n", BITMASK_IS_CLEAR(mask,masksize));
329         printk("should be cleared\n");
330 }
331
332 checklist_t *RO the_global_list;
333
334 void test_checklist_handler(trapframe_t *tf, void* data)
335 {
336         udelay(1000000);
337         cprintf("down_checklist(%x,%d)\n", the_global_list, core_id());
338         down_checklist(the_global_list);
339 }
340
341 void test_checklists(void)
342 {
343         INIT_CHECKLIST(a_list, MAX_NUM_CPUS);
344         the_global_list = &a_list;
345         printk("Checklist Build, mask size: %d\n", sizeof(a_list.mask.bits));
346         printk("mask\n");
347         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
348         SET_BITMASK_BIT(a_list.mask.bits, 11);
349         printk("Set bit 11\n");
350         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
351
352         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
353         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CPUS);
354         FILL_BITMASK(a_mask.bits, num_cpus);
355         //CLR_BITMASK_BIT(a_mask.bits, core_id());
356         //SET_BITMASK_BIT(a_mask.bits, 1);
357         //printk("New mask (1, 17, 25):\n");
358         printk("Created new mask, filled up to num_cpus\n");
359         PRINT_BITMASK(a_mask.bits, a_mask.size);
360         printk("committing new mask\n");
361         commit_checklist_wait(&a_list, &a_mask);
362         printk("Old mask (copied onto):\n");
363         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
364         //smp_call_function_single(1, test_checklist_handler, 0, 0);
365
366         smp_call_function_all(test_checklist_handler, NULL, 0);
367
368         printk("Waiting on checklist\n");
369         waiton_checklist(&a_list);
370         printk("Done Waiting!\n");
371
372 }
373
374 atomic_t a, b, c;
375
376 #ifdef __IVY__
377 void test_incrementer_handler(trapframe_t *tf, atomic_t *data)
378 #else
379 void test_incrementer_handler(trapframe_t *tf, void *data)
380 #endif
381 {
382         assert(data);
383         atomic_inc(data);
384 }
385
386 void test_null_handler(trapframe_t *tf, void* data)
387 {
388         asm volatile("nop");
389 }
390
391 void test_smp_call_functions(void)
392 {
393         int i;
394         atomic_init(&a, 0);
395         atomic_init(&b, 0);
396         atomic_init(&c, 0);
397         handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
398                           *waiter4 = 0, *waiter5 = 0;
399         uint8_t me = core_id();
400         printk("\nCore %d: SMP Call Self (nowait):\n", me);
401         printk("---------------------\n");
402         smp_call_function_self(test_hello_world_handler, NULL, 0);
403         printk("\nCore %d: SMP Call Self (wait):\n", me);
404         printk("---------------------\n");
405         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
406         smp_call_wait(waiter0);
407         printk("\nCore %d: SMP Call All (nowait):\n", me);
408         printk("---------------------\n");
409         smp_call_function_all(test_hello_world_handler, NULL, 0);
410         printk("\nCore %d: SMP Call All (wait):\n", me);
411         printk("---------------------\n");
412         smp_call_function_all(test_hello_world_handler, NULL, &waiter0);
413         smp_call_wait(waiter0);
414         printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
415         printk("---------------------\n");
416         for(i = 1; i < num_cpus; i++)
417                 smp_call_function_single(i, test_hello_world_handler, NULL, 0);
418         printk("\nCore %d: SMP Call Self (wait):\n", me);
419         printk("---------------------\n");
420         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
421         smp_call_wait(waiter0);
422         printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
423         printk("---------------------\n");
424         for(i = 1; i < num_cpus; i++)
425         {
426                 smp_call_function_single(i, test_hello_world_handler, NULL, &waiter0);
427                 smp_call_wait(waiter0);
428         }
429         printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
430         printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
431         smp_call_function_all(test_incrementer_handler, &a, 0);
432         smp_call_function_all(test_incrementer_handler, &b, 0);
433         smp_call_function_all(test_incrementer_handler, &c, 0);
434         // if i can clobber a previous IPI, the interleaving might do it
435         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
436         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
437         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
438         smp_call_function_single(4 % num_cpus, test_incrementer_handler, &a, 0);
439         smp_call_function_single(5 % num_cpus, test_incrementer_handler, &b, 0);
440         smp_call_function_single(6 % num_cpus, test_incrementer_handler, &c, 0);
441         smp_call_function_all(test_incrementer_handler, &a, 0);
442         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
443         smp_call_function_all(test_incrementer_handler, &b, 0);
444         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
445         smp_call_function_all(test_incrementer_handler, &c, 0);
446         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
447         // wait, so we're sure the others finish before printing.
448         // without this, we could (and did) get 19,18,19, since the B_inc
449         // handler didn't finish yet
450         smp_call_function_self(test_null_handler, NULL, &waiter0);
451         // need to grab all 5 handlers (max), since the code moves to the next free.
452         smp_call_function_self(test_null_handler, NULL, &waiter1);
453         smp_call_function_self(test_null_handler, NULL, &waiter2);
454         smp_call_function_self(test_null_handler, NULL, &waiter3);
455         smp_call_function_self(test_null_handler, NULL, &waiter4);
456         smp_call_wait(waiter0);
457         smp_call_wait(waiter1);
458         smp_call_wait(waiter2);
459         smp_call_wait(waiter3);
460         smp_call_wait(waiter4);
461         printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
462         printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
463         smp_call_function_self(test_null_handler, NULL, &waiter0);
464         printk("Sent one\n");
465         smp_call_function_self(test_null_handler, NULL, &waiter1);
466         printk("Sent two\n");
467         smp_call_wait(waiter0);
468         printk("Wait one\n");
469         smp_call_wait(waiter1);
470         printk("Wait two\n");
471         printk("\tMade it through!\n");
472         printk("Attempting to deadlock by smp_calling more than are available:\n");
473         printk("\tShould see an Insufficient message and a kernel warning.\n");
474         if (smp_call_function_self(test_null_handler, NULL, &waiter0))
475                 printk("\tInsufficient handlers to call function (0)\n");
476         if (smp_call_function_self(test_null_handler, NULL, &waiter1))
477                 printk("\tInsufficient handlers to call function (1)\n");
478         if (smp_call_function_self(test_null_handler, NULL, &waiter2))
479                 printk("\tInsufficient handlers to call function (2)\n");
480         if (smp_call_function_self(test_null_handler, NULL, &waiter3))
481                 printk("\tInsufficient handlers to call function (3)\n");
482         if (smp_call_function_self(test_null_handler, NULL, &waiter4))
483                 printk("\tInsufficient handlers to call function (4)\n");
484         if (smp_call_function_self(test_null_handler, NULL, &waiter5))
485                 printk("\tInsufficient handlers to call function (5)\n");
486         smp_call_wait(waiter0);
487         smp_call_wait(waiter1);
488         smp_call_wait(waiter2);
489         smp_call_wait(waiter3);
490         smp_call_wait(waiter4);
491         smp_call_wait(waiter5);
492         printk("\tMade it through!\n");
493
494         printk("Done\n");
495 }
496
497 #ifdef __i386__
498 void test_lapic_status_bit(void)
499 {
500         register_interrupt_handler(interrupt_handlers, I_TESTING,
501                                    test_incrementer_handler, &a);
502         #define NUM_IPI 100000
503         atomic_set(&a,0);
504         printk("IPIs received (should be 0): %d\n", a);
505         for(int i = 0; i < NUM_IPI; i++) {
506                 send_ipi(7, 0, I_TESTING);
507                 lapic_wait_to_send();
508         }
509         // need to wait a bit to let those IPIs get there
510         udelay(5000000);
511         printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
512         // hopefully that handler never fires again.  leaving it registered for now.
513 }
514 #endif // __i386__
515
516 /******************************************************************************/
517 /*            Test Measurements: Couples with measurement.c                   */
518 // All user processes can R/W the UGDATA page
519 barrier_t*COUNT(1) bar = (barrier_t*COUNT(1))TC(UGDATA);
520 uint32_t*COUNT(1) job_to_run = (uint32_t*COUNT(1))TC(UGDATA + sizeof(barrier_t));
521 env_t* env_batch[64]; // Fairly arbitrary, just the max I plan to use.
522
523 /* Helpers for test_run_measurements */
524 static void wait_for_all_envs_to_die(void)
525 {
526         while (atomic_read(&num_envs))
527                 cpu_relax();
528 }
529
530 // this never returns.
531 static void sync_tests(int start_core, int num_threads, int job_num)
532 {
533         assert(start_core + num_threads <= num_cpus);
534         wait_for_all_envs_to_die();
535         for (int i = start_core; i < start_core + num_threads; i++)
536                 env_batch[i] = kfs_proc_create(kfs_lookup_path("roslib_measurements"));
537         lcr3(env_batch[start_core]->env_cr3);
538         init_barrier(bar, num_threads);
539         *job_to_run = job_num;
540         for (int i = start_core; i < start_core + num_threads; i++)
541                 smp_call_function_single(i, run_env_handler, env_batch[i], 0);
542         process_workqueue();
543         // we want to fake a run, to reenter manager for the next case
544         env_t *env = kfs_proc_create(kfs_lookup_path("roslib_null"));
545         smp_call_function_single(0, run_env_handler, env, 0);
546         // Note we are still holding references to all the processes
547         process_workqueue();
548         panic("whoops!\n");
549 }
550
551 static void async_tests(int start_core, int num_threads, int job_num)
552 {
553         int count;
554
555         assert(start_core + num_threads <= num_cpus);
556         wait_for_all_envs_to_die();
557         for (int i = start_core; i < start_core + num_threads; i++)
558                 env_batch[i] = kfs_proc_create(kfs_lookup_path("roslib_measurements"));
559         printk("async_tests: checkpoint 0\n");
560         lcr3(env_batch[start_core]->env_cr3);
561         init_barrier(bar, num_threads);
562         printk("async_tests: checkpoint 1\n");
563         *job_to_run = job_num;
564         for (int i = start_core; i < start_core + num_threads; i++)
565                 smp_call_function_single(i, run_env_handler, env_batch[i], 0);
566         count = 0;
567         while (count > -num_threads) {
568                 count = 0;
569                 for (int i = start_core; i < start_core + num_threads; i++) {
570                         count += process_generic_syscalls(env_batch[i], 1);
571                 }
572                 cpu_relax();
573         }
574         // we want to fake a run, to reenter manager for the next case
575         env_t *env = kfs_proc_create(kfs_lookup_path("roslib_null"));
576         smp_call_function_single(0, run_env_handler, env, 0);
577         // Note we are still holding references to all the processes
578         process_workqueue();
579         // this all never returns
580         panic("whoops!\n");
581 }
582
583 void test_run_measurements(uint32_t job_num)
584 {
585         switch (job_num) {
586                 case 0: // Nulls
587                         printk("Case 0:\n");
588                         async_tests(2, 1, job_num);  // start core 2, 1 core total
589                         break;
590                 case 1: // Sync
591                         printk("Case 1:\n");
592                         sync_tests(2, 1, job_num);
593                         break;
594                 case 2:
595                         printk("Case 2:\n");
596                         sync_tests(2, 2, job_num);
597                         break;
598                 case 3:
599                         printk("Case 3:\n");
600                         sync_tests(0, 3, job_num);
601                         break;
602                 case 4:
603                         printk("Case 4:\n");
604                         sync_tests(0, 4, job_num);
605                         break;
606                 case 5:
607                         printk("Case 5:\n");
608                         sync_tests(0, 5, job_num);
609                         break;
610                 case 6:
611                         printk("Case 6:\n");
612                         sync_tests(0, 6, job_num);
613                         break;
614                 case 7:
615                         printk("Case 7:\n");
616                         sync_tests(0, 7, job_num);
617                         break;
618                 case 8:
619                         printk("Case 8:\n");
620                         sync_tests(0, 8, job_num);
621                         break;
622                 case 9:
623                         printk("Case 9:\n");
624                         async_tests(2, 1, job_num);
625                         break;
626                 case 10:
627                         printk("Case 10:\n");
628                         async_tests(2, 2, job_num);
629                         break;
630                 case 11:
631                         printk("Case 11:\n");
632                         async_tests(2, 3, job_num);
633                         break;
634                 case 12:
635                         printk("Case 12:\n");
636                         async_tests(2, 4, job_num);
637                         break;
638                 case 13:
639                         printk("Case 13:\n");
640                         async_tests(2, 5, job_num);
641                         break;
642                 case 14:
643                         printk("Case 14:\n");
644                         async_tests(2, 6, job_num);
645                         break;
646                 default:
647                         warn("Invalid test number!!");
648         }
649         panic("Error in test setup!!");
650 }
651
652 /************************************************************/
653 /* ISR Handler Functions */
654
655 void test_hello_world_handler(trapframe_t *tf, void* data)
656 {
657         int trapno;
658         #if defined(__i386__)
659         trapno = tf->tf_trapno;
660         #elif defined(__sparc_v8__)
661         trapno = (tf->tbr >> 4) & 0xFF;
662         #else
663         trapno = 0;
664         #endif
665
666         cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n",
667                 trapno, core_id(), tf);
668 }
669
670 spinlock_t print_info_lock = SPINLOCK_INITIALIZER;
671
672 void test_print_info_handler(trapframe_t *tf, void* data)
673 {
674         spin_lock_irqsave(&print_info_lock);
675         cprintf("----------------------------\n");
676         cprintf("This is Core %d\n", core_id());
677 #ifdef __i386__
678         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
679         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
680                 read_msr(0x200), read_msr(0x201));
681         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
682                 read_msr(0x202), read_msr(0x203));
683         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
684                 read_msr(0x204), read_msr(0x205));
685         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
686                 read_msr(0x206), read_msr(0x207));
687         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
688                 read_msr(0x208), read_msr(0x209));
689         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
690                 read_msr(0x20a), read_msr(0x20b));
691         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
692                 read_msr(0x20c), read_msr(0x20d));
693         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
694                 read_msr(0x20e), read_msr(0x20f));
695 #endif // __i386__
696         cprintf("----------------------------\n");
697         spin_unlock_irqsave(&print_info_lock);
698 }
699
700 void test_barrier_handler(trapframe_t *tf, void* data)
701 {
702         cprintf("Round 1: Core %d\n", core_id());
703         waiton_barrier(&test_cpu_array);
704         waiton_barrier(&test_cpu_array);
705         waiton_barrier(&test_cpu_array);
706         waiton_barrier(&test_cpu_array);
707         waiton_barrier(&test_cpu_array);
708         waiton_barrier(&test_cpu_array);
709         cprintf("Round 2: Core %d\n", core_id());
710         waiton_barrier(&test_cpu_array);
711         cprintf("Round 3: Core %d\n", core_id());
712         // uncomment to see it fucked up
713         //cprintf("Round 4: Core %d\n", core_id());
714 }
715
716 #ifdef __IVY__
717 static void test_waiting_handler(trapframe_t *tf, atomic_t *data)
718 #else
719 static void test_waiting_handler(trapframe_t *tf, void *data)
720 #endif
721 {
722         atomic_dec(data);
723 }
724
725 #ifdef __i386__
726 void test_pit(void)
727 {
728         cprintf("Starting test for PIT now (10s)\n");
729         udelay_pit(10000000);
730         cprintf("End now\n");
731         cprintf("Starting test for TSC (if stable) now (10s)\n");
732         udelay(10000000);
733         cprintf("End now\n");
734
735         cprintf("Starting test for LAPIC (if stable) now (10s)\n");
736         enable_irq();
737         lapic_set_timer(10000000, FALSE);
738
739         atomic_t waiting;
740         atomic_init(&waiting, 1);
741         register_interrupt_handler(interrupt_handlers, I_TESTING,
742                                    test_waiting_handler, &waiting);
743         while(atomic_read(&waiting))
744                 cpu_relax();
745         cprintf("End now\n");
746 }
747
748 void test_circ_buffer(void)
749 {
750         int arr[5] = {0, 1, 2, 3, 4};
751
752         for (int i = 0; i < 5; i++) {
753                 FOR_CIRC_BUFFER(i, 5, j)
754                         printk("Starting with current = %d, each value = %d\n", i, j);
755         }
756         return;
757 }
758
759 #ifdef __IVY__
760 void test_am_handler(trapframe_t* tf, uint32_t srcid, uint32_t a0, uint32_t a1,
761                      uint32_t a2)
762 #else
763 void test_am_handler(trapframe_t* tf, uint32_t srcid, void * a0, void * a1,
764                      void * a2)
765 #endif
766 {
767         printk("Received AM on core %d from core %d: arg0= 0x%08x, arg1 = "
768                "0x%08x, arg2 = 0x%08x\n", core_id(), srcid, a0, a1, a2);
769         return;
770 }
771
772 void test_active_messages(void)
773 {
774         // basic tests, make sure we can handle a wraparound and that the error
775         // messages work.
776         printk("sending NUM_ACTIVE_MESSAGES to core 1, sending (#,deadbeef,0)\n");
777         for (int i = 0; i < NUM_ACTIVE_MESSAGES; i++)
778 #ifdef __IVY__
779                 while (send_active_message(1, test_am_handler, i, 0xdeadbeef, 0))
780                         cpu_relax();
781 #else
782                 while (send_active_message(1, test_am_handler, (void *)i,
783                                            (void *)0xdeadbeef, (void *)0))
784                         cpu_relax();
785 #endif
786         udelay(5000000);
787         printk("sending 2*NUM_ACTIVE_MESSAGES to core 1, sending (#,cafebabe,0)\n");
788         for (int i = 0; i < 2*NUM_ACTIVE_MESSAGES; i++)
789 #ifdef __IVY__
790                 while (send_active_message(1, test_am_handler, i, 0xdeadbeef, 0))
791                         cpu_relax();
792 #else
793                 while (send_active_message(1, test_am_handler, (void *)i,
794                                            (void *)0xdeadbeef, (void *)0))
795                         cpu_relax();
796 #endif
797         udelay(5000000);
798         return;
799 }
800 #endif // __i386__
801
802 static void test_single_cache(int iters, size_t size, int align, int flags,
803                               void (*ctor)(void *, size_t),
804                               void (*dtor)(void *, size_t))
805 {
806         struct kmem_cache *test_cache;
807         void *objects[iters];
808         test_cache = kmem_cache_create("test_cache", size, align, flags, ctor, dtor);
809         printk("Testing Kmem Cache:\n");
810         print_kmem_cache(test_cache);
811         for (int i = 0; i < iters; i++) {
812                 objects[i] = kmem_cache_alloc(test_cache, 0);
813                 printk("Buffer %d addr = %p\n", i, objects[i]);
814         }
815         for (int i = 0; i < iters; i++) {
816                 kmem_cache_free(test_cache, objects[i]);
817         }
818         kmem_cache_destroy(test_cache);
819         printk("\n\n\n\n");
820 }
821
822 void a_ctor(void *buf, size_t size)
823 {
824         printk("constructin tests\n");
825 }
826 void a_dtor(void *buf, size_t size)
827 {
828         printk("destructin tests\n");
829 }
830
831 void test_slab(void)
832 {
833         test_single_cache(10, 128, 512, 0, 0, 0);
834         test_single_cache(10, 128, 4, 0, a_ctor, a_dtor);
835         test_single_cache(10, 1024, 16, 0, 0, 0);
836 }
837
838 void test_kmalloc(void)
839 {
840         printk("Testing Kmalloc\n");
841         void *bufs[NUM_KMALLOC_CACHES + 1];     
842         size_t size;
843         for (int i = 0; i < NUM_KMALLOC_CACHES + 1; i++){
844                 size = (KMALLOC_SMALLEST << i) - KMALLOC_OFFSET;
845                 bufs[i] = kmalloc(size, 0);
846                 printk("Size %d, Addr = %p\n", size, bufs[i]);
847         }
848         for (int i = 0; i < NUM_KMALLOC_CACHES; i++) {
849                 printk("Freeing buffer %d\n", i);
850                 kfree(bufs[i]);
851         }
852         printk("Testing a large kmalloc\n");
853         size = (KMALLOC_LARGEST << 2);
854         bufs[0] = kmalloc(size, 0);
855         printk("Size %d, Addr = %p\n", size, bufs[0]);
856         kfree(bufs[0]);
857 }
858
859 static size_t test_hash_fn_col(void *k)
860 {
861         return (size_t)k % 2; // collisions in slots 0 and 1
862 }
863
864 void test_hashtable(void)
865 {
866         struct test {int x; int y;};
867         struct test tstruct[10];
868
869         struct hashtable *h;
870         int k = 5;
871         struct test *v = &tstruct[0];
872
873         h = create_hashtable(32, __generic_hash, __generic_eq);
874         
875         // test inserting one item, then finding it again
876         printk("Tesing one item, insert, search, and removal\n");
877         if(!hashtable_insert(h, (void*)k, v))
878                 printk("Failed to insert to hashtable!\n");
879         v = NULL;
880         if (!(v = hashtable_search(h, (void*)k)))
881                 printk("Failed to find in hashtable!\n");
882         if (v != &tstruct[0])
883                 printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[0]);
884         v = NULL;
885         if (!(v = hashtable_remove(h, (void*)k)))
886                 printk("Failed to remove from hashtable!\n");
887         // shouldn't be able to find it again
888         if ((v = hashtable_search(h, (void*)k)))
889                 printk("Should not have been able to find in hashtable!\n");
890         
891         printk("Tesing a bunch of items, insert, search, and removal\n");
892         for (int i = 0; i < 10; i++) {
893                 k = i; // vary the key, we don't do KEY collisions
894                 if(!hashtable_insert(h, (void*)k, &tstruct[i]))
895                         printk("Failed to insert iter %d to hashtable!\n", i);
896         }
897         // read out the 10 items
898         for (int i = 0; i < 10; i++) {
899                 k = i;
900                 if (!(v = hashtable_search(h, (void*)k)))
901                         printk("Failed to find in hashtable!\n");
902                 if (v != &tstruct[i])
903                         printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[i]);
904         }
905         if (hashtable_count(h) != 10)
906                 printk("Wrong accounting of number of elements!\n");
907         // remove the 10 items
908         for (int i = 0; i < 10; i++) {
909                 k = i;
910                 if (!(v = hashtable_remove(h, (void*)k)))
911                         printk("Failed to remove from hashtable!\n");
912         }
913         // make sure they are all gone
914         for (int i = 0; i < 10; i++) {
915                 k = i;
916                 if ((v = hashtable_search(h, (void*)k)))
917                         printk("Should not have been able to find in hashtable!\n");
918         }
919         if (hashtable_count(h))
920                 printk("Wrong accounting of number of elements!\n");
921         hashtable_destroy(h);
922
923         // same test of a bunch of items, but with collisions.
924         printk("Tesing a bunch of items with collisions, etc.\n");
925         h = create_hashtable(32, test_hash_fn_col, __generic_eq);
926         // insert 10 items
927         for (int i = 0; i < 10; i++) {
928                 k = i; // vary the key, we don't do KEY collisions
929                 if(!hashtable_insert(h, (void*)k, &tstruct[i]))
930                         printk("Failed to insert iter %d to hashtable!\n", i);
931         }
932         // read out the 10 items
933         for (int i = 0; i < 10; i++) {
934                 k = i;
935                 if (!(v = hashtable_search(h, (void*)k)))
936                         printk("Failed to find in hashtable!\n");
937                 if (v != &tstruct[i])
938                         printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[i]);
939         }
940         if (hashtable_count(h) != 10)
941                 printk("Wrong accounting of number of elements!\n");
942         // remove the 10 items
943         for (int i = 0; i < 10; i++) {
944                 k = i;
945                 if (!(v = hashtable_remove(h, (void*)k)))
946                         printk("Failed to remove from hashtable!\n");
947         }
948         // make sure they are all gone
949         for (int i = 0; i < 10; i++) {
950                 k = i;
951                 if ((v = hashtable_search(h, (void*)k)))
952                         printk("Should not have been able to find in hashtable!\n");
953         }
954         if (hashtable_count(h))
955                 printk("Wrong accounting of number of elements!\n");
956         hashtable_destroy(h);
957 }
958