summaryrefslogtreecommitdiff
path: root/ghc/rts/parallel/GranSimRts.h
blob: fc31a1f0a606d5a6cad75ae8e4f7a33aba349064 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/* --------------------------------------------------------------------------
   Time-stamp: <Tue Mar 06 2001 00:18:30 Stardate: [-30]6285.06 hwloidl>

   Variables and functions specific to GranSim.
   ----------------------------------------------------------------------- */

#ifndef GRANSIM_RTS_H
#define GRANSIM_RTS_H

//@node Headers for GranSim objs used only in the RTS internally, , ,
//@section Headers for GranSim objs used only in the RTS internally

//@menu
//* Event queue::		
//* Spark handling routines::	
//* Processor related stuff::	
//* Local types::		
//* Statistics gathering::	
//* Prototypes::		
//@end menu
//*/ fool highlight

//@node Event queue, Spark handling routines, Headers for GranSim objs used only in the RTS internally, Headers for GranSim objs used only in the RTS internally
//@subsection Event queue

#if defined(GRAN) || defined(PAR)
/* Granularity event types for output (see DumpGranEvent) */
typedef enum GranEventType_ {
    GR_START = 0, GR_STARTQ, 
    GR_STEALING, GR_STOLEN, GR_STOLENQ, 
    GR_FETCH, GR_REPLY, GR_BLOCK, GR_RESUME, GR_RESUMEQ,
    GR_SCHEDULE, GR_DESCHEDULE,
    GR_END,
    SP_SPARK, SP_SPARKAT, SP_USED, SP_PRUNED, SP_EXPORTED, SP_ACQUIRED, SP_REQUESTED,
    GR_ALLOC,
    GR_TERMINATE,
    GR_SYSTEM_START, GR_SYSTEM_END,            /* only for debugging */
    GR_EVENT_MAX
} GranEventType;

extern char *gran_event_names[];
#endif

#if defined(GRAN)                                            /* whole file */

/* Event Types (internal use only) */
typedef enum rtsEventType_ {
 ContinueThread = 0,  /* Continue running the first thread in the queue */
 StartThread,         /* Start a newly created thread */
 ResumeThread,        /* Resume a previously running thread */
 MoveSpark,           /* Move a spark from one PE to another */
 MoveThread,          /* Move a thread from one PE to another */
 FindWork,            /* Search for work */
 FetchNode,           /* Fetch a node */
 FetchReply,          /* Receive a node */
 GlobalBlock,         /* Block a TSO on a remote node */
 UnblockThread        /* Make a TSO runnable */
} rtsEventType;

/* Number of last event type */
#define MAX_EVENT       9
 
typedef struct rtsEvent_ {
  PEs           proc;    /* Processor id */
  PEs           creator; /* Processor id of PE that created the event */
  rtsEventType  evttype; /* rtsEvent type */
  rtsTime       time;    /* Time at which event happened */
  StgTSO       *tso;     /* Associated TSO, if relevant */
  StgClosure   *node;    /* Associated node, if relevant */
  rtsSpark     *spark;   /* Associated SPARK, if relevant */
  StgInt        gc_info; /* Counter of heap objects to mark (used in GC only)*/
  struct rtsEvent_ *next;
  } rtsEvent;

typedef rtsEvent *rtsEventQ;

extern rtsEventQ EventHd;

/* Interface for ADT of Event Queue */
rtsEvent *get_next_event(void);
rtsTime   get_time_of_next_event(void);
void      insert_event(rtsEvent *newentry);
void      new_event(PEs proc, PEs creator, rtsTime time, 
		    rtsEventType evttype, StgTSO *tso, 
		    StgClosure *node, rtsSpark *spark);
void      print_event(rtsEvent *event);
void      print_eventq(rtsEvent *hd);
void      prepend_event(rtsEvent *event);
rtsEventQ grab_event(void);
void      prune_eventq(StgTSO *tso, StgClosure *node); 

