Skip to content

Commit 4f68815

Browse files
committed
Add atomic reference counting for reflect objects.
1 parent 5494aa3 commit 4f68815

File tree

7 files changed

+141
-38
lines changed

7 files changed

+141
-38
lines changed

source/reflect/source/reflect_class.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#include <reflect/reflect_accessor.h>
2929

30+
#include <threading/threading_atomic_ref_count.h>
31+
3032
#include <reflect/reflect_memory_tracker.h>
3133

3234
#include <log/log.h>
@@ -40,7 +42,7 @@ struct class_type
4042
enum accessor_type_id accessor;
4143
class_impl impl;
4244
class_interface interface;
43-
size_t ref_count;
45+
struct threading_atomic_ref_count_type ref;
4446
vector constructors;
4547
map methods;
4648
map static_methods;
@@ -106,7 +108,7 @@ klass class_create(const char *name, enum accessor_type_id accessor, class_impl
106108

107109
cls->impl = impl;
108110
cls->accessor = accessor;
109-
cls->ref_count = 0;
111+
threading_atomic_ref_count_store(&cls->ref, 0);
110112
cls->interface = singleton ? singleton() : NULL;
111113
cls->constructors = vector_create_type(constructor);
112114
cls->methods = map_create(&hash_callback_str, &comparable_callback_str);
@@ -144,12 +146,11 @@ int class_increment_reference(klass cls)
144146
return 1;
145147
}
146148

147-
if (cls->ref_count == SIZE_MAX)
149+
if (threading_atomic_ref_count_increment(&cls->ref) == 1)
148150
{
149151
return 1;
150152
}
151153

152-
++cls->ref_count;
153154
reflect_memory_tracker_increment(class_stats);
154155

155156
return 0;
@@ -162,12 +163,11 @@ int class_decrement_reference(klass cls)
162163
return 1;
163164
}
164165

165-
if (cls->ref_count == 0)
166+
if (threading_atomic_ref_count_decrement(&cls->ref) == 1)
166167
{
167168
return 1;
168169
}
169170

170-
--cls->ref_count;
171171
reflect_memory_tracker_decrement(class_stats);
172172

173173
return 0;
@@ -843,7 +843,7 @@ void class_destroy(klass cls)
843843
log_write("metacall", LOG_LEVEL_ERROR, "Invalid reference counter in class: %s", cls->name ? cls->name : "<anonymous>");
844844
}
845845

846-
if (cls->ref_count == 0)
846+
if (threading_atomic_ref_count_load(&cls->ref) == 0)
847847
{
848848
if (cls->name == NULL)
849849
{

source/reflect/source/reflect_exception.c

+9-8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <reflect/reflect_exception.h>
2222

23+
#include <threading/threading_atomic_ref_count.h>
2324
#include <threading/threading_thread_id.h>
2425

2526
#include <reflect/reflect_memory_tracker.h>
@@ -36,7 +37,7 @@ struct exception_type
3637
int64_t code; /* Numeric code of error */
3738
char *stacktrace; /* Stack trace of the error */
3839
uint64_t id; /* Thread id where the error was raised */
39-
size_t ref_count;
40+
struct threading_atomic_ref_count_type ref;
4041
/* TODO: value attributes; // This should implement a map for representing the extra attributes of an exception */
4142
};
4243

@@ -56,7 +57,8 @@ exception exception_create(char *message, char *label, int64_t code, char *stack
5657
ex->code = code;
5758
ex->stacktrace = stacktrace;
5859
ex->id = thread_id_get_current();
59-
ex->ref_count = 0;
60+
61+
threading_atomic_ref_count_store(&ex->ref, 0);
6062

6163
reflect_memory_tracker_allocation(exception_stats);
6264

@@ -128,7 +130,8 @@ exception exception_create_const(const char *message, const char *label, int64_t
128130

129131
ex->code = code;
130132
ex->id = thread_id_get_current();
131-
ex->ref_count = 0;
133+
134+
threading_atomic_ref_count_store(&ex->ref, 0);
132135

133136
reflect_memory_tracker_allocation(exception_stats);
134137

@@ -151,12 +154,11 @@ int exception_increment_reference(exception ex)
151154
return 1;
152155
}
153156

154-
if (ex->ref_count == SIZE_MAX)
157+
if (threading_atomic_ref_count_increment(&ex->ref) == 1)
155158
{
156159
return 1;
157160
}
158161

159-
++ex->ref_count;
160162
reflect_memory_tracker_increment(exception_stats);
161163

162164
return 0;
@@ -169,12 +171,11 @@ int exception_decrement_reference(exception ex)
169171
return 1;
170172
}
171173

172-
if (ex->ref_count == 0)
174+
if (threading_atomic_ref_count_decrement(&ex->ref) == 1)
173175
{
174176
return 1;
175177
}
176178

177-
--ex->ref_count;
178179
reflect_memory_tracker_decrement(exception_stats);
179180

180181
return 0;
@@ -234,7 +235,7 @@ void exception_destroy(exception ex)
234235
log_write("metacall", LOG_LEVEL_ERROR, "Invalid reference counter in exception: %s", ex->label ? ex->label : "<anonymous>");
235236
}
236237

