Home | History | Annotate | Line # | Download | only in go
      1  1.1  kamil //===-- test.c ------------------------------------------------------------===//
      2  1.1  kamil //
      3  1.1  kamil //                     The LLVM Compiler Infrastructure
      4  1.1  kamil //
      5  1.1  kamil // This file is distributed under the University of Illinois Open Source
      6  1.1  kamil // License. See LICENSE.TXT for details.
      7  1.1  kamil //
      8  1.1  kamil //===----------------------------------------------------------------------===//
      9  1.1  kamil //
     10  1.1  kamil // Sanity test for Go runtime.
     11  1.1  kamil //
     12  1.1  kamil //===----------------------------------------------------------------------===//
     13  1.1  kamil 
     14  1.1  kamil #include <sys/mman.h>
     15  1.1  kamil #include <errno.h>
     16  1.1  kamil #include <stdio.h>
     17  1.1  kamil #include <stdlib.h>
     18  1.1  kamil 
     19  1.1  kamil void __tsan_init(void **thr, void **proc, void (*cb)(long, void*));
     20  1.1  kamil void __tsan_fini();
     21  1.1  kamil void __tsan_map_shadow(void *addr, unsigned long size);
     22  1.1  kamil void __tsan_go_start(void *thr, void **chthr, void *pc);
     23  1.1  kamil void __tsan_go_end(void *thr);
     24  1.1  kamil void __tsan_proc_create(void **pproc);
     25  1.1  kamil void __tsan_proc_destroy(void *proc);
     26  1.1  kamil void __tsan_proc_wire(void *proc, void *thr);
     27  1.1  kamil void __tsan_proc_unwire(void *proc, void *thr);
     28  1.1  kamil void __tsan_read(void *thr, void *addr, void *pc);
     29  1.1  kamil void __tsan_write(void *thr, void *addr, void *pc);
     30  1.1  kamil void __tsan_func_enter(void *thr, void *pc);
     31  1.1  kamil void __tsan_func_exit(void *thr);
     32  1.1  kamil void __tsan_malloc(void *thr, void *pc, void *p, unsigned long sz);
     33  1.1  kamil void __tsan_free(void *p, unsigned long sz);
     34  1.1  kamil void __tsan_acquire(void *thr, void *addr);
     35  1.1  kamil void __tsan_release(void *thr, void *addr);
     36  1.1  kamil void __tsan_release_merge(void *thr, void *addr);
     37  1.1  kamil 
     38  1.1  kamil void *current_proc;
     39  1.1  kamil 
     40  1.1  kamil void symbolize_cb(long cmd, void *ctx) {
     41  1.1  kamil   switch (cmd) {
     42  1.1  kamil   case 0:
     43  1.1  kamil     if (current_proc == 0)
     44  1.1  kamil       abort();
     45  1.1  kamil     *(void**)ctx = current_proc;
     46  1.1  kamil   }
     47  1.1  kamil }
     48  1.1  kamil 
     49  1.1  kamil /*
     50  1.1  kamil  * See lib/tsan/rtl/tsan_platform.h for details of what the memory layout
     51  1.1  kamil  * of Go programs looks like.  To prevent running over existing mappings,
     52  1.1  kamil  * we pick an address slightly inside the Go heap region.
     53  1.1  kamil  */
     54  1.1  kamil void *go_heap = (void *)0xC011110000;
     55  1.1  kamil char *buf0;
     56  1.1  kamil 
     57  1.1  kamil void foobar() {}
     58  1.1  kamil void barfoo() {}
     59  1.1  kamil 
     60  1.1  kamil int main(void) {
     61  1.1  kamil   void *thr0 = 0;
     62  1.1  kamil   void *proc0 = 0;
     63  1.1  kamil   __tsan_init(&thr0, &proc0, symbolize_cb);
     64  1.1  kamil   current_proc = proc0;
     65  1.1  kamil 
     66  1.1  kamil   // Allocate something resembling a heap in Go.
     67  1.1  kamil   buf0 = mmap(go_heap, 16384, PROT_READ | PROT_WRITE,
     68  1.1  kamil               MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0);
     69  1.1  kamil   if (buf0 == MAP_FAILED) {
     70  1.1  kamil     fprintf(stderr, "failed to allocate Go-like heap at %p; errno %d\n",
     71  1.1  kamil             go_heap, errno);
     72  1.1  kamil     return 1;
     73  1.1  kamil   }
     74  1.1  kamil   char *buf = (char*)((unsigned long)buf0 + (64<<10) - 1 & ~((64<<10) - 1));
     75  1.1  kamil   __tsan_map_shadow(buf, 4096);
     76  1.1  kamil   __tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);
     77  1.1  kamil   __tsan_free(buf, 10);
     78  1.1  kamil   __tsan_func_enter(thr0, (char*)&main + 1);
     79  1.1  kamil   __tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);
     80  1.1  kamil   __tsan_release(thr0, buf);
     81  1.1  kamil   __tsan_release_merge(thr0, buf);
     82  1.1  kamil   void *thr1 = 0;
     83  1.1  kamil   __tsan_go_start(thr0, &thr1, (char*)&barfoo + 1);
     84  1.1  kamil   void *thr2 = 0;
     85  1.1  kamil   __tsan_go_start(thr0, &thr2, (char*)&barfoo + 1);
     86  1.1  kamil   __tsan_func_exit(thr0);
     87  1.1  kamil   __tsan_func_enter(thr1, (char*)&foobar + 1);
     88  1.1  kamil   __tsan_func_enter(thr1, (char*)&foobar + 1);
     89  1.1  kamil   __tsan_write(thr1, buf, (char*)&barfoo + 1);
     90  1.1  kamil   __tsan_acquire(thr1, buf);
     91  1.1  kamil   __tsan_func_exit(thr1);
     92  1.1  kamil   __tsan_func_exit(thr1);
     93  1.1  kamil   __tsan_go_end(thr1);
     94  1.1  kamil   void *proc1 = 0;
     95  1.1  kamil   __tsan_proc_create(&proc1);
     96  1.1  kamil   current_proc = proc1;
     97  1.1  kamil   __tsan_func_enter(thr2, (char*)&foobar + 1);
     98  1.1  kamil   __tsan_read(thr2, buf, (char*)&barfoo + 1);
     99  1.1  kamil   __tsan_free(buf, 10);
    100  1.1  kamil   __tsan_func_exit(thr2);
    101  1.1  kamil   __tsan_go_end(thr2);
    102  1.1  kamil   __tsan_proc_destroy(proc1);
    103  1.1  kamil   current_proc = proc0;
    104  1.1  kamil   __tsan_fini();
    105  1.1  kamil   return 0;
    106  1.1  kamil }
    107