void      traverse_eventq_for_gc(void);
void      markEventQueue(void);

//@node Spark handling routines, Processor related stuff, Event queue, Headers for GranSim objs used only in the RTS internally
//@subsection Spark handling routines

/* These functions are only used in the RTS internally; see GranSim.h for rest */
void 	  disposeSpark(rtsSpark *spark);
void 	  disposeSparkQ(rtsSparkQ spark);
void 	  print_spark(rtsSpark *spark);
void      print_sparkq(PEs proc);
void 	  print_sparkq_stats(void);
nat  	  spark_queue_len(PEs proc);
rtsSpark *delete_from_sparkq (rtsSpark *spark, PEs p, rtsBool dispose_too);
void      markSparkQueue(void);

//@node Processor related stuff, Local types, Spark handling routines, Headers for GranSim objs used only in the RTS internally
//@subsection Processor related stuff

typedef enum rtsProcStatus_ {
  Idle = 0,             /* empty threadq */
  Sparking,             /* non-empty sparkq; FINDWORK has been issued */
  Starting,             /* STARTTHREAD has been issue */
  Fetching,             /* waiting for remote data (only if block-on-fetch) */
  Fishing,              /* waiting for remote spark/thread */
  Busy                  /* non-empty threadq, with head of queue active */
} rtsProcStatus;

/*
#define IS_IDLE(proc)        (procStatus[proc] == Idle)
#define IS_SPARKING(proc)    (procStatus[proc] == Sparking)
#define IS_STARTING(proc)    (procStatus[proc] == Starting)
#define IS_FETCHING(proc)    (procStatus[proc] == Fetching)
#define IS_FISHING(proc)     (procStatus[proc] == Fishing)
#define IS_BUSY(proc)        (procStatus[proc] == Busy)    
#define ANY_IDLE             (any_idle())
#define MAKE_IDLE(proc)      procStatus[proc] = Idle
#define MAKE_SPARKING(proc)  procStatus[proc] = Sparking
#define MAKE_STARTING(proc)  procStatus[proc] = Starting
#define MAKE_FETCHING(proc)  procStatus[proc] = Fetching
#define MAKE_FISHING(proc)   procStatus[proc] = Fishing
#define MAKE_BUSY(proc)      procStatus[proc] = Busy
*/

//@node Local types, Statistics gathering, Processor related stuff, Headers for GranSim objs used only in the RTS internally
//@subsection Local types

/* Return codes of HandleFetchRequest:
    0 ... ok (FETCHREPLY event with a buffer containing addresses of the 
              nearby graph has been scheduled)
    1 ... node is already local (fetched by somebody else; no event is
                                  scheduled in here)
    2 ... fetch request has been forwrded to the PE that now contains the
           node
    3 ... node is a black hole (BH, BQ or RBH); no event is scheduled, and
           the current TSO is put into the blocking queue of that node
    4 ... out of heap in PackNearbyGraph; GC should be triggered in calling
          function to guarantee that the tso and node inputs are valid
          (they may be moved during GC).
   Return codes of blockFetch:
    0 ... ok; tso is now at beginning of BQ attached to the bh closure
    1 ... the bh closure is no BH any more; tso is immediately unblocked
*/

typedef enum rtsFetchReturnCode_ {
  Ok = 0,
  NodeIsLocal,
  NodeHasMoved,
  NodeIsBH,
  NodeIsNoBH,
  OutOfHeap,
} rtsFetchReturnCode;
  
//@node Statistics gathering, Prototypes, Local types, Headers for GranSim objs used only in the RTS internally
//@subsection Statistics gathering

extern unsigned int /* nat */ OutstandingFetches[], OutstandingFishes[];
extern rtsProcStatus procStatus[];
extern StgTSO *BlockedOnFetch[];

