Arax -8d09c51940345c86062e8ef2427c705ae66e5926
A Runtime Framework for Decoupling Applications from Heterogeneous Accelerators
Loading...
Searching...
No Matches
arax_object.c
Go to the documentation of this file.
1#include "arax_object.h"
2#include "arax_pipe.h"
3#include "arax_accel.h"
4#include "arax_proc.h"
5#include "arax_task.h"
6#include "arax_data.h"
7#include <stdio.h>
8#include <string.h>
9#include <stdarg.h>
10
11static const char *type2str[ARAX_TYPE_COUNT] = {
12 "Phys.Accel",// "Physical Accelerators",
13 "Virt.Accel",// "Virtual Accelerators",
14 "Procedures",
15 "Arax--Data",
16 "Arax-Tasks",
17};
18
26
27#ifdef ARAX_REF_DEBUG // if(OBJ->type==1)(specify which type of object debug)
28#define PRINT_REFS(OBJ, DELTA) \
29 ({ \
30 if ( (1 << (OBJ->type)) & ARAX_REF_DEBUG_MASK) \
31 printf("%s:%s(%p,ABA:%d ,%d=>%d)\n", \
32 __func__, type2str[OBJ->type], \
33 OBJ, ((OBJ->ref_count & 0xffff0000) >> 16), \
34 (OBJ->ref_count & 0xffff), \
35 ((OBJ->ref_count & 0xffff) DELTA) & 0xffff); \
36 })
37#else
38#define PRINT_REFS(OBJ, DELTA)
39// without bitmask print
40// #define PRINT_REFS(OBJ,DELTA)({ if(OBJ->type==3) printf("%s(%p(%s),%d=>%d)//\n",__func__,OBJ,type2str[OBJ->type],(OBJ->ref_count), (OBJ->ref_count DELTA)) ; } )
41#endif /* ifdef ARAX_REF_DEBUG */
42
43typedef void (*arax_object_dtor)(arax_pipe_s *pipe, arax_object_s *obj);
44
50
51
59
61{
62 int r;
63
64 repo->pipe = pipe;
65 for (r = 0; r < ARAX_TYPE_COUNT; r++) {
66 utils_list_init(&repo->repo[r].list);
67 utils_spinlock_init(&repo->repo[r].lock);
68 }
69}
70
72{
73 int r;
74 int len;
75 int failed = 0;
76
77 for (r = 0; r < ARAX_TYPE_COUNT; r++) {
78 len = repo->repo[r].list.length;
79 failed += len;
80 if (len) {
81 fprintf(stderr, "%lu %*s still registered!\n",
82 repo->repo[r].list.length,
83 (int) ( strlen(type2str[r]) - (len == 1) ),
84 type2str[r]);
85 }
86 }
87 return failed;
88}
89
91{
92 if (type < ARAX_TYPE_COUNT)
93 return type2str[type];
94
95 return 0;
96}
97
99 arax_object_type_e type, const char *name, size_t size, const int ref_count)
100{
101 arax_object_s *obj;
102
103 arax_pipe_size_dec(repo->pipe, size);
104 obj = arch_alloc_allocate(&(repo->pipe->allocator), size);
105
106 if (!obj) // GCOV_EXCL_LINE
107 return 0; // GCOV_EXCL_LINE
108
109 obj->name = arch_alloc_allocate(&(repo->pipe->allocator), strlen(name) + 1);
110 strcpy(obj->name, name);
111 obj->repo = repo;
112 obj->alloc_size = size;
113 obj->type = type;
114 obj->ref_count = ref_count;
115 utils_list_node_init(&(obj->list), obj);
116 utils_spinlock_lock(&(repo->repo[type].lock) );
117 utils_list_add(&(repo->repo[type].list), &(obj->list) );
118 utils_spinlock_unlock(&(repo->repo[type].lock) );
119
120 if (sizeof(union arax_object_union) >= size)
121 memset(obj + 1, 0, size - sizeof(arax_object_s));
122 else
123 memset(obj + 1, 0, sizeof(union arax_object_union) - sizeof(arax_object_s));
124
125 return obj;
126}
127
128void arax_object_rename(arax_object_s *obj, const char *fmt, ...)
129{
130 va_list args;
131
132 va_start(args, fmt);
133 char tmp;
134 size_t new_size = vsnprintf(&tmp, 1, fmt, args);
135 size_t old_size = strlen(obj->name);
136
137 if (old_size < new_size) {
138 arch_alloc_free(&(obj->repo->pipe->allocator), obj->name);
139 obj->name = arch_alloc_allocate(&(obj->repo->pipe->allocator), new_size + 1);
140 }
141 vsprintf(obj->name, fmt, args);
142 va_end(args);
143}
144
146{
147 arax_assert(obj);
149
150 #ifdef ARAX_REF_DEBUG
151 PRINT_REFS(obj, +0x10001);
152 arax_assert( (obj->ref_count & 0xffff ) >= 0);
153 __sync_add_and_fetch(&(obj->ref_count), 0x10001);
154 #else
155 PRINT_REFS(obj, +1);
156 arax_assert(obj->ref_count >= 0);
157 __sync_add_and_fetch(&(obj->ref_count), 1);
158 #endif
159}
160
162{
163 arax_object_repo_s *repo;
164
165 arax_assert(obj);
167
168 repo = obj->repo;
169 #ifdef ARAX_REF_DEBUG
170 PRINT_REFS(obj, +0xffff);
171 arax_assert( (obj->ref_count & 0xffff ) > 0);
172 #else
173 PRINT_REFS(obj, -1);
174 arax_assert(obj->ref_count > 0);
175 #endif
176
177 utils_spinlock_lock(&(repo->repo[obj->type].lock) );
178
179 #ifdef ARAX_REF_DEBUG
180 int refs = __sync_add_and_fetch(&(obj->ref_count), 0xffff) & 0xffff;
181 #else
182 int refs = __sync_add_and_fetch(&(obj->ref_count), -1);
183 #endif
184 if (!refs) { // Seems to be no longer in use, must free it
185 #ifdef ARAX_REF_DEBUG
186 if (refs == (obj->ref_count & 0xffff ))
187 #else
188 if (refs == obj->ref_count)
189 #endif
190 { // Ensure nobody changed the ref count
191 utils_list_del(&(repo->repo[obj->type].list), &(obj->list) ); // remove it from repo
192 }
193 utils_spinlock_unlock(&(repo->repo[obj->type].lock) );
194
195 dtor_table[obj->type](repo->pipe, obj);
196
197 size_t size = obj->alloc_size;
198
199 arch_alloc_free(&(repo->pipe->allocator), obj->name);
200
201 arch_alloc_free(&(repo->pipe->allocator), obj);
202
203 arax_pipe_size_inc(repo->pipe, size);
204 } else {
205 utils_spinlock_unlock(&(repo->repo[obj->type].lock) );
206 }
207
208 return refs;
209} /* arax_object_ref_dec */
210
212{
213 #ifdef ARAX_REF_DEBUG
214 int refs = __sync_add_and_fetch(&(obj->ref_count), 0xffff) & 0xffff;
215 #else
216 int refs = __sync_add_and_fetch(&(obj->ref_count), -1);
217 #endif
218 if (!refs) { // Seems to be no longer in use, must free it
219 arax_object_repo_s *repo = obj->repo;
220 utils_list_del(&(repo->repo[obj->type].list), &(obj->list) ); // remove it from repo
221 dtor_table[obj->type](repo->pipe, obj);
222
223 size_t size = obj->alloc_size;
224
225 arch_alloc_free(&(repo->pipe->allocator), obj->name);
226
227 arch_alloc_free(&(repo->pipe->allocator), obj);
228
229 arax_pipe_size_inc(repo->pipe, size);
230 }
231
232 arax_assert(refs >= 0);
233
234 return refs;
235}
236
238{
239 #ifdef ARAX_REF_DEBUG
240 return (obj->ref_count & 0xffff);
241
242 #else
243 return obj->ref_count;
244
245 #endif
246}
247
250{
251 utils_spinlock_lock(&(repo->repo[type].lock) );
252 return &(repo->repo[type].list);
253}
254
struct arax_pipe arax_pipe_s
#define arch_alloc_free(ALLOC, MEM)
Definition alloc.h:70
void * arch_alloc_allocate(arch_alloc_s *alloc, size_t size)
#define arax_assert(EXPR)
Definition arax_assert.h:7
enum arax_object_type arax_object_type_e
@ ARAX_TYPE_COUNT
Definition arax_object.h:21
#define ARAX_OBJ_DTOR_USE(TYPE)
#define ARAX_OBJ_DTOR_DECL(TYPE)
struct arax_task_msg arax_task_msg_s
int arax_object_ref_dec_pre_locked(arax_object_s *obj)
static const arax_object_dtor dtor_table[ARAX_TYPE_COUNT]
Definition arax_object.c:52
int arax_object_repo_exit(arax_object_repo_s *repo)
Definition arax_object.c:71
arax_object_s * arax_object_register(arax_object_repo_s *repo, arax_object_type_e type, const char *name, size_t size, const int ref_count)
Definition arax_object.c:98
const char * arax_object_type_to_str(arax_object_type_e type)
Definition arax_object.c:90
void arax_object_rename(arax_object_s *obj, const char *fmt,...)
int arax_object_refs(arax_object_s *obj)
static const char * type2str[ARAX_TYPE_COUNT]
Definition arax_object.c:11
void arax_object_repo_init(arax_object_repo_s *repo, arax_pipe_s *pipe)
Definition arax_object.c:60
void arax_object_ref_inc(arax_object_s *obj)
utils_list_s * arax_object_list_lock(arax_object_repo_s *repo, arax_object_type_e type)
void arax_object_list_unlock(arax_object_repo_s *repo, arax_object_type_e type)
void(* arax_object_dtor)(arax_pipe_s *pipe, arax_object_s *obj)
Definition arax_object.c:43
int arax_object_ref_dec(arax_object_s *obj)
#define PRINT_REFS(OBJ, DELTA)
Definition arax_object.c:38
void ARAX_PIPE_THOTTLE_DEBUG_FUNC arax_pipe_size_dec(arax_pipe_s *pipe, size_t sz ARAX_PIPE_THOTTLE_DEBUG_PARAMS)
Definition arax_pipe.c:259
void ARAX_PIPE_THOTTLE_DEBUG_FUNC arax_pipe_size_inc(arax_pipe_s *pipe, size_t sz ARAX_PIPE_THOTTLE_DEBUG_PARAMS)
Definition arax_pipe.c:253
utils_list_node_s * utils_list_del(utils_list_s *list, utils_list_node_s *node)
Definition list.c:26
void utils_list_node_init(utils_list_node_s *node, void *owner)
Definition list.c:74
utils_list_s * utils_list_init(void *mem)
Definition list.c:3
void utils_list_add(utils_list_s *list, utils_list_node_s *node)
Definition list.c:20
#define utils_spinlock_lock(V)
Definition queue.c:35
#define utils_spinlock_init(V)
Definition queue.c:34
#define utils_spinlock_unlock(V)
Definition queue.c:36
arax_vaccel_s vaccel
Definition arax_object.c:21
arax_proc_s proc
Definition arax_object.c:22
arax_task_msg_s task
Definition arax_object.c:23
arax_accel_s accel
Definition arax_object.c:20
arax_data_s data
Definition arax_object.c:24
utils_spinlock lock
Definition arax_object.h:33
struct arax_object_repo_s::@001144062210171162324314250161237076324015155136 repo[ARAX_TYPE_COUNT]
arax_pipe_s * pipe
Definition arax_object.h:29
utils_list_s list
Definition arax_object.h:32
size_t alloc_size
Definition arax_object.h:44
volatile int ref_count
Definition arax_object.h:46
arax_object_type_e type
Definition arax_object.h:45
arax_object_repo_s * repo
Definition arax_object.h:42
utils_list_node_s list
Definition arax_object.h:43
size_t length
Definition list.h:19
arch_alloc_s allocator
Definition arax_pipe.h:46