1 /* ----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team 1998-2008
4 *
5 * Generational garbage collector: utilities
6 *
7 * Documentation on the architecture of the Garbage Collector can be
8 * found in the online commentary:
9 *
10 * https://gitlab.haskell.org/ghc/ghc/wikis/commentary/rts/storage/gc
11 *
12 * --------------------------------------------------------------------------*/
13
14 #pragma once
15
16 #include "BeginPrivate.h"
17
18 #include "GCTDecl.h"
19
20 bdescr* allocGroup_sync(uint32_t n);
21 bdescr* allocGroupOnNode_sync(uint32_t node, uint32_t n);
22
allocBlock_sync(void)23 INLINE_HEADER bdescr *allocBlock_sync(void)
24 {
25 return allocGroup_sync(1);
26 }
27
allocBlockOnNode_sync(uint32_t node)28 INLINE_HEADER bdescr *allocBlockOnNode_sync(uint32_t node)
29 {
30 return allocGroupOnNode_sync(node,1);
31 }
32
33 void freeChain_sync(bdescr *bd);
34 void freeGroup_sync(bdescr *bd);
35
36 void push_scanned_block (bdescr *bd, gen_workspace *ws);
37 StgPtr todo_block_full (uint32_t size, gen_workspace *ws);
38 StgPtr alloc_todo_block (gen_workspace *ws, uint32_t size);
39
40 bdescr *grab_local_todo_block (gen_workspace *ws);
41 #if defined(THREADED_RTS)
42 bdescr *steal_todo_block (uint32_t s);
43 #endif
44
45 // Returns true if a block is partially full. This predicate is used to try
46 // to re-use partial blocks wherever possible, and to reduce wastage.
47 // We might need to tweak the actual value.
48 INLINE_HEADER bool
isPartiallyFull(bdescr * bd)49 isPartiallyFull(bdescr *bd)
50 {
51 return (bd->free + WORK_UNIT_WORDS < bd->start + BLOCK_SIZE_W);
52 }
53
54 // Version of recordMutableGen for use during GC. This uses the
55 // mutable lists attached to the current gc_thread structure, which
56 // are the same as the mutable lists on the Capability.
57 INLINE_HEADER void
recordMutableGen_GC(StgClosure * p,uint32_t gen_no)58 recordMutableGen_GC (StgClosure *p, uint32_t gen_no)
59 {
60 bdescr *bd;
61
62 bd = gct->mut_lists[gen_no];
63 if (bd->free >= bd->start + BLOCK_SIZE_W) {
64 bdescr *new_bd;
65 new_bd = allocBlock_sync();
66 new_bd->link = bd;
67 bd = new_bd;
68 gct->mut_lists[gen_no] = bd;
69 }
70 *bd->free++ = (StgWord) p;
71 // N.B. we are allocating into our Capability-local mut_list, therefore
72 // we don't need an atomic increment.
73 }
74
75 #include "EndPrivate.h"
76