/* global structure for collecting statistics */
typedef struct GlobalGranStats_ {
  /* event stats */
  nat noOfEvents;
  nat event_counts[MAX_EVENT];

  /* communication stats */
  nat fetch_misses;
  nat tot_fake_fetches;   // GranSim internal; faked Fetches are a kludge!!
  nat tot_low_pri_sparks;

  /* load distribution statistics */  
  nat rs_sp_count, rs_t_count, ntimes_total, fl_total, 
      no_of_steals, no_of_migrates;

  /* spark queue stats */
  nat tot_sq_len, tot_sq_probes, tot_sparks;
  nat tot_add_threads, tot_tq_len, non_end_add_threads;

  /* packet statistics */
  nat tot_packets, tot_packet_size, tot_cuts, tot_thunks;

  /* thread stats */
  nat tot_threads_created, threads_created_on_PE[MAX_PROC],
      tot_TSOs_migrated;

  /* spark stats */
  nat pruned_sparks, withered_sparks;
  nat tot_sparks_created, sparks_created_on_PE[MAX_PROC];

  /* scheduling stats */
  nat tot_yields, tot_stackover, tot_heapover;

  /* blocking queue statistics */
  rtsTime tot_bq_processing_time;
  nat tot_bq_len, tot_bq_len_local, tot_awbq, tot_FMBQs;
} GlobalGranStats;

extern GlobalGranStats globalGranStats;

//@node Prototypes,  , Statistics gathering, Headers for GranSim objs used only in the RTS internally
//@subsection Prototypes

/* Generally useful fcts */
PEs where_is(StgClosure *node);
rtsBool is_unique(StgClosure *node);

/* Prototypes of event handling functions; needed in Schedule.c:ReSchedule() */
void do_the_globalblock (rtsEvent* event);
void do_the_unblock (rtsEvent* event);
void do_the_fetchnode (rtsEvent* event);
void do_the_fetchreply (rtsEvent* event);
void do_the_movethread (rtsEvent* event);
void do_the_movespark (rtsEvent* event);
void do_the_startthread(rtsEvent *event);
void do_the_findwork(rtsEvent* event);
void gimme_spark (rtsEvent *event, rtsBool *found_res, rtsSparkQ *spark_res);
rtsBool munch_spark (rtsEvent *event, rtsSparkQ spark);

/* GranSimLight routines */
void GranSimLight_enter_system(rtsEvent *event, StgTSO **ActiveTSOp);
void GranSimLight_leave_system(rtsEvent *event, StgTSO **ActiveTSOp);

/* Communication related routines */
rtsFetchReturnCode fetchNode(StgClosure* node, PEs from, PEs to);
rtsFetchReturnCode handleFetchRequest(StgClosure* node, PEs curr_proc, PEs p, StgTSO* tso);
void               handleIdlePEs(void);

long int random(void); /* used in stealSpark() and stealThread() in GranSim.c */

/* Scheduling fcts defined in GranSim.c */
void    insertThread(StgTSO *tso, PEs proc);
void    endThread(StgTSO *tso, PEs proc);
rtsBool GranSimLight_insertThread(StgTSO *tso, PEs proc);
nat     thread_queue_len(PEs proc);

/* For debugging */
rtsBool is_on_queue (StgTSO *tso, PEs proc);
#endif

#if defined(GRAN) || defined(PAR)
/* 
   Interface for dumping routines (i.e. writing to log file).
   These routines are shared with GUM (and could also be used for SMP).
*/
void DumpGranEvent(GranEventType name, StgTSO *tso);
void DumpEndEvent(PEs proc, StgTSO *tso, rtsBool mandatory_thread);
void DumpTSO(StgTSO *tso);
void DumpRawGranEvent(PEs proc, PEs p, GranEventType name, 
 	              StgTSO *tso, StgClosure *node, 
		      StgInt sparkname, StgInt len);
void DumpVeryRawGranEvent(rtsTime time, PEs proc, PEs p, GranEventType name,
			  StgTSO *tso, StgClosure *node, 
			  StgInt sparkname, StgInt len);
#endif

#endif /* GRANSIM_RTS_H  */