OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2007 Chris Wilson | 2 * Copyright © 2007 Chris Wilson |
3 * Copyright © 2009,2010 Red Hat, Inc. | 3 * Copyright © 2009,2010 Red Hat, Inc. |
4 * Copyright © 2011 Google, Inc. | 4 * Copyright © 2011 Google, Inc. |
5 * | 5 * |
6 * This is part of HarfBuzz, a text shaping library. | 6 * This is part of HarfBuzz, a text shaping library. |
7 * | 7 * |
8 * Permission is hereby granted, without written agreement and without | 8 * Permission is hereby granted, without written agreement and without |
9 * license or royalty fees, to use, copy, modify, and distribute this | 9 * license or royalty fees, to use, copy, modify, and distribute this |
10 * software and its documentation for any purpose, provided that the | 10 * software and its documentation for any purpose, provided that the |
(...skipping 16 matching lines...) Expand all Loading... |
27 * Chris Wilson <chris@chris-wilson.co.uk> | 27 * Chris Wilson <chris@chris-wilson.co.uk> |
28 * Red Hat Author(s): Behdad Esfahbod | 28 * Red Hat Author(s): Behdad Esfahbod |
29 * Google Author(s): Behdad Esfahbod | 29 * Google Author(s): Behdad Esfahbod |
30 */ | 30 */ |
31 | 31 |
32 #ifndef HB_OBJECT_PRIVATE_HH | 32 #ifndef HB_OBJECT_PRIVATE_HH |
33 #define HB_OBJECT_PRIVATE_HH | 33 #define HB_OBJECT_PRIVATE_HH |
34 | 34 |
35 #include "hb-private.hh" | 35 #include "hb-private.hh" |
36 | 36 |
| 37 #include "hb-atomic-private.hh" |
37 #include "hb-mutex-private.hh" | 38 #include "hb-mutex-private.hh" |
38 | 39 |
39 | 40 |
40 | |
41 /* Debug */ | 41 /* Debug */ |
42 | 42 |
43 #ifndef HB_DEBUG_OBJECT | 43 #ifndef HB_DEBUG_OBJECT |
44 #define HB_DEBUG_OBJECT (HB_DEBUG+0) | 44 #define HB_DEBUG_OBJECT (HB_DEBUG+0) |
45 #endif | 45 #endif |
46 | 46 |
47 | 47 |
48 /* atomic_int */ | |
49 | |
50 /* We need external help for these */ | |
51 | |
52 #ifdef HAVE_GLIB | |
53 | |
54 #include <glib.h> | |
55 | |
56 typedef volatile int hb_atomic_int_t; | |
57 #if GLIB_CHECK_VERSION(2,29,5) | |
58 #define hb_atomic_int_add(AI, V) g_atomic_int_add (&(AI), V) | |
59 #else | |
60 #define hb_atomic_int_add(AI, V) g_atomic_int_exchange_and_add (&(AI), V) | |
61 #endif | |
62 #define hb_atomic_int_get(AI) g_atomic_int_get (&(AI)) | |
63 #define hb_atomic_int_set(AI, V) g_atomic_int_set (&(AI), V) | |
64 | |
65 | |
66 #elif defined(_MSC_VER) && _MSC_VER >= 1600 | |
67 | |
68 #include <intrin.h> | |
69 | |
70 typedef long hb_atomic_int_t; | |
71 #define hb_atomic_int_add(AI, V) _InterlockedExchangeAdd (&(AI), V) | |
72 #define hb_atomic_int_get(AI) (_ReadBarrier (), (AI)) | |
73 #define hb_atomic_int_set(AI, V) ((void) _InterlockedExchange (&(AI), (V)
)) | |
74 | |
75 | |
76 #else | |
77 | |
78 #ifdef _MSC_VER | |
79 #pragma message("Could not find any system to define atomic_int macros, library
will NOT be thread-safe") | |
80 #else | |
81 #warning "Could not find any system to define atomic_int macros, library will NO
T be thread-safe" | |
82 #endif | |
83 | |
84 typedef volatile int hb_atomic_int_t; | |
85 #define hb_atomic_int_add(AI, V) ((AI) += (V), (AI) - (V)) | |
86 #define hb_atomic_int_get(AI) (AI) | |
87 #define hb_atomic_int_set(AI, V) ((void) ((AI) = (V))) | |
88 | |
89 | |
90 #endif | |
91 | |
92 | |
93 | |
94 | |
95 /* reference_count */ | 48 /* reference_count */ |
96 | 49 |
97 typedef struct { | 50 struct hb_reference_count_t |
| 51 { |
98 hb_atomic_int_t ref_count; | 52 hb_atomic_int_t ref_count; |
99 | 53 |
100 #define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) | 54 #define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) |
101 #define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} | 55 #define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} |
102 | 56 |
103 inline void init (int v) { ref_count = v; /* non-atomic is fine */ } | 57 inline void init (int v) { const_cast<hb_atomic_int_t &> (ref_count) = v; } |
104 inline int inc (void) { return hb_atomic_int_add (ref_count, 1); } | 58 inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &
> (ref_count), 1); } |
105 inline int dec (void) { return hb_atomic_int_add (ref_count, -1); } | 59 inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &
> (ref_count), -1); } |
106 inline void set (int v) { hb_atomic_int_set (ref_count, v); } | |
107 | 60 |
108 inline int get (void) const { return hb_atomic_int_get (ref_count); } | 61 inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_I
NVALID_VALUE; } |
109 inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVA
LID_VALUE; } | |
110 | 62 |
111 } hb_reference_count_t; | 63 }; |
112 | 64 |
113 | 65 |
114 /* user_data */ | 66 /* user_data */ |
115 | 67 |
116 struct hb_user_data_array_t { | 68 struct hb_user_data_array_t |
117 | 69 { |
118 struct hb_user_data_item_t { | 70 struct hb_user_data_item_t { |
119 hb_user_data_key_t *key; | 71 hb_user_data_key_t *key; |
120 void *data; | 72 void *data; |
121 hb_destroy_func_t destroy; | 73 hb_destroy_func_t destroy; |
122 | 74 |
123 inline bool operator == (hb_user_data_key_t *other_key) const { return key =
= other_key; } | 75 inline bool operator == (hb_user_data_key_t *other_key) const { return key =
= other_key; } |
124 inline bool operator == (hb_user_data_item_t &other) const { return key == o
ther.key; } | 76 inline bool operator == (hb_user_data_item_t &other) const { return key == o
ther.key; } |
125 | 77 |
126 void finish (void) { if (destroy) destroy (data); } | 78 void finish (void) { if (destroy) destroy (data); } |
127 }; | 79 }; |
128 | 80 |
129 hb_lockable_set_t<hb_user_data_item_t, hb_static_mutex_t> items; | 81 hb_lockable_set_t<hb_user_data_item_t, hb_static_mutex_t> items; |
130 | 82 |
131 HB_INTERNAL bool set (hb_user_data_key_t *key, | 83 HB_INTERNAL bool set (hb_user_data_key_t *key, |
132 void * data, | 84 void * data, |
133 hb_destroy_func_t destroy, | 85 hb_destroy_func_t destroy, |
134 hb_bool_t replace); | 86 hb_bool_t replace); |
135 | 87 |
136 HB_INTERNAL void *get (hb_user_data_key_t *key); | 88 HB_INTERNAL void *get (hb_user_data_key_t *key); |
137 | 89 |
138 HB_INTERNAL void finish (void); | 90 HB_INTERNAL void finish (void); |
139 }; | 91 }; |
140 | 92 |
141 | 93 |
142 /* object_header */ | 94 /* object_header */ |
143 | 95 |
144 typedef struct _hb_object_header_t hb_object_header_t; | 96 struct hb_object_header_t |
145 | 97 { |
146 struct _hb_object_header_t { | |
147 hb_reference_count_t ref_count; | 98 hb_reference_count_t ref_count; |
148 hb_user_data_array_t user_data; | 99 hb_user_data_array_t user_data; |
149 | 100 |
150 #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID} | 101 #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID} |
151 | 102 |
152 static inline void *create (unsigned int size) { | 103 static inline void *create (unsigned int size) { |
153 hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size); | 104 hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size); |
154 | 105 |
155 if (likely (obj)) | 106 if (likely (obj)) |
156 obj->init (); | 107 obj->init (); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 return false; | 144 return false; |
194 | 145 |
195 return user_data.set (key, data, destroy_func, replace); | 146 return user_data.set (key, data, destroy_func, replace); |
196 } | 147 } |
197 | 148 |
198 inline void *get_user_data (hb_user_data_key_t *key) { | 149 inline void *get_user_data (hb_user_data_key_t *key) { |
199 return user_data.get (key); | 150 return user_data.get (key); |
200 } | 151 } |
201 | 152 |
202 inline void trace (const char *function) const { | 153 inline void trace (const char *function) const { |
| 154 if (unlikely (!this)) return; |
| 155 /* XXX We cannot use DEBUG_MSG_FUNC here since that one currecntly only |
| 156 * prints the class name and throws away the template info. */ |
203 DEBUG_MSG (OBJECT, (void *) this, | 157 DEBUG_MSG (OBJECT, (void *) this, |
204 » "refcount=%d %s", | 158 » "%s refcount=%d", |
205 » this ? ref_count.get () : 0, | 159 » function, |
206 » function); | 160 » this ? ref_count.ref_count : 0); |
207 } | 161 } |
208 | 162 |
209 }; | 163 }; |
210 | 164 |
211 | 165 |
212 | |
213 | |
214 /* object */ | 166 /* object */ |
215 | 167 |
216 template <typename Type> | 168 template <typename Type> |
217 static inline void hb_object_trace (const Type *obj, const char *function) | 169 static inline void hb_object_trace (const Type *obj, const char *function) |
218 { | 170 { |
219 obj->header.trace (function); | 171 obj->header.trace (function); |
220 } | 172 } |
221 template <typename Type> | 173 template <typename Type> |
222 static inline Type *hb_object_create (void) | 174 static inline Type *hb_object_create (void) |
223 { | 175 { |
(...skipping 30 matching lines...) Expand all Loading... |
254 } | 206 } |
255 | 207 |
256 template <typename Type> | 208 template <typename Type> |
257 static inline void *hb_object_get_user_data (Type *obj, | 209 static inline void *hb_object_get_user_data (Type *obj, |
258 hb_user_data_key_t *key) | 210 hb_user_data_key_t *key) |
259 { | 211 { |
260 return obj->header.get_user_data (key); | 212 return obj->header.get_user_data (key); |
261 } | 213 } |
262 | 214 |
263 | 215 |
264 | |
265 | |
266 | |
267 #endif /* HB_OBJECT_PRIVATE_HH */ | 216 #endif /* HB_OBJECT_PRIVATE_HH */ |
OLD | NEW |