forked from taisei-project/taisei
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrefs.c
93 lines (74 loc) · 2.13 KB
/
refs.c
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
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (c) 2011-2018, Lukas Weber <[email protected]>.
* Copyright (c) 2012-2018, Andrei Alexeyev <[email protected]>.
*/
#include "taisei.h"
#include "global.h"
#include "refs.h"
void *_FREEREF;
#ifdef DEBUG
// #define DEBUG_REFS
#endif
#ifdef DEBUG_REFS
#define REFLOG(...) log_debug(__VA_ARGS__);
#else
#define REFLOG(...)
#endif
int add_ref(void *ptr) {
int i, firstfree = -1;
for(i = 0; i < global.refs.count; i++) {
if(global.refs.ptrs[i].ptr == ptr) {
global.refs.ptrs[i].refs++;
REFLOG("increased refcount for %p (ref %i): %i", ptr, i, global.refs.ptrs[i].refs);
return i;
} else if(firstfree < 0 && global.refs.ptrs[i].ptr == FREEREF) {
firstfree = i;
}
}
if(firstfree >= 0) {
global.refs.ptrs[firstfree].ptr = ptr;
global.refs.ptrs[firstfree].refs = 1;
REFLOG("found free ref for %p: %i", ptr, firstfree);
return firstfree;
}
global.refs.ptrs = realloc(global.refs.ptrs, (++global.refs.count)*sizeof(Reference));
global.refs.ptrs[global.refs.count - 1].ptr = ptr;
global.refs.ptrs[global.refs.count - 1].refs = 1;
REFLOG("new ref for %p: %i", ptr, global.refs.count - 1);
return global.refs.count - 1;
}
void del_ref(void *ptr) {
int i;
for(i = 0; i < global.refs.count; i++)
if(global.refs.ptrs[i].ptr == ptr)
global.refs.ptrs[i].ptr = NULL;
}
void free_ref(int i) {
if(i < 0)
return;
global.refs.ptrs[i].refs--;
REFLOG("decreased refcount for %p (ref %i): %i", global.refs.ptrs[i].ptr, i, global.refs.ptrs[i].refs);
if(global.refs.ptrs[i].refs <= 0) {
global.refs.ptrs[i].ptr = FREEREF;
global.refs.ptrs[i].refs = 0;
REFLOG("ref %i is now free", i);
}
}
void free_all_refs(void) {
int inuse = 0;
int inuse_unique = 0;
for(int i = 0; i < global.refs.count; i++) {
if(global.refs.ptrs[i].refs) {
inuse += global.refs.ptrs[i].refs;
inuse_unique += 1;
}
}
if(inuse) {
log_warn("%i refs were still in use (%i unique, %i total allocated)", inuse, inuse_unique, global.refs.count);
}
free(global.refs.ptrs);
memset(&global.refs, 0, sizeof(RefArray));
}