-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrc.c
149 lines (126 loc) · 2.67 KB
/
rc.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/time.h>
typedef struct {
int64_t memcount;
int16_t wrefct;
int16_t wrefal;
void ***wrefs;
void (*teardown)(void *, int);
} __egl_ptr;
typedef struct {
__egl_ptr main;
__egl_ptr *to;
} __egl_ptr_ptr;
int64_t __egl_millis()
{
struct timeval t;
gettimeofday(&t, 0);
int64_t millitime = t.tv_sec * INT64_C(1000) + t.tv_usec / 1000;
return millitime;
}
void __egl_prepare(__egl_ptr *ptr)
{
ptr->memcount = 0;
ptr->wrefct = 0;
ptr->wrefal = 0;
ptr->wrefs = NULL;
ptr->teardown = NULL;
}
void __egl_incr_ptr(__egl_ptr *ptr)
{
if(ptr)
ptr->memcount = ptr->memcount + 1;
}
void __egl_set_nil(void ***vals, int16_t ct)
{
int i;
for(i = 0; i < ct; i++)
*vals[i] = NULL;
}
void __egl_decr_ptr(__egl_ptr *ptr)
{
if(!ptr || ptr->memcount < 0)
return;
ptr->memcount = ptr->memcount - 1;
if(!ptr->memcount)
{
if(ptr->wrefs)
{
__egl_set_nil(ptr->wrefs, ptr->wrefct);
free(ptr->wrefs);
}
if(ptr->teardown) ptr->teardown(ptr, 1);
free(ptr);
}
}
void __egl_counted_destructor(__egl_ptr_ptr *ptr, int i)
{
__egl_decr_ptr(ptr->to);
}
void __egl_check_ptr(__egl_ptr *ptr)
{
if(!ptr || ptr->memcount < 0)
return;
if(!ptr->memcount)
{
if(ptr->wrefs)
{
__egl_set_nil(ptr->wrefs, ptr->wrefct);
free(ptr->wrefs);
}
if(ptr->teardown) ptr->teardown(ptr, 1);
free(ptr);
}
}
void __egl_add_weak(__egl_ptr *ptr, void **pos)
{
if(!ptr || ptr->memcount < 0)
return;
if(ptr->wrefal == ptr->wrefct)
{
ptr->wrefs = realloc(ptr->wrefs, (ptr->wrefct + 10) * sizeof(void *));
ptr->wrefal += 10;
}
ptr->wrefs[ptr->wrefct++] = pos;
}
void __egl_remove_weak(__egl_ptr **pos)
{
if(!pos)
return;
if(!*pos)
return;
__egl_ptr *ptr = *pos;
int idx = -1;
int i;
for(i = 0; i < ptr->wrefct; i++)
{
if(ptr->wrefs[i] == (void *)pos)
{
idx = i;
break;
}
}
if(idx < 0)
return;
if(idx == ptr->wrefct - 1)
{
ptr->wrefct--;
ptr->wrefs[idx] = NULL;
return;
}
memmove(ptr->wrefs + idx, ptr->wrefs + idx + 1, (ptr->wrefct - idx - 1) * sizeof(void *));
ptr->wrefs[--ptr->wrefct] = NULL;
}
void __egl_array_fill_nil(void *arr, int64_t ct)
{
memset(arr, 0, ct * sizeof(void *));
}
void __egl_array_decr_ptrs(void **arr, int64_t ct)
{
int64_t i;
for(i = 0; i < ct; i++)
__egl_decr_ptr(arr[i]);
}