/* runtime.h -- runtime support for Go. Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #include "config.h" #define _GNU_SOURCE #include "go-assert.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_MMAN_H #include #endif #include "go-alloc.h" #include "go-panic.h" #include "go-string.h" typedef struct __go_string String; /* This file supports C files copied from the 6g runtime library. This is a version of the 6g runtime.h rewritten for gccgo's version of the code. */ typedef signed int int8 __attribute__ ((mode (QI))); typedef unsigned int uint8 __attribute__ ((mode (QI))); typedef signed int int16 __attribute__ ((mode (HI))); typedef unsigned int uint16 __attribute__ ((mode (HI))); typedef signed int int32 __attribute__ ((mode (SI))); typedef unsigned int uint32 __attribute__ ((mode (SI))); typedef signed int int64 __attribute__ ((mode (DI))); typedef unsigned int uint64 __attribute__ ((mode (DI))); typedef float float32 __attribute__ ((mode (SF))); typedef double float64 __attribute__ ((mode (DF))); typedef unsigned int uintptr __attribute__ ((mode (pointer))); /* Defined types. */ typedef uint8 bool; typedef uint8 byte; typedef struct M M; typedef struct MCache MCache; typedef struct Lock Lock; /* We use mutexes for locks. 6g uses futexes directly, and perhaps someday we will do that too. */ struct Lock { uint32 key; sem_t sem; }; /* A Note. */ typedef struct Note Note; struct Note { int32 woken; }; /* Per CPU declarations. */ #ifdef __rtems__ #define __thread #endif extern __thread M* m; extern M m0; #ifdef __rtems__ #undef __thread #endif /* Constants. */ enum { true = 1, false = 0, }; /* Structures. */ struct M { int32 mallocing; int32 gcing; int32 locks; int32 nomemprof; int32 gcing_for_prof; int32 holds_finlock; int32 gcing_for_finlock; MCache *mcache; /* For the list of all threads. */ struct __go_thread_id *list_entry; /* For the garbage collector. */ void *gc_sp; size_t gc_len; void *gc_next_segment; void *gc_next_sp; void *gc_initial_sp; struct __go_panic_defer_struct *gc_panic_defer; }; /* Macros. */ #define nelem(x) (sizeof(x)/sizeof((x)[0])) #define nil ((void*)0) #define USED(v) ((void) v) /* We map throw to assert. */ #define runtime_throw(s) __go_assert(s == 0) void* runtime_mal(uintptr); void runtime_mallocinit(void); void runtime_initfintab(void); void siginit(void); bool __go_sigsend(int32 sig); int64 runtime_nanotime(void); void runtime_stoptheworld(void); void runtime_starttheworld(void); void __go_go(void (*pfn)(void*), void*); void __go_gc_goroutine_init(void*); void __go_enable_gc(void); int __go_run_goroutine_gc(int); void __go_scanstacks(void (*scan)(byte *, int64)); void __go_stealcache(void); void __go_cachestats(void); /* * mutual exclusion locks. in the uncontended case, * as fast as spin locks (just a few user-level instructions), * but on the contention path they sleep in the kernel. */ void runtime_initlock(Lock*); void runtime_lock(Lock*); void runtime_unlock(Lock*); void runtime_destroylock(Lock*); void semacquire (uint32 *) asm ("libgo_runtime.runtime.Semacquire"); void semrelease (uint32 *) asm ("libgo_runtime.runtime.Semrelease"); /* * sleep and wakeup on one-time events. * before any calls to notesleep or notewakeup, * must call noteclear to initialize the Note. * then, any number of threads can call notesleep * and exactly one thread can call notewakeup (once). * once notewakeup has been called, all the notesleeps * will return. future notesleeps will return immediately. */ void noteclear(Note*); void notesleep(Note*); void notewakeup(Note*); /* Functions. */ #define runtime_printf printf #define runtime_malloc(s) __go_alloc(s) #define runtime_free(p) __go_free(p) #define runtime_memclr(buf, size) __builtin_memset((buf), 0, (size)) #define runtime_strcmp(s1, s2) __builtin_strcmp((s1), (s2)) #define runtime_getenv(s) getenv(s) #define runtime_atoi(s) atoi(s) #define runtime_mcmp(a, b, s) __builtin_memcmp((a), (b), (s)) #define runtime_memmove(a, b, s) __builtin_memmove((a), (b), (s)) MCache* runtime_allocmcache(void); void free(void *v); struct __go_func_type; void runtime_addfinalizer(void*, void(*fn)(void*), const struct __go_func_type *); void runtime_walkfintab(void (*fn)(void*), void (*scan)(byte *, int64)); #define runtime_mmap mmap #define runtime_munmap(p, s) munmap((p), (s)) #define runtime_cas(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) struct __go_func_type; void reflect_call(const struct __go_func_type *, const void *, _Bool, void **, void **) asm ("libgo_reflect.reflect.call"); #ifdef __rtems__ void __wrap_rtems_task_variable_add(void **); #endif