summaryrefslogtreecommitdiff
path: root/ghc/includes/Parallel.lh
diff options
context:
space:
mode:
authorpartain <unknown>1996-01-08 20:28:12 +0000
committerpartain <unknown>1996-01-08 20:28:12 +0000
commite7d21ee4f8ac907665a7e170c71d59e13a01da09 (patch)
tree93715bf4e6e4bbe8049e4d8d4d3fbd19158a88d6 /ghc/includes/Parallel.lh
parente48474bff05e6cfb506660420f025f694c870d38 (diff)
downloadhaskell-e7d21ee4f8ac907665a7e170c71d59e13a01da09.tar.gz
[project @ 1996-01-08 20:28:12 by partain]
Initial revision
Diffstat (limited to 'ghc/includes/Parallel.lh')
-rw-r--r--ghc/includes/Parallel.lh512
1 files changed, 512 insertions, 0 deletions
diff --git a/ghc/includes/Parallel.lh b/ghc/includes/Parallel.lh
new file mode 100644
index 0000000000..83f2f444f9
--- /dev/null
+++ b/ghc/includes/Parallel.lh
@@ -0,0 +1,512 @@
+%
+% (c) Kevin Hammond, Parade/AQUA Projects, Glasgow University, February 15th. 1995
+%
+% This is for GUM only.
+%
+%************************************************************************
+%* *
+\section[Parallel.lh]{Definitions for parallel machines}
+%* *
+%************************************************************************
+
+Multi-slurp protection:
+\begin{code}
+#ifndef Parallel_H
+#define Parallel_H
+\end{code}
+
+This section contains definitions applicable only to programs compiled
+to run on a parallel machine. Some of these things can probably be
+ripped out now that we don't store GAs in closures, but beware that
+this {\em might} break GranSim, so check first! KH
+
+These basic definitions need to be around, one way or the other:
+\begin{code}
+#define PAR_FIXED_HDR (GA_HDR_SIZE)
+#define PAR_HDR_POSN AFTER_INFO_HDR
+#define AFTER_PAR_HDR (PAR_HDR_POSN+PAR_FIXED_HDR)
+
+#define SET_PAR_HDR(closure,ga) /* nothing */
+#define SET_STATIC_PAR_HDR(closure) /* nothing */
+\end{code}
+
+\begin{code}
+# ifdef PAR
+# define MAX_PES 128 /* Maximum number of processors */
+
+extern I_ do_gr_profile;
+extern I_ do_sp_profile;
+extern I_ do_gr_binary;
+
+extern P_ PendingFetches;
+extern GLOBAL_TASK_ID *PEs;
+
+extern rtsBool IAmMainThread, GlobalStopPending;
+extern rtsBool fishing;
+extern GLOBAL_TASK_ID SysManTask;
+extern int seed; /*pseudo-random-number generator seed:*/
+ /*Initialised in ParInit*/
+extern I_ threadId; /*Number of Threads that have existed on a PE*/
+extern GLOBAL_TASK_ID mytid;
+
+extern int nPEs;
+
+extern rtsBool InGlobalGC; /* Are we in the midst of performing global GC */
+
+extern HashTable *pGAtoGALAtable;
+extern HashTable *LAtoGALAtable;
+extern GALA *freeIndirections;
+extern GALA *liveIndirections;
+extern GALA *freeGALAList;
+extern GALA *liveRemoteGAs;
+extern int thisPE;
+
+void RunParallelSystem PROTO((StgPtr program_closure));
+void initParallelSystem(STG_NO_ARGS);
+void SynchroniseSystem(STG_NO_ARGS);
+
+void registerTask PROTO((GLOBAL_TASK_ID gtid));
+globalAddr *LAGAlookup PROTO((P_ addr));
+P_ GALAlookup PROTO((globalAddr *ga));
+globalAddr *MakeGlobal PROTO((P_ addr, rtsBool preferred));
+globalAddr *setRemoteGA PROTO((P_ addr, globalAddr *ga, rtsBool preferred));
+void splitWeight PROTO((globalAddr *to, globalAddr *from));
+globalAddr *addWeight PROTO((globalAddr *ga));
+void initGAtables(STG_NO_ARGS);
+W_ taskIDtoPE PROTO((GLOBAL_TASK_ID gtid));
+void RebuildLAGAtable(STG_NO_ARGS);
+
+void *lookupHashTable PROTO((HashTable *table, StgWord key));
+void insertHashTable PROTO((HashTable *table, StgWord key, void *data));
+void freeHashTable PROTO((HashTable *table, void (*freeDataFun) PROTO((void *data))));
+HashTable *allocHashTable(STG_NO_ARGS);
+void *removeHashTable PROTO((HashTable *table, StgWord key, void *data));
+
+extern void myexit PROTO((I_));
+# define EXIT myexit
+# define exit : error : Wrong exit!
+# else
+# define EXIT exit
+# endif
+
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[anti-parallel-SM]{But if we're {\em not} compiling for a parallel system...}
+%* *
+%************************************************************************
+
+Get this out of the way. These are all null definitions.
+
+\begin{code}
+# if !(defined(GRAN) || defined(PAR))
+
+# define GA_HDR_SIZE 0
+# define GA(closure) /*nothing*/
+
+# define SET_GA(closure,ga) /* nothing */
+# define SET_STATIC_GA(closure) /* nothing */
+# define SET_GRAN_HDR(closure,pe) /* nothing */
+# define SET_STATIC_PROCS(closure) /* nothing */
+
+# define SET_TASK_ACTIVITY(act) /* nothing */
+
+# else
+# ifdef GRAN
+
+# define GA_HDR_SIZE 1
+
+# define PROCS_HDR_POSN PAR_HDR_POSN
+# define PROCS_HDR_SIZE 1
+
+/* Accessing components of the field */
+# define PROCS(closure) (*((P_)(closure)+PROCS_HDR_POSN))
+
+# define SET_PROCS(closure, procs) \
+ PROCS(closure) = (W_)(procs) /* Set closure's location */
+# define SET_GRAN_HDR(closure,pe) SET_PROCS(closure,pe)
+
+# if defined(GRAN_TNG)
+# define SET_STATIC_PROCS(closure) , (W_) (Everywhere)
+# else
+# define SET_STATIC_PROCS(closure) , (W_) (MainPE)
+# endif /* GRAN_TNG */
+
+# define SET_TASK_ACTIVITY(act) /* nothing */
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[parallel-GAs]{Parallel-only part of fixed headers (global addresses)}
+%* *
+%************************************************************************
+
+Definitions relating to the entire parallel-only fixed-header field.
+
+On GUM, the global addresses for each local closure are stored in a separate
+hash table, rather then with the closure in the heap. We call @getGA@ to
+look up the global address associated with a local closure (0 is returned
+for local closures that have no global address), and @setGA@ to store a new
+global address for a local closure which did not previously have one.
+
+\begin{code}
+# else /* it must be PARallel (to end of file) */
+
+# define GA_HDR_SIZE 0
+
+# define GA(closure) getGA(closure)
+
+# define SET_GA(closure, ga) setGA(closure,ga)
+# define SET_STATIC_GA(closure)
+# define SET_GRAN_HDR(closure,pe)
+# define SET_STATIC_PROCS(closure)
+
+# define MAX_GA_WEIGHT 0 /* Treat as 2^n */
+
+# define PACK_GA(pe,slot) ((((W_)(pe)) << (BITS_IN(W_)/2)) | ((W_)(slot)))
+
+\end{code}
+
+At the moment, there is no activity profiling for GUM. This may change.
+
+\begin{code}
+
+# define SET_TASK_ACTIVITY(act)
+
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[parallel-heap-objs]{Special parallel-only heap objects (`closures')}
+%* *
+%************************************************************************
+
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% NB: The following definitons are BOTH for GUM and GrAnSim -- HWL
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+The rest of this file contains definitions for {\it GUM and GrAnSim}.
+Although we don't create FetchMe nodes in GrAnSim (we simulate it by
+bitmask twiddling) we use FetchMe_info when converting nodes into RBHs
+(mainly to keep the code as close to GUM as possible). So, we define all
+the FetchMe related stuff in GrAnSim, too. % -- HWL
+
+%************************************************************************
+%* *
+\subsubsection[FETCHME-closures]{@FETCHME@ heap objects (`closures')}
+%* *
+%************************************************************************
+
+FetchMes are pointers into the global heap. When evaluated, the value
+they point to is read from the global heap.
+
+A FetchMe closure has the form:
+
+\begin{onlylatex}
+\begin{center}
+\end{onlylatex}
+\begin{tabular}{||l|l||}\hline
+\tr{FETCHME_info} & junk \\ \hline
+\end{tabular}
+\begin{onlylatex}
+\end{center}
+\end{onlylatex}
+
+The argument word is a pointer (outside of the heap) to a globalAddr structure...
+in particular, the one corresponding to the object to be fetched. Note that
+we can't just used the LAGA table, because weight-splitting may force us to
+reassign a local GA to the @FetchMe@ so that we can give out new references.
+
+A @FetchMe@ must have a valid @MUT_LINK@ field, because it may act as
+a transition between an RBH on the OldMutables list and a BQ still on
+the OldMutables list.
+
+
+\begin{code}
+# define FETCHME_VHS IND_VHS
+# define FETCHME_HS IND_HS
+
+# define FETCHME_GA_LOCN FETCHME_HS
+
+# define FETCHME_CLOSURE_SIZE(closure) IND_CLOSURE_SIZE(closure)
+# define FETCHME_CLOSURE_NoPTRS(closure) 0L
+# define FETCHME_CLOSURE_NoNONPTRS(closure) (IND_CLOSURE_SIZE(closure)-IND_VHS)
+
+# define SET_FETCHME_HDR(closure,infolbl,cc,size,ptrs) \
+{ SET_FIXED_HDR(closure,FetchMe_info,<bogus CC>); \
+ SET_MUT_RESERVED_WORDS(closure); \
+}
+
+# define FETCHME_GA(closure) (((globalAddr **)(closure))[FETCHME_GA_LOCN])
+
+EXTFUN(FetchMe_entry);
+EXTDATA_RO(FetchMe_info);
+
+\end{code}
+
+%************************************************************************
+%* *
+\subsubsection[BlockedFetch-closures]{@BlockedFetch@ heap objects (`closures')}
+%* *
+%************************************************************************
+
+@BlockedFetch@s are inbound fetch messages blocked on local closures.
+They arise as entries in a local blocking queue when a fetch has been
+received for a local black hole. When awakened, we look at their
+contents to figure out where to send a resume.
+
+A @BlockedFetch@ closure has the form:
+
+\begin{onlylatex}
+\begin{center}
+\end{onlylatex}
+\begin{tabular}{||l|l|l||}\hline
+\tr{BF_info} & link & node & gtid & slot & weight \\ \hline
+\end{tabular}
+\begin{onlylatex}
+\end{center}
+\end{onlylatex}
+
+\begin{code}
+# define BF_VHS (GC_MUT_RESERVED_WORDS)
+# define BF_HS (FIXED_HS + BF_VHS)
+
+# define BF_LINK_LOCN (BF_HS)
+# define BF_NODE_LOCN (BF_HS + 1)
+# define BF_GTID_LOCN (BF_HS + 2)
+# define BF_SLOT_LOCN (BF_HS + 3)
+# define BF_WEIGHT_LOCN (BF_HS + 4)
+
+# define BF_CLOSURE_NoPTRS(closure) 2
+# define BF_CLOSURE_NoNONPTRS(closure) 3
+
+# define BF_CLOSURE_SIZE(closure) (BF_VHS + 5)
+
+# define BF_LINK(closure) (((PP_)closure)[BF_LINK_LOCN])
+# define BF_NODE(closure) (((PP_)closure)[BF_NODE_LOCN])
+# define BF_GTID(closure) (((P_)closure)[BF_GTID_LOCN])
+# define BF_SLOT(closure) (((P_)closure)[BF_SLOT_LOCN])
+# define BF_WEIGHT(closure) (((P_)closure)[BF_WEIGHT_LOCN])
+
+# define BF_CLOSURE_PTR(closure, no) (((P_)(closure))[BF_HS + (no) - 1])
+
+/* std start-filling-in macro: */
+# define SET_BF_HDR(closure,infolbl,cc) \
+{ SET_FIXED_HDR(closure,infolbl,cc); \
+ SET_MUT_RESERVED_WORDS(closure); \
+}
+
+EXTFUN(BF_entry);
+EXTDATA_RO(BF_info);
+
+\end{code}
+
+%************************************************************************
+%* *
+\subsubsection[FMBQ-closures]{@FMBQ@ (FetchMe with blocking queue) heap objects (`closures')}
+%* *
+%************************************************************************
+
+FetchMe's with blocking queues are @Fetchme@ nodes which have been entered
+(and therefore a fetch has been sent), but for which we have not yet received
+a @Resume@ message. They look just like normal blocking queues, but have
+a distinguished info pointer.
+
+\begin{code}
+# define FMBQ_VHS BQ_VHS
+# define FMBQ_HS BQ_HS
+
+# define FMBQ_CLOSURE_SIZE(closure) BQ_CLOSURE_SIZE(closure)
+# define FMBQ_CLOSURE_NoPTRS(closure) BQ_CLOSURE_NoPTRS(closure)
+# define FMBQ_CLOSURE_NoNONPTRS(closure) BQ_CLOSURE_NoNONPTRS(closure)
+# define FMBQ_CLOSURE_PTR(closure, no) BQ_CLOSURE_PTR(closure, no)
+
+# define FMBQ_ENTRIES(closure) BQ_ENTRIES(closure)
+# define FMBQ_LINK(closure) BQ_LINK(closure)
+
+EXTFUN(FMBQ_entry);
+EXTDATA_RO(FMBQ_info);
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[parallel-info-tables]{Special parallel-only info-table stuff}
+%* *
+%************************************************************************
+
+%************************************************************************
+%* *
+\subsubsection[FETCHME_ITBL]{@FETCHME_ITBL@}
+%* *
+%************************************************************************
+
+ToDo: delete FetchMe CAT (because we don't profile and parallelize at
+the same time...) Even better...set things up so that we can profile
+and parallelize at the same time!
+
+\begin{code}
+
+# define FETCHME_ITBL(itbl_name,entry_code) \
+ CAT_DECLARE(FetchMe,INTERNAL_KIND,"FetchMe","<FetchMe>") \
+ EXTFUN(entry_code); \
+ EXTDATA_RO(MK_REP_LBL(FetchMe,,)); \
+ const W_ itbl_name[] = { \
+ (W_) entry_code \
+ ,(W_) INFO_OTHER_TAG \
+ ,(W_) MK_REP_REF(FetchMe,,) \
+ INCLUDE_PROFILING_INFO(FetchMe) \
+ }
+
+# define FETCHME_RTBL() \
+ const W_ MK_REP_LBL(FetchMe,,)[] = { \
+ INCLUDE_TYPE_INFO(FETCHME) \
+ INCLUDE_SIZE_INFO(MIN_UPD_SIZE, 0L) \
+ INCLUDE_PAR_INFO \
+ INCLUDE_COPYING_INFO(_Evacuate_FetchMe,_Scavenge_FetchMe) \
+ INCLUDE_COMPACTING_INFO(_ScanLink_FetchMe,_PRStart_FetchMe,_ScanMove_FetchMe,_PRIn_Error) \
+ }
+
+\end{code}
+
+%************************************************************************
+%* *
+\subsubsection[BF_ITBL]{@BF_ITBL@}
+%* *
+%************************************************************************
+
+The special info table used for thread state objects (BlockedFetchs).
+
+\begin{code}
+
+# define BF_ITBL() \
+ CAT_DECLARE(BF,INTERNAL_KIND,"BlockedFetch","<BlockedFetch>") \
+ EXTFUN(BF_entry); \
+ EXTDATA_RO(MK_REP_LBL(BF,,)); \
+ const W_ BF_info[] = { \
+ (W_) BF_entry \
+ ,(W_) INFO_OTHER_TAG \
+ ,(W_) MK_REP_REF(BF,,) \
+ INCLUDE_PROFILING_INFO(BF) \
+ }
+
+# define BF_RTBL() \
+ const W_ MK_REP_LBL(BF,,)[] = { \
+ INCLUDE_TYPE_INFO(BF) \
+ INCLUDE_SIZE_INFO(BF_CLOSURE_SIZE(dummy),BF_CLOSURE_NoPTRS(dummy)) \
+ INCLUDE_PAR_INFO \
+ INCLUDE_COPYING_INFO(_Evacuate_BF,_Scavenge_BF) \
+ INCLUDE_COMPACTING_INFO(_ScanLink_BF,_PRStart_BF,_ScanMove_BF,_PRIn_BF) \
+ }
+
+\end{code}
+
+%************************************************************************
+%* *
+\subsubsection[FMBQ_ITBL]{@FMBQ_ITBL@}
+%* *
+%************************************************************************
+
+Special info-table for local blocking queues.
+
+\begin{code}
+# define FMBQ_ITBL() \
+ CAT_DECLARE(FMBQ,INTERNAL_KIND,"FMBQ","<FMBQ>") \
+ EXTFUN(FMBQ_entry); \
+ EXTDATA_RO(MK_REP_LBL(FMBQ,,)); \
+ const W_ FMBQ_info[] = { \
+ (W_) FMBQ_entry \
+ ,(W_) INFO_OTHER_TAG \
+ ,(W_) MK_REP_REF(FMBQ,,) \
+ INCLUDE_PROFILING_INFO(FMBQ) \
+ }
+
+# define FMBQ_RTBL() \
+ const W_ MK_REP_LBL(FMBQ,,)[] = { \
+ INCLUDE_TYPE_INFO(FMBQ) \
+ INCLUDE_SIZE_INFO(MIN_UPD_SIZE,INFO_UNUSED) \
+ INCLUDE_PAR_INFO \
+ INCLUDE_COPYING_INFO(_Evacuate_BQ,_Scavenge_BQ) \
+ SPEC_COMPACTING_INFO(_ScanLink_BQ,_PRStart_BQ,_ScanMove_BQ,_PRIn_BQ) \
+ }
+
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[parallel-spark-pool-defs]{Parallel-only Spark pool definitions}
+%* *
+%************************************************************************
+
+\begin{code}
+# ifdef GRAN
+# define HAVE_SPARK ((PendingSparksHd[REQUIRED_POOL] != Nil_closure) || \
+ (PendingSparksHd[ADVISORY_POOL] != Nil_closure))
+# else
+# define HAVE_SPARK ((PendingSparksHd[REQUIRED_POOL] < PendingSparksTl[REQUIRED_POOL]) \
+ || (PendingSparksHd[ADVISORY_POOL] < PendingSparksTl[ADVISORY_POOL]))
+# endif
+
+# define HAVE_WORK (RUNNING_THREAD || HAVE_SPARK)
+# define RUNNING_THREAD (CurrentTSO != NULL)
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[parallel-pack-defs]{Parallel-only Packing definitions}
+%* *
+%************************************************************************
+
+
+Symbolic constants for the packing code.
+
+This constant defines how many words of data we can pack into a single
+packet in the parallel (GUM) system.
+
+\begin{code}
+# ifdef GUM
+P_ PackNearbyGraph PROTO((P_ closure,W_ *size));
+P_ PackTSO PROTO((P_ tso, W_ *size));
+P_ PackStkO PROTO((P_ stko, W_ *size));
+P_ AllocateHeap PROTO((W_ size)); /* Doesn't belong */
+
+P_ get_closure_info PROTO((P_ closure, W_ *size, W_ *ptrs, W_ *nonptrs, W_ *vhs));
+
+rtsBool isOffset PROTO((globalAddr *ga)),
+ isFixed PROTO((globalAddr *ga));
+
+void InitClosureQueue (STG_NO_ARGS);
+P_ DeQueueClosure(STG_NO_ARGS);
+void QueueClosure PROTO((P_ closure));
+rtsBool QueueEmpty(STG_NO_ARGS);
+void PrintPacket PROTO((P_ buffer));
+void doGlobalGC(STG_NO_ARGS);
+
+P_ UnpackGraph PROTO((W_ *buffer, globalAddr **gamap, W_ *nGAs));
+# endif
+
+# define PACK_BUFFER_SIZE 1024
+# define PACK_HEAP_REQUIRED \
+ ((PACK_BUFFER_SIZE - PACK_HDR_SIZE) / (PACK_GA_SIZE + _FHS) * (SPEC_HS + 2))
+
+\end{code}
+
+\begin{code}
+# define PACK_GA_SIZE 3 /* Size of a packed GA in words */
+ /* Size of a packed fetch-me in words */
+# define PACK_FETCHME_SIZE (PACK_GA_SIZE + FIXED_HS)
+
+# define PACK_HDR_SIZE 1 /* Words of header in a packet */
+
+# define PACK_PLC_SIZE 2 /* Size of a packed PLC in words */
+
+# define MAX_GAS (PACK_BUFFER_SIZE / PACK_GA_SIZE)
+
+\end{code}
+End multi-slurp protection:
+\begin{code}
+# endif /* yes, it is PARallel */
+#endif /* it was GRAN or PARallel */
+
+#endif /* Parallel_H */
+\end{code}