#include <stdio.h>
#include <limits.h>
#ifndef _WIN32_WCE
#include <signal.h>
#endif

#define I_HIDE_POINTERS	/* To make GC_call_with_alloc_lock visible */
#include "private/gc_pmark.h"

#ifdef GC_SOLARIS_THREADS
# include <sys/syscall.h>
#endif
#if defined(MSWIN32) || defined(MSWINCE)
# define WIN32_LEAN_AND_MEAN
# define NOSERVICE
# include <windows.h>
# include <tchar.h>
#endif


/* Dont unnecessarily call GC_register_main_static_data() in case 	*/
/* dyn_load.c isn't linked in.						*/
#ifdef DYNAMIC_LOADING
# define GC_REGISTER_MAIN_STATIC_DATA() GC_register_main_static_data()
#else
# define GC_REGISTER_MAIN_STATIC_DATA() TRUE
#endif


#include "private/gcconfig.h"

char * GC_register_stackbottom = (char *)0xdeadbeef;
char * GC_stackbottom = (char *)0xdeadbeef;

void GC_init_for_d()
{
    GC_setpagesize();
#   ifdef MSWIN32
 	GC_init_win32();
#   endif
#   if defined(SEARCH_FOR_DATA_START)
	GC_init_linux_data_start();
#   endif
#   if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
	GC_init_netbsd_elf();
#   endif
#   if !defined(THREADS) || defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) \
	|| defined(GC_SOLARIS_THREADS)
      if (GC_stackbottom == 0) {
	GC_stackbottom = GC_get_stack_base();
#       if defined(LINUX) && defined(IA64)
	  GC_register_stackbottom = GC_get_register_stack_base();
#       endif
      } else {
#       if defined(LINUX) && defined(IA64)
	  if (GC_register_stackbottom == 0) {
	    WARN("GC_register_stackbottom should be set with GC_stackbottom", 0);
	    /* The following is likely to fail, since we rely on 	*/
	    /* alignment properties that may not hold with a user set	*/
	    /* GC_stackbottom.						*/
	    GC_register_stackbottom = GC_get_register_stack_base();
	  }
#	endif
      }
#   endif
      if (GC_REGISTER_MAIN_STATIC_DATA()) GC_register_data_segments();
    
#   if defined(DYNAMIC_LOADING) && defined(DARWIN)
    {
        /* This must be called WITHOUT the allocation lock held
        and before any threads are created */
        extern void GC_init_dyld();
        GC_init_dyld();
    }
#   endif

    /* not part of the normal init... */
    GC_register_dynamic_libraries();
}

void GC_noop1(x)
word x;
{
    static VOLATILE word sink;

    sink = x;
}

void GC_abort(const char * msg)
{
    fprintf(stderr, "%s\n", msg);
    abort();
}
