summaryrefslogtreecommitdiff
path: root/rts/sm/Storage.h
blob: a4421db3f279fde92e75a00a8dc933b9431f2df6 (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
/* -----------------------------------------------------------------------------
 *
 * (c) The GHC Team, 1998-2009
 *
 * External Storage Manger Interface
 *
 * ---------------------------------------------------------------------------*/

#ifndef SM_STORAGE_H
#define SM_STORAGE_H

#include "Capability.h"

#include "BeginPrivate.h"

/* -----------------------------------------------------------------------------
   Initialisation / De-initialisation
   -------------------------------------------------------------------------- */

void initStorage(void);
void exitStorage(void);
void freeStorage(rtsBool free_heap);

// Adding more Capabilities later: this function allocates nurseries
// and initialises other storage-related things.
void storageAddCapabilities (nat from, nat to);

/* -----------------------------------------------------------------------------
   Storage manager state
   -------------------------------------------------------------------------- */

INLINE_HEADER rtsBool
doYouWantToGC( Capability *cap )
{
  return (cap->r.rCurrentNursery->link == NULL ||
          g0->n_new_large_words >= large_alloc_lim);
}

/* for splitting blocks groups in two */
bdescr * splitLargeBlock (bdescr *bd, W_ blocks);

/* -----------------------------------------------------------------------------
   Generational garbage collection support

   updateWithIndirection(p1,p2)  Updates the object at p1 with an
                                 indirection pointing to p2.  This is
                                 normally called for objects in an old
                                 generation (>0) when they are updated.

   updateWithPermIndirection(p1,p2)  As above but uses a permanent indir.

   -------------------------------------------------------------------------- */

/*
 * Storage manager mutex
 */
#if defined(THREADED_RTS)
extern Mutex sm_mutex;
#endif

#if defined(THREADED_RTS)
#define ACQUIRE_SM_LOCK   ACQUIRE_LOCK(&sm_mutex);
#define RELEASE_SM_LOCK   RELEASE_LOCK(&sm_mutex);
#define ASSERT_SM_LOCK()  ASSERT_LOCK_HELD(&sm_mutex);
#else
#define ACQUIRE_SM_LOCK
#define RELEASE_SM_LOCK
#define ASSERT_SM_LOCK()
#endif

/* -----------------------------------------------------------------------------
   The write barrier for MVARs and TVARs
   -------------------------------------------------------------------------- */

void dirty_MVAR(StgRegTable *reg, StgClosure *p);
void dirty_TVAR(Capability *cap, StgTVar *p);

/* -----------------------------------------------------------------------------
   Nursery manipulation
   -------------------------------------------------------------------------- */

extern nursery *nurseries;
extern nat n_nurseries;

void     resetNurseries       ( void );
void     clearNursery         ( Capability *cap );
void     resizeNurseries      ( W_ blocks );
void     resizeNurseriesFixed ( void );
W_       countNurseryBlocks   ( void );
rtsBool  getNewNursery        ( Capability *cap );

/* -----------------------------------------------------------------------------
   Allocation accounting

   See [Note allocation accounting] in Storage.c
   -------------------------------------------------------------------------- */

//
// Called when we are finished allocating into a block; account for the amount
// allocated in cap->total_allocated.
//
INLINE_HEADER void finishedNurseryBlock (Capability *cap, bdescr *bd) {
    cap->total_allocated += bd->free - bd->start;
}

INLINE_HEADER void newNurseryBlock (bdescr *bd) {
    bd->free = bd->start;
}

void    updateNurseriesStats (void);
StgWord calcTotalAllocated   (void);

/* -----------------------------------------------------------------------------
   Stats 'n' DEBUG stuff
   -------------------------------------------------------------------------- */

W_    countLargeAllocated  (void);
W_    countOccupied        (bdescr *bd);
W_    calcNeeded           (rtsBool force_major, W_ *blocks_needed);

W_    gcThreadLiveWords  (nat i, nat g);
W_    gcThreadLiveBlocks (nat i, nat g);

W_    genLiveWords  (generation *gen);
W_    genLiveBlocks (generation *gen);

W_    calcLiveBlocks (void);
W_    calcLiveWords  (void);

/* ----------------------------------------------------------------------------
   Storage manager internal APIs and globals
   ------------------------------------------------------------------------- */

extern bdescr *exec_block;

#define END_OF_STATIC_LIST ((StgClosure*)1)

void move_STACK  (StgStack *src, StgStack *dest);

/* -----------------------------------------------------------------------------
   CAF lists

   dyn_caf_list  (CAFs chained through static_link)
      This is a chain of all CAFs in the program, used for
      dynamically-linked GHCi.
      See Note [dyn_caf_list].

   debug_caf_list  (CAFs chained through saved_info)
      A chain of all *live* CAFs in the program, that does not keep
      the CAFs alive.  Used for detecting when we enter a GC'd CAF,
      and to give diagnostics with +RTS -DG.

   revertible_caf_list  (CAFs chained through static_link)
      A chain of CAFs in object code loaded with the RTS linker.
      These CAFs can be reverted to their unevaluated state using
      revertCAFs.
 --------------------------------------------------------------------------- */

extern StgIndStatic * dyn_caf_list;
extern StgIndStatic * debug_caf_list;
extern StgIndStatic * revertible_caf_list;

#include "EndPrivate.h"

#endif /* SM_STORAGE_H */