summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2008-04-02 05:14:12 +0000
committerSimon Marlow <simonmar@microsoft.com>2008-04-02 05:14:12 +0000
commitc245355e6f2c7b7c95e9af910c4d420e13af9413 (patch)
treee8309f467b8bea2501e9f7de7af86fbfc22e0a67 /includes
parentab5c770bed51f08d56a0d61086988053b21aa461 (diff)
downloadhaskell-c245355e6f2c7b7c95e9af910c4d420e13af9413.tar.gz
Do not #include external header files when compiling via C
This has several advantages: - -fvia-C is consistent with -fasm with respect to FFI declarations: both bind to the ABI, not the API. - foreign calls can now be inlined freely across module boundaries, since a header file is not required when compiling the call. - bootstrapping via C will be more reliable, because this difference in behavour between the two backends has been removed. There is one disadvantage: - we get no checking by the C compiler that the FFI declaration is correct. So now, the c-includes field in a .cabal file is always ignored by GHC, as are header files specified in an FFI declaration. This was previously the case only for -fasm compilations, now it is also the case for -fvia-C too.
Diffstat (limited to 'includes')
-rw-r--r--includes/README13
-rw-r--r--includes/Regs.h23
-rw-r--r--includes/Rts.h6
-rw-r--r--includes/RtsExternal.h3
-rw-r--r--includes/RtsTypeable.h2
-rw-r--r--includes/SMP.h154
-rw-r--r--includes/SMPClosureOps.h71
-rw-r--r--includes/SpinLock.h110
-rw-r--r--includes/Stg.h9
-rw-r--r--includes/StgMiscClosures.h44
10 files changed, 256 insertions, 179 deletions
diff --git a/includes/README b/includes/README
index a63d02705f..fef91fe0fd 100644
--- a/includes/README
+++ b/includes/README
@@ -64,33 +64,35 @@ Rts.h
StgDLL.h /* stuff related to Windows DLLs */
MachRegs.h /* global register assignments for this arch */
Regs.h /* "registers" in the virtual machine */
- StgProf.h /* profiling gubbins */
StgMiscClosures.h /* decls for closures & info tables in the RTS */
- RtsExternal.h /* decls for RTS things required by .hc code */
- (RtsAPI.h)
- (HsFFI.h)
+ SMP.h /* basic primitives for synchronisation */
RtsTypes.h /* types used in the RTS */
Constants.h /* build-time constants */
StgLdvProf.h
StgFun.h
+ StgProf.h /* profiling gubbins */
Closures.h
Liveness.h /* macros for constructing RET_DYN liveness masks */
ClosureMacros.h
ClosureTypes.h
InfoTables.h
+ SMPClosureOps.h /* lockClosure/unlockClosure etc. */
+ SpinLock.h
TSO.h
Updates.h /* macros for performing updates */
GranSim.h
Parallel.h
- SMP.h
Block.h
Stable.h
Hooks.h
Signals.h
DNInvoke.h
Dotnet.h
+ RtsExternal.h /* decls for RTS things required by .hc code */
+ (RtsAPI.h)
+ (HsFFI.h)
Cmm.h /* included into .cmm source only */
DerivedConstants.h /* generated by mkDerivedConstants.c from other */
@@ -110,4 +112,3 @@ ieee-flpt.h /* ToDo: needed? */
RtsAPI.h /* The top-level interface to the RTS (rts_evalIO(), etc.) */
HsFFI.h /* The external FFI api */
-
diff --git a/includes/Regs.h b/includes/Regs.h
index 6524c8f669..0f974ec4ad 100644
--- a/includes/Regs.h
+++ b/includes/Regs.h
@@ -22,14 +22,6 @@
#ifndef REGS_H
#define REGS_H
-#if defined(HAVE_FRAMEWORK_GMP)
-#include <GMP/gmp.h>
-#elif defined(HAVE_LIB_GMP)
-#include <gmp.h>
-#else
-#include "gmp.h" // Needs MP_INT definition
-#endif
-
/*
* Spark pools: used to store pending sparks
* (THREADED_RTS & PARALLEL_HASKELL only)
@@ -79,6 +71,11 @@ typedef union {
StgTSOPtr t;
} StgUnion;
+// Urgh.. we don't know the size of an MP_INT here because we haven't
+// #included gmp.h. We should really autoconf this, but GMP may not
+// be available at ./configure time if we're building it (GMP) locally.
+#define MP_INT_WORDS 3
+
/*
* This is the table that holds shadow-locations for all the STG
* registers. The shadow locations are used when:
@@ -117,11 +114,11 @@ typedef struct StgRegTable_ {
// rmp_tmp1..rmp_result2 are only used in THREADED_RTS builds to
// avoid per-thread temps in bss, but currently always incldue here
// so we just run mkDerivedConstants once
- StgWord rmp_tmp_w;
- MP_INT rmp_tmp1;
- MP_INT rmp_tmp2;
- MP_INT rmp_result1;
- MP_INT rmp_result2;
+ StgWord rmp_tmp_w[MP_INT_WORDS];
+ StgWord rmp_tmp1[MP_INT_WORDS];
+ StgWord rmp_tmp2[MP_INT_WORDS];
+ StgWord rmp_result1[MP_INT_WORDS];
+ StgWord rmp_result2[MP_INT_WORDS];
StgWord rRet; // holds the return code of the thread
StgSparkPool rSparks; /* per-task spark pool */
} StgRegTable;
diff --git a/includes/Rts.h b/includes/Rts.h
index df8cb46900..cec93e68b0 100644
--- a/includes/Rts.h
+++ b/includes/Rts.h
@@ -18,6 +18,9 @@ extern "C" {
#endif
#include "Stg.h"
+// ToDo: move RtsExternal stuff elsewhere
+#include "RtsExternal.h"
+
// Turn off inlining when debugging - it obfuscates things
#ifdef DEBUG
# undef STATIC_INLINE
@@ -165,7 +168,8 @@ TAG_CLOSURE(StgWord tag,StgClosure * p)
/* Parallel information */
#include "Parallel.h"
#include "OSThreads.h"
-#include "SMP.h"
+#include "SMPClosureOps.h"
+#include "SpinLock.h"
/* GNU mp library */
#if defined(HAVE_FRAMEWORK_GMP)
diff --git a/includes/RtsExternal.h b/includes/RtsExternal.h
index b95da387bd..24dace2b14 100644
--- a/includes/RtsExternal.h
+++ b/includes/RtsExternal.h
@@ -111,9 +111,6 @@ extern void setIOManagerPipe (int fd);
extern void* allocateExec(unsigned int len);
// Breakpoint stuff
-extern int rts_stop_next_breakpoint;
-extern int rts_stop_on_exception;
-extern HsStablePtr rts_breakpoint_io_action;
/* -----------------------------------------------------------------------------
Storage manager stuff exported
diff --git a/includes/RtsTypeable.h b/includes/RtsTypeable.h
index 28b59cdc13..343c514ace 100644
--- a/includes/RtsTypeable.h
+++ b/includes/RtsTypeable.h
@@ -9,8 +9,6 @@
#ifndef GHC_RTS_TYPEABLE_H
#define GHC_RTS_TYPEABLE_H
-#include "Stg.h"
-
void initTypeableStore(void);
void exitTypeableStore(void);
diff --git a/includes/SMP.h b/includes/SMP.h
index a91e5d5619..0e6322d40b 100644
--- a/includes/SMP.h
+++ b/includes/SMP.h
@@ -1,8 +1,8 @@
/* ----------------------------------------------------------------------------
*
- * (c) The GHC Team, 2005
+ * (c) The GHC Team, 2005-2008
*
- * Macros for THREADED_RTS support
+ * Macros for multi-CPU support
*
* -------------------------------------------------------------------------- */
@@ -175,132 +175,6 @@ write_barrier(void) {
#endif
}
-/* -----------------------------------------------------------------------------
- * Locking/unlocking closures
- *
- * This is used primarily in the implementation of MVars.
- * -------------------------------------------------------------------------- */
-
-#define SPIN_COUNT 4000
-
-#ifdef KEEP_LOCKCLOSURE
-// We want a callable copy of lockClosure() so that we can refer to it
-// from .cmm files compiled using the native codegen.
-extern StgInfoTable *lockClosure(StgClosure *p);
-INLINE_ME
-#else
-INLINE_HEADER
-#endif
-StgInfoTable *
-lockClosure(StgClosure *p)
-{
- StgWord info;
- do {
- nat i = 0;
- do {
- info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
- if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
- } while (++i < SPIN_COUNT);
- yieldThread();
- } while (1);
-}
-
-INLINE_HEADER void
-unlockClosure(StgClosure *p, const StgInfoTable *info)
-{
- // This is a strictly ordered write, so we need a write_barrier():
- write_barrier();
- p->header.info = info;
-}
-
-/* -----------------------------------------------------------------------------
- * Spin locks
- *
- * These are simple spin-only locks as opposed to Mutexes which
- * probably spin for a while before blocking in the kernel. We use
- * these when we are sure that all our threads are actively running on
- * a CPU, eg. in the GC.
- *
- * TODO: measure whether we really need these, or whether Mutexes
- * would do (and be a bit safer if a CPU becomes loaded).
- * -------------------------------------------------------------------------- */
-
-#if defined(DEBUG)
-typedef struct StgSync_
-{
- StgWord32 lock;
- StgWord64 spin; // DEBUG version counts how much it spins
-} StgSync;
-#else
-typedef StgWord StgSync;
-#endif
-
-typedef lnat StgSyncCount;
-
-
-#if defined(DEBUG)
-
-// Debug versions of spin locks maintain a spin count
-
-// How to use:
-// To use the debug veriosn of the spin locks, a debug version of the program
-// can be run under a deugger with a break point on stat_exit. At exit time
-// of the program one can examine the state the spin count counts of various
-// spin locks to check for contention.
-
-// acquire spin lock
-INLINE_HEADER void ACQUIRE_SPIN_LOCK(StgSync * p)
-{
- StgWord32 r = 0;
- do {
- p->spin++;
- r = cas((StgVolatilePtr)&(p->lock), 1, 0);
- } while(r == 0);
- p->spin--;
-}
-
-// release spin lock
-INLINE_HEADER void RELEASE_SPIN_LOCK(StgSync * p)
-{
- write_barrier();
- p->lock = 1;
-}
-
-// initialise spin lock
-INLINE_HEADER void initSpinLock(StgSync * p)
-{
- write_barrier();
- p->lock = 1;
- p->spin = 0;
-}
-
-#else
-
-// acquire spin lock
-INLINE_HEADER void ACQUIRE_SPIN_LOCK(StgSync * p)
-{
- StgWord32 r = 0;
- do {
- r = cas((StgVolatilePtr)p, 1, 0);
- } while(r == 0);
-}
-
-// release spin lock
-INLINE_HEADER void RELEASE_SPIN_LOCK(StgSync * p)
-{
- write_barrier();
- (*p) = 1;
-}
-
-// init spin lock
-INLINE_HEADER void initSpinLock(StgSync * p)
-{
- write_barrier();
- (*p) = 1;
-}
-
-#endif /* DEBUG */
-
/* ---------------------------------------------------------------------- */
#else /* !THREADED_RTS */
@@ -314,30 +188,8 @@ xchg(StgPtr p, StgWord w)
return old;
}
-INLINE_HEADER StgInfoTable *
-lockClosure(StgClosure *p)
-{ return (StgInfoTable *)p->header.info; }
-
-INLINE_HEADER void
-unlockClosure(StgClosure *p STG_UNUSED, const StgInfoTable *info STG_UNUSED)
-{ /* nothing */ }
-
-// Using macros here means we don't have to ensure the argument is in scope
-#define ACQUIRE_SPIN_LOCK(p) /* nothing */
-#define RELEASE_SPIN_LOCK(p) /* nothing */
-
-INLINE_HEADER void initSpinLock(void * p STG_UNUSED)
-{ /* nothing */ }
-
#endif /* !THREADED_RTS */
-// Handy specialised versions of lockClosure()/unlockClosure()
-INLINE_HEADER void lockTSO(StgTSO *tso)
-{ lockClosure((StgClosure *)tso); }
-
-INLINE_HEADER void unlockTSO(StgTSO *tso)
-{ unlockClosure((StgClosure*)tso, (const StgInfoTable *)&stg_TSO_info); }
+#endif /* CMINUSMINUS */
#endif /* SMP_H */
-
-#endif /* CMINUSMINUS */
diff --git a/includes/SMPClosureOps.h b/includes/SMPClosureOps.h
new file mode 100644
index 0000000000..fe78168011
--- /dev/null
+++ b/includes/SMPClosureOps.h
@@ -0,0 +1,71 @@
+/* ----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 2005
+ *
+ * Macros for THREADED_RTS support
+ *
+ * -------------------------------------------------------------------------- */
+
+#ifndef SMPCLOSUREOPS_H
+#define SMPCLOSUREOPS_H
+
+#if defined(THREADED_RTS)
+
+/* -----------------------------------------------------------------------------
+ * Locking/unlocking closures
+ *
+ * This is used primarily in the implementation of MVars.
+ * -------------------------------------------------------------------------- */
+
+#define SPIN_COUNT 4000
+
+#ifdef KEEP_LOCKCLOSURE
+// We want a callable copy of lockClosure() so that we can refer to it
+// from .cmm files compiled using the native codegen.
+extern StgInfoTable *lockClosure(StgClosure *p);
+INLINE_ME
+#else
+INLINE_HEADER
+#endif
+StgInfoTable *
+lockClosure(StgClosure *p)
+{
+ StgWord info;
+ do {
+ nat i = 0;
+ do {
+ info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
+ } while (++i < SPIN_COUNT);
+ yieldThread();
+ } while (1);
+}
+
+INLINE_HEADER void
+unlockClosure(StgClosure *p, const StgInfoTable *info)
+{
+ // This is a strictly ordered write, so we need a write_barrier():
+ write_barrier();
+ p->header.info = info;
+}
+
+#else /* !THREADED_RTS */
+
+INLINE_HEADER StgInfoTable *
+lockClosure(StgClosure *p)
+{ return (StgInfoTable *)p->header.info; }
+
+INLINE_HEADER void
+unlockClosure(StgClosure *p STG_UNUSED, const StgInfoTable *info STG_UNUSED)
+{ /* nothing */ }
+
+#endif /* THREADED_RTS */
+
+// Handy specialised versions of lockClosure()/unlockClosure()
+INLINE_HEADER void lockTSO(StgTSO *tso)
+{ lockClosure((StgClosure *)tso); }
+
+INLINE_HEADER void unlockTSO(StgTSO *tso)
+{ unlockClosure((StgClosure*)tso, (const StgInfoTable *)&stg_TSO_info); }
+
+#endif /* SMPCLOSUREOPS_H */
diff --git a/includes/SpinLock.h b/includes/SpinLock.h
new file mode 100644
index 0000000000..de08ca1aa5
--- /dev/null
+++ b/includes/SpinLock.h
@@ -0,0 +1,110 @@
+/* ----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 2006-2008
+ *
+ * Spin locks
+ *
+ * These are simple spin-only locks as opposed to Mutexes which
+ * probably spin for a while before blocking in the kernel. We use
+ * these when we are sure that all our threads are actively running on
+ * a CPU, eg. in the GC.
+ *
+ * TODO: measure whether we really need these, or whether Mutexes
+ * would do (and be a bit safer if a CPU becomes loaded).
+ *
+ * -------------------------------------------------------------------------- */
+
+#ifndef SPINLOCK_H
+#define SPINLOCK_H
+
+#if defined(THREADED_RTS)
+
+#if defined(DEBUG)
+typedef struct StgSync_
+{
+ StgWord32 lock;
+ StgWord64 spin; // DEBUG version counts how much it spins
+} StgSync;
+#else
+typedef StgWord StgSync;
+#endif
+
+typedef lnat StgSyncCount;
+
+
+#if defined(DEBUG)
+
+// Debug versions of spin locks maintain a spin count
+
+// How to use:
+// To use the debug veriosn of the spin locks, a debug version of the program
+// can be run under a deugger with a break point on stat_exit. At exit time
+// of the program one can examine the state the spin count counts of various
+// spin locks to check for contention.
+
+// acquire spin lock
+INLINE_HEADER void ACQUIRE_SPIN_LOCK(StgSync * p)
+{
+ StgWord32 r = 0;
+ do {
+ p->spin++;
+ r = cas((StgVolatilePtr)&(p->lock), 1, 0);
+ } while(r == 0);
+ p->spin--;
+}
+
+// release spin lock
+INLINE_HEADER void RELEASE_SPIN_LOCK(StgSync * p)
+{
+ write_barrier();
+ p->lock = 1;
+}
+
+// initialise spin lock
+INLINE_HEADER void initSpinLock(StgSync * p)
+{
+ write_barrier();
+ p->lock = 1;
+ p->spin = 0;
+}
+
+#else
+
+// acquire spin lock
+INLINE_HEADER void ACQUIRE_SPIN_LOCK(StgSync * p)
+{
+ StgWord32 r = 0;
+ do {
+ r = cas((StgVolatilePtr)p, 1, 0);
+ } while(r == 0);
+}
+
+// release spin lock
+INLINE_HEADER void RELEASE_SPIN_LOCK(StgSync * p)
+{
+ write_barrier();
+ (*p) = 1;
+}
+
+// init spin lock
+INLINE_HEADER void initSpinLock(StgSync * p)
+{
+ write_barrier();
+ (*p) = 1;
+}
+
+#endif /* DEBUG */
+
+#else /* !THREADED_RTS */
+
+// Using macros here means we don't have to ensure the argument is in scope
+#define ACQUIRE_SPIN_LOCK(p) /* nothing */
+#define RELEASE_SPIN_LOCK(p) /* nothing */
+
+INLINE_HEADER void initSpinLock(void * p STG_UNUSED)
+{ /* nothing */ }
+
+#endif /* THREADED_RTS */
+
+#endif /* SPINLOCK_H */
+
diff --git a/includes/Stg.h b/includes/Stg.h
index 1facd5f405..6ddf17a0a0 100644
--- a/includes/Stg.h
+++ b/includes/Stg.h
@@ -41,6 +41,11 @@
#include "ghcconfig.h"
#include "RtsConfig.h"
+/* The code generator calls the math functions directly in .hc code.
+ NB. after configuration stuff above, because this sets #defines
+ that depend on config info, such as __USE_FILE_OFFSET64 */
+#include <math.h>
+
/* -----------------------------------------------------------------------------
Useful definitions
-------------------------------------------------------------------------- */
@@ -148,7 +153,6 @@ typedef StgWord StgWordArray[];
#include "StgDLL.h"
#include "MachRegs.h"
#include "Regs.h"
-#include "StgProf.h" /* ToDo: separate out RTS-only stuff from here */
#if IN_STG_CODE
/*
@@ -158,8 +162,7 @@ typedef StgWord StgWordArray[];
#include "StgMiscClosures.h"
#endif
-/* RTS external interface */
-#include "RtsExternal.h"
+#include "SMP.h" // write_barrier() inline is required
/* -----------------------------------------------------------------------------
Moving Floats and Doubles
diff --git a/includes/StgMiscClosures.h b/includes/StgMiscClosures.h
index a99ff72a22..c82ec05bd4 100644
--- a/includes/StgMiscClosures.h
+++ b/includes/StgMiscClosures.h
@@ -493,6 +493,12 @@ RTS_FUN(stg_threadFinished);
RTS_FUN(stg_init_finish);
RTS_FUN(stg_init);
+RTS_FUN(StgReturn);
+
+extern int rts_stop_next_breakpoint;
+extern int rts_stop_on_exception;
+extern void *rts_breakpoint_io_action;
+
/* -----------------------------------------------------------------------------
PrimOps
-------------------------------------------------------------------------- */
@@ -598,4 +604,42 @@ RTS_FUN(getApStackValzh_fast);
RTS_FUN(noDuplicatezh_fast);
+/* Other misc stuff */
+
+#if IN_STG_CODE && !IN_STGCRUN
+
+// Schedule.c
+extern int RTS_VAR(context_switch);
+extern StgWord RTS_VAR(blocked_queue_hd), RTS_VAR(blocked_queue_tl);
+extern StgWord RTS_VAR(sleeping_queue);
+extern StgWord RTS_VAR(blackhole_queue);
+extern StgWord RTS_VAR(sched_mutex);
+
+// Apply.cmm
+// canned bitmap for each arg type
+extern StgWord stg_arg_bitmaps[];
+
+// Storage.c
+extern unsigned int RTS_VAR(alloc_blocks);
+extern unsigned int RTS_VAR(alloc_blocks_lim);
+extern StgWord RTS_VAR(weak_ptr_list);
+extern StgWord RTS_VAR(atomic_modify_mutvar_mutex);
+
+// RtsFlags
+extern StgWord RTS_VAR(RtsFlags); // bogus type
+
+// Stable.c
+extern StgWord RTS_VAR(stable_ptr_table);
+
+// Profiling.c
+extern unsigned int RTS_VAR(era);
+extern StgWord RTS_VAR(CCCS); /* current CCS */
+extern unsigned int RTS_VAR(entering_PAP);
+extern StgWord RTS_VAR(CC_LIST); /* registered CC list */
+extern StgWord RTS_VAR(CCS_LIST); /* registered CCS list */
+extern unsigned int RTS_VAR(CC_ID); /* global ids */
+extern unsigned int RTS_VAR(CCS_ID);
+
+#endif
+
#endif /* STGMISCCLOSURES_H */