📄 gc.h
字号:
/* Register the current thread, with the indicated stack base, as *//* a new thread whose stack(s) should be traced by the GC. If a *//* platform does not implicitly do so, this must be called before a *//* thread can allocate garbage collected memory, or assign pointers *//* to the garbage collected heap. Once registered, a thread will be *//* stopped during garbage collections. *//* Return codes: */#define GC_SUCCESS 0#define GC_DUPLICATE 1 /* Was already registered. */#define GC_NO_THREADS 2 /* No thread support in GC. */#define GC_UNIMPLEMENTED 3 /* Not yet implemented on this platform. */int GC_register_my_thread(struct GC_stack_base *);/* Unregister the current thread. The thread may no longer allocate *//* garbage collected memory or manipulate pointers to the *//* garbage collected heap after making this call. *//* Specifically, if it wants to return or otherwise communicate a *//* pointer to the garbage-collected heap to another thread, it must *//* do this before calling GC_unregister_my_thread, most probably *//* by saving it in a global data structure. */int GC_unregister_my_thread(void);/* Attempt to fill in the GC_stack_base structure with the stack base *//* for this thread. This appears to be required to implement anything *//* like the JNI AttachCurrentThread in an environment in which new *//* threads are not automatically registered with the collector. *//* It is also unfortunately hard to implement well on many platforms. *//* Returns GC_SUCCESS or GC_UNIMPLEMENTED. */int GC_get_stack_base(struct GC_stack_base *);/* The following routines are primarily intended for use with a *//* preprocessor which inserts calls to check C pointer arithmetic. *//* They indicate failure by invoking the corresponding _print_proc. *//* Check that p and q point to the same object. *//* Fail conspicuously if they don't. *//* Returns the first argument. *//* Succeeds if neither p nor q points to the heap. *//* May succeed if both p and q point to between heap objects. */GC_API void * GC_same_obj (void * p, void * q);/* Checked pointer pre- and post- increment operations. Note that *//* the second argument is in units of bytes, not multiples of the *//* object size. This should either be invoked from a macro, or the *//* call should be automatically generated. */GC_API void * GC_pre_incr (void * *p, size_t how_much);GC_API void * GC_post_incr (void * *p, size_t how_much);/* Check that p is visible *//* to the collector as a possibly pointer containing location. *//* If it isn't fail conspicuously. *//* Returns the argument in all cases. May erroneously succeed *//* in hard cases. (This is intended for debugging use with *//* untyped allocations. The idea is that it should be possible, though *//* slow, to add such a call to all indirect pointer stores.) *//* Currently useless for multithreaded worlds. */GC_API void * GC_is_visible (void * p);/* Check that if p is a pointer to a heap page, then it points to *//* a valid displacement within a heap object. *//* Fail conspicuously if this property does not hold. *//* Uninteresting with GC_all_interior_pointers. *//* Always returns its argument. */GC_API void * GC_is_valid_displacement (void * p);/* Explicitly dump the GC state. This is most often called from the *//* debugger, or by setting the GC_DUMP_REGULARLY environment variable, *//* but it may be useful to call it from client code during debugging. */void GC_dump(void);/* Safer, but slow, pointer addition. Probably useful mainly with *//* a preprocessor. Useful only for heap pointers. */#ifdef GC_DEBUG# define GC_PTR_ADD3(x, n, type_of_result) \ ((type_of_result)GC_same_obj((x)+(n), (x)))# define GC_PRE_INCR3(x, n, type_of_result) \ ((type_of_result)GC_pre_incr(&(x), (n)*sizeof(*x))# define GC_POST_INCR2(x, type_of_result) \ ((type_of_result)GC_post_incr(&(x), sizeof(*x))# ifdef __GNUC__# define GC_PTR_ADD(x, n) \ GC_PTR_ADD3(x, n, typeof(x))# define GC_PRE_INCR(x, n) \ GC_PRE_INCR3(x, n, typeof(x))# define GC_POST_INCR(x, n) \ GC_POST_INCR3(x, typeof(x))# else /* We can't do this right without typeof, which ANSI */ /* decided was not sufficiently useful. Repeatedly */ /* mentioning the arguments seems too dangerous to be */ /* useful. So does not casting the result. */# define GC_PTR_ADD(x, n) ((x)+(n))# endif#else /* !GC_DEBUG */# define GC_PTR_ADD3(x, n, type_of_result) ((x)+(n))# define GC_PTR_ADD(x, n) ((x)+(n))# define GC_PRE_INCR3(x, n, type_of_result) ((x) += (n))# define GC_PRE_INCR(x, n) ((x) += (n))# define GC_POST_INCR2(x, n, type_of_result) ((x)++)# define GC_POST_INCR(x, n) ((x)++)#endif/* Safer assignment of a pointer to a nonstack location. */#ifdef GC_DEBUG# define GC_PTR_STORE(p, q) \ (*(void **)GC_is_visible(p) = GC_is_valid_displacement(q))#else /* !GC_DEBUG */# define GC_PTR_STORE(p, q) *((p) = (q))#endif/* Functions called to report pointer checking errors */GC_API void (*GC_same_obj_print_proc) (void * p, void * q);GC_API void (*GC_is_valid_displacement_print_proc) (void * p);GC_API void (*GC_is_visible_print_proc) (void * p);/* For pthread support, we generally need to intercept a number of *//* thread library calls. We do that here by macro defining them. */#if !defined(GC_USE_LD_WRAP) && \ (defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS))# include "gc_pthread_redirects.h"#endif# if defined(PCR) || defined(GC_SOLARIS_THREADS) || \ defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) /* Any flavor of threads. *//* This returns a list of objects, linked through their first *//* word. Its use can greatly reduce lock contention problems, since *//* the allocation lock can be acquired and released many fewer times. *//* It is used internally by gc_local_alloc.h, which provides a simpler *//* programming interface on Linux. */void * GC_malloc_many(size_t lb);#define GC_NEXT(p) (*(void * *)(p)) /* Retrieve the next element */ /* in returned list. */extern void GC_thr_init(void); /* Needed for Solaris/X86 ?? */#endif /* THREADS *//* Register a callback to control the scanning of dynamic libraries. When the GC scans the static data of a dynamic library, it will first call a user-supplied routine with filename of the library and the address and length of the memory region. This routine should return nonzero if that region should be scanned. */GC_API void GC_register_has_static_roots_callback (int (*callback)(const char *, void *, size_t));#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) \ && !defined(__CYGWIN__) \ && !defined(GC_PTHREADS)#ifdef __cplusplus } /* Including windows.h in an extern "C" context no longer works. */#endif# include <windows.h>#ifdef __cplusplus extern "C" {#endif /* * All threads must be created using GC_CreateThread or GC_beginthreadex, * or must explicitly call GC_register_my_thread, * so that they will be recorded in the thread table. * For backwards compatibility, it is possible to build the GC * with GC_DLL defined, and to call GC_use_DllMain(). * This implicitly registers all created threads, but appears to be * less robust. * * Currently the collector expects all threads to fall through and * terminate normally, or call GC_endthreadex() or GC_ExitThread, * so that the thread is properly unregistered. (An explicit call * to GC_unregister_my_thread() should also work, but risks unregistering * the thread twice.) */ GC_API HANDLE WINAPI GC_CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); GC_API uintptr_t GC_beginthreadex( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr); GC_API void GC_endthreadex(unsigned retval); GC_API void WINAPI GC_ExitThread(DWORD dwExitCode);# if defined(_WIN32_WCE) /* * win32_threads.c implements the real WinMain, which will start a new thread * to call GC_WinMain after initializing the garbage collector. */ GC_API int WINAPI GC_WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow );# ifndef GC_BUILD# define WinMain GC_WinMain# endif# endif /* defined(_WIN32_WCE) */ /* * Use implicit thread registration via DllMain. */GC_API void GC_use_DllMain(void);# define CreateThread GC_CreateThread# define ExitThread GC_ExitThread# define _beginthreadex GC_beginthreadex# define _endthreadex GC_endthreadex# define _beginthread { > "Please use _beginthreadex instead of _beginthread" < }#endif /* defined(GC_WIN32_THREADS) && !cygwin */ /* * Fully portable code should call GC_INIT() from the main program * before making any other GC_ calls. On most platforms this is a * no-op and the collector self-initializes. But a number of platforms * make that too hard. * A GC_INIT call is required if the collector is built with THREAD_LOCAL_ALLOC * defined and the initial allocation call is not to GC_malloc(). */#if defined(__CYGWIN32__) || defined (_AIX) /* * Similarly gnu-win32 DLLs need explicit initialization from * the main program, as does AIX. */# ifdef __CYGWIN32__ extern int _data_start__[]; extern int _data_end__[]; extern int _bss_start__[]; extern int _bss_end__[];# define GC_MAX(x,y) ((x) > (y) ? (x) : (y))# define GC_MIN(x,y) ((x) < (y) ? (x) : (y))# define GC_DATASTART ((void *) GC_MIN(_data_start__, _bss_start__))# define GC_DATAEND ((void *) GC_MAX(_data_end__, _bss_end__))# if defined(GC_DLL)# define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); \ GC_gcollect(); /* For blacklisting. */}# else /* Main program init not required */# define GC_INIT() { GC_init(); }# endif# endif# if defined(_AIX) extern int _data[], _end[];# define GC_DATASTART ((void *)((ulong)_data))# define GC_DATAEND ((void *)((ulong)_end))# define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); }# endif#else# define GC_INIT() { GC_init(); }#endif#if !defined(_WIN32_WCE) \ && ((defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \ || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)) /* win32S may not free all resources on process exit. */ /* This explicitly deallocates the heap. */ GC_API void GC_win32_free_heap ();#endif#if ( defined(_AMIGA) && !defined(GC_AMIGA_MAKINGLIB) ) /* Allocation really goes through GC_amiga_allocwrapper_do */# include "gc_amiga_redirects.h"#endif#if defined(GC_REDIRECT_TO_LOCAL) && !defined(GC_LOCAL_ALLOC_H)# include "gc_local_alloc.h"#endif#ifdef __cplusplus } /* end of extern "C" */#endif#endif /* _GC_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -