Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / gc-core.h
1 /** @file
2  * @brief Wrapper for Boehm GC
3  */
4 /* Authors:
5  *   MenTaLguY <mental@rydia.net>
6  *
7  * Copyright (C) 2004 MenTaLguY
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #ifndef SEEN_INKSCAPE_GC_CORE_H
13 #define SEEN_INKSCAPE_GC_CORE_H
15 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
19 #include <new>
20 #include <cstdlib>
21 #include <cstddef>
22 #ifdef HAVE_GC_GC_H
23 # include <gc/gc.h>
24 #else
25 # include <gc.h>
26 #endif
27 #include <glib/gmain.h>
29 namespace Inkscape {
30 namespace GC {
32 enum ScanPolicy {
33     SCANNED,
34     ATOMIC
35 };
37 enum CollectionPolicy {
38     AUTO,
39     MANUAL
40 };
42 enum Delete {
43     GC
44 };
46 typedef void (*CleanupFunc)(void *mem, void *data);
48 struct Ops {
49     void (*do_init)();
50     void *(*malloc)(std::size_t size);
51     void *(*malloc_atomic)(std::size_t size);
52     void *(*malloc_uncollectable)(std::size_t size);
53     void *(*malloc_atomic_uncollectable)(std::size_t size);
54     void *(*base)(void *ptr);
55     void (*register_finalizer_ignore_self)(void *base,
56                                            CleanupFunc func, void *data,
57                                            CleanupFunc *old_func,
58                                            void **old_data);
59     int (*general_register_disappearing_link)(void **p_ptr,
60                                               void *base);
61     int (*unregister_disappearing_link)(void **p_ptr);
62     std::size_t (*get_heap_size)();
63     std::size_t (*get_free_bytes)();
64     void (*gcollect)();
65     void (*enable)();
66     void (*disable)();
67     void (*free)(void *ptr);
68 };
70 struct Core {
71 public:
72     static void init();
73     static inline void *malloc(std::size_t size) {
74         return _ops.malloc(size);
75     }
76     static inline void *malloc_atomic(std::size_t size) {
77         return _ops.malloc_atomic(size);
78     }
79     static inline void *malloc_uncollectable(std::size_t size) {
80         return _ops.malloc_uncollectable(size);
81     }
82     static inline void *malloc_atomic_uncollectable(std::size_t size) {
83         return _ops.malloc_atomic_uncollectable(size);
84     }
85     static inline void *base(void *ptr) {
86         return _ops.base(ptr);
87     }
88     static inline void register_finalizer_ignore_self(void *base,
89                                                       CleanupFunc func,
90                                                       void *data,
91                                                       CleanupFunc *old_func,
92                                                       void **old_data)
93     {
94         return _ops.register_finalizer_ignore_self(base, func, data,
95                                                    old_func, old_data);
96     }
97     static inline int general_register_disappearing_link(void **p_ptr,
98                                                          void *base)
99     {
100         return _ops.general_register_disappearing_link(p_ptr, base);
101     }
102     static inline int unregister_disappearing_link(void **p_ptr) {
103         return _ops.unregister_disappearing_link(p_ptr);
104     }
105     static inline std::size_t get_heap_size() {
106         return _ops.get_heap_size();
107     }
108     static inline std::size_t get_free_bytes() {
109         return _ops.get_free_bytes();
110     }
111     static inline void gcollect() {
112         _ops.gcollect();
113     }
114     static inline void enable() {
115         _ops.enable();
116     }
117     static inline void disable() {
118         _ops.disable();
119     }
120     static inline void free(void *ptr) {
121         return _ops.free(ptr);
122     }
123 private:
124     static Ops _ops;
125 };
127 inline void init() {
128     Core::init();
131 void request_early_collection();
136 inline void *operator new(std::size_t size,
137                           Inkscape::GC::ScanPolicy scan,
138                           Inkscape::GC::CollectionPolicy collect,
139                           Inkscape::GC::CleanupFunc cleanup=NULL,
140                           void *data=NULL)
141 throw(std::bad_alloc)
143     using namespace Inkscape::GC;
145     void *mem;
146     if ( collect == AUTO ) {
147         if ( scan == SCANNED ) {
148             mem = Core::malloc(size);
149         } else {
150             mem = Core::malloc_atomic(size);
151         }
152     } else {
153         if ( scan == SCANNED ) {
154             mem = Core::malloc_uncollectable(size);
155         } else {
156             mem = Core::malloc_atomic_uncollectable(size);
157         }
158     }
159     if (!mem) {
160         throw std::bad_alloc();
161     }
162     if (cleanup) {
163         Core::register_finalizer_ignore_self(mem, cleanup, data, NULL, NULL);
164     }
165     return mem;
168 inline void *operator new(std::size_t size,
169                           Inkscape::GC::ScanPolicy scan,
170                           Inkscape::GC::CleanupFunc cleanup=NULL,
171                           void *data=NULL)
172 throw(std::bad_alloc)
174     return operator new(size, scan, Inkscape::GC::AUTO, cleanup, data);
177 inline void *operator new[](std::size_t size,
178                             Inkscape::GC::ScanPolicy scan,
179                             Inkscape::GC::CollectionPolicy collect,
180                             Inkscape::GC::CleanupFunc cleanup=NULL,
181                             void *data=NULL)
182 throw(std::bad_alloc)
184     return operator new(size, scan, collect, cleanup, data);
187 inline void *operator new[](std::size_t size,
188                             Inkscape::GC::ScanPolicy scan,
189                             Inkscape::GC::CleanupFunc cleanup=NULL,
190                             void *data=NULL)
191 throw(std::bad_alloc)
193     return operator new[](size, scan, Inkscape::GC::AUTO, cleanup, data);
196 inline void operator delete(void *mem, Inkscape::GC::Delete) {
197     Inkscape::GC::Core::free(mem);
200 inline void operator delete[](void *mem, Inkscape::GC::Delete) {
201     operator delete(mem, Inkscape::GC::GC);
204 #endif
205 /*
206   Local Variables:
207   mode:c++
208   c-file-style:"stroustrup"
209   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
210   indent-tabs-mode:nil
211   fill-column:99
212   End:
213 */
214 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :