File: meta_alloc.h

package info (click to toggle)
freecell-solver 5.0.0-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,256 kB
  • sloc: ansic: 28,700; perl: 10,050; xml: 5,600; python: 1,339; sh: 533; cpp: 275; makefile: 20; javascript: 8
file content (105 lines) | stat: -rw-r--r-- 2,799 bytes parent folder | download | duplicates (4)
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
/*
 * This file is part of Freecell Solver. It is subject to the license terms in
 * the COPYING.txt file found in the top-level directory of this distribution
 * and at http://fc-solve.shlomifish.org/docs/distro/COPYING.html . No part of
 * Freecell Solver, including this file, may be copied, modified, propagated,
 * or distributed except according to the terms contained in the COPYING file.
 *
 * Copyright (c) 2000 Shlomi Fish
 */
/*
 * meta_alloc.h - the Freecell Solver compact allocator based on the
 * meta-allocator concept that is used to collect the pages allocated by
 * the standard allocator after it is destroyed and to recycle them.
 *
 * Also see alloc.h.
 */
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include "state.h"

typedef struct
{
    char *recycle_bin;
} meta_allocator;

typedef struct
{
    char *old_list;
    char *max_ptr;
    char *ptr;
    char *rollback_ptr;
    meta_allocator *meta;
} compact_allocator;

extern void fc_solve_compact_allocator_extend(compact_allocator *);

/* To be called after the meta_alloc was set. */
static inline void fc_solve_compact_allocator_init_helper(
    compact_allocator *const allocator)
{
    allocator->old_list = NULL;
    fc_solve_compact_allocator_extend(allocator);
}

static inline void fc_solve_meta_compact_allocator_init(
    meta_allocator *const meta)
{
    meta->recycle_bin = NULL;
}

extern void fc_solve_meta_compact_allocator_finish(meta_allocator *);

extern void fc_solve_compact_allocator_init(
    compact_allocator *, meta_allocator *);

static inline void *fcs_compact_alloc_ptr(
    compact_allocator *const allocator, const size_t how_much_proto)
{
    /* Round ptr to the next pointer boundary */
    const size_t how_much =
        how_much_proto +
        ((sizeof(char *) - ((how_much_proto) & (sizeof(char *) - 1))) &
            (sizeof(char *) - 1));

    if ((size_t)(allocator->max_ptr - allocator->ptr) < how_much)
    {
        fc_solve_compact_allocator_extend(allocator);
    }
    else
    {
        allocator->rollback_ptr = allocator->ptr;
    }
    allocator->ptr += how_much;

    return allocator->rollback_ptr;
}

static inline void fcs_compact_alloc_release(compact_allocator *const allocator)
{
    allocator->ptr = allocator->rollback_ptr;
}

extern void fc_solve_compact_allocator_finish(compact_allocator *);

static inline fcs_collectible_state *fcs_state_ia_alloc_into_var(
    compact_allocator *const allocator)
{
    return (fcs_collectible_state *)fcs_compact_alloc_ptr(
        allocator, sizeof(fcs_collectible_state));
}

static inline void fc_solve_compact_allocator_recycle(
    compact_allocator *const allocator)
{
    fc_solve_compact_allocator_finish(allocator);
    fc_solve_compact_allocator_init_helper(allocator);
}

#ifdef __cplusplus
};
#endif