237-
if (ex->ref_count == 0)
238+
if (threading_atomic_ref_count_load(&ex->ref) == 0)
238239
{
239240
if (ex->message != NULL)
240241
{

source/reflect/source/reflect_function.c

+16-15
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <reflect/reflect_function.h>
2222
#include <reflect/reflect_value_type.h>
2323

24+
#include <threading/threading_atomic_ref_count.h>
25+
2426
#include <reflect/reflect_memory_tracker.h>
2527

2628
#include <log/log.h>
@@ -34,7 +36,7 @@ struct function_type
3436
signature s;
3537
function_impl impl;
3638
function_interface interface;
37-
size_t ref_count;
39+
struct threading_atomic_ref_count_type ref;
3840
enum async_id async;
3941
void *data;
4042
};
@@ -77,7 +79,6 @@ function function_create(const char *name, size_t args_count, function_impl impl
7779
}
7880

7981
func->impl = impl;
80-
func->ref_count = 0;
8182
func->async = SYNCHRONOUS;
8283
func->data = NULL;
8384

@@ -87,12 +88,11 @@ function function_create(const char *name, size_t args_count, function_impl impl
8788
{
8889
log_write("metacall", LOG_LEVEL_ERROR, "Invalid function signature allocation");
8990

90-
free(func->name);
91-
free(func);
92-
93-
return NULL;
91+
goto function_create_error;
9492
}
9593

94+
threading_atomic_ref_count_store(&func->ref, 0);
95+
9696
func->interface = singleton ? singleton() : NULL;
9797

9898
if (func->interface != NULL && func->interface->create != NULL)
@@ -101,16 +101,19 @@ function function_create(const char *name, size_t args_count, function_impl impl
101101
{
102102
log_write("metacall", LOG_LEVEL_ERROR, "Invalid function (%s) create callback <%p>", func->name, func->interface->create);
103103

104-
free(func->name);
105-
free(func);
106-
107-
return NULL;
104+
goto function_create_error;
108105
}
109106
}
110107

111108
reflect_memory_tracker_allocation(function_stats);
112109

113110
return func;
111+
112+
function_create_error:
113+
free(func->name);
114+
free(func);
115+
116+
return NULL;
114117
}
115118

116119
int function_increment_reference(function func)
@@ -120,12 +123,11 @@ int function_increment_reference(function func)
120123
return 1;
121124
}
122125

123-
if (func->ref_count == SIZE_MAX)
126+
if (threading_atomic_ref_count_increment(&func->ref) == 1)
124127
{
125128
return 1;
126129
}
127130

128-
++func->ref_count;
129131
reflect_memory_tracker_increment(function_stats);
130132

131133
return 0;
@@ -138,12 +140,11 @@ int function_decrement_reference(function func)
138140
return 1;
139141
}
140142

141-
if (func->ref_count == 0)
143+
if (threading_atomic_ref_count_decrement(&func->ref) == 1)
142144
{
143145
return 1;
144146
}
145147

146-
--func->ref_count;
147148
reflect_memory_tracker_decrement(function_stats);
148149

149150
return 0;
@@ -639,7 +640,7 @@ void function_destroy(function func)
639640
log_write("metacall", LOG_LEVEL_ERROR, "Invalid reference counter in function: %s", func->name ? func->name : "<anonymous>");
640641
}
641642

642-
if (func->ref_count == 0)
643+
if (threading_atomic_ref_count_load(&func->ref) == 0)
643644
{
644645
if (func->name == NULL)
645646
{

source/reflect/source/reflect_object.c

+8-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#include <reflect/reflect_memory_tracker.h>
2929

30+
#include <threading/threading_atomic_ref_count.h>
31+
3032
#include <log/log.h>
3133

3234
#include <stdlib.h>
@@ -38,7 +40,7 @@ struct object_type
3840
enum accessor_type_id accessor;
3941
object_impl impl;
4042
object_interface interface;
41-
size_t ref_count;
43+
struct threading_atomic_ref_count_type ref;
4244
klass cls;
4345
};
4446

@@ -79,7 +81,8 @@ object object_create(const char *name, enum accessor_type_id accessor, object_im
7981

8082
obj->impl = impl;
8183
obj->accessor = accessor;
82-
obj->ref_count = 0;
84+
threading_atomic_ref_count_store(&obj->ref, 0);
85+
8386
obj->interface = singleton ? singleton() : NULL;
8487

8588
obj->cls = cls;
@@ -109,12 +112,11 @@ int object_increment_reference(object obj)
109112
return 1;
110113
}
111114

112-
if (obj->ref_count == SIZE_MAX)
115+
if (threading_atomic_ref_count_increment(&obj->ref) == 1)
113116
{
114117
return 1;
115118
}
116119

117-
++obj->ref_count;
118120
reflect_memory_tracker_increment(object_stats);
119121

120122
return 0;
@@ -127,12 +129,11 @@ int object_decrement_reference(object obj)
127129
return 1;
128130
}
129131

130-
if (obj->ref_count == 0)
132+
if (threading_atomic_ref_count_decrement(&obj->ref) == 1)
131133
{
132134
return 1;
133135
}
134136

135-
--obj->ref_count;
136137
reflect_memory_tracker_decrement(object_stats);
137138

138139
return 0;
@@ -393,7 +394,7 @@ void object_destroy(object obj)
393394
log_write("metacall", LOG_LEVEL_ERROR, "Invalid reference counter in object: %s", obj->name ? obj->name : "<anonymous>");
394395
}
395396

396-
if (obj->ref_count == 0)
397+
if (threading_atomic_ref_count_load(&obj->ref) == 0)
397398
{
398399
if (obj->name == NULL)
399400
{

source/threading/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ set(headers
3737
${include_path}/threading.h
3838
${include_path}/threading_atomic.h
3939
${include_path}/threading_thread_id.h
40+
${include_path}/threading_atomic_ref_count.h
4041
)
4142

4243
set(sources

0 commit comments

Comments
 (0)