-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmemory.c
125 lines (98 loc) · 2.14 KB
/
memory.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
/*
* memory.c
* FluidApp
*/
#include "memory.h"
#include <stdio.h>
#include <stdlib.h>
#ifndef CELL
#include <libkern/OSAtomic.h>
#endif
#include <sys/time.h>
#include <pthread.h>
typedef struct memory_pvt memory_pvt;
struct memory_pvt
{
x_dealloc kill; //Your guess is as good as mine...
int32_t rc; //The retain count...
} __attribute__ ((aligned(16)));
//Replacement allocator
void *x_malloc(int size, x_dealloc in_d)
{
memory_pvt *toRet = malloc128(size + sizeof(memory_pvt));
if (toRet == NULL)
x_raise(errorCreate(NULL, error_memory, "Out of memory!"));
toRet->rc = 1;
toRet->kill = in_d;
return toRet + 1;
}
//Replacment free function
void x_free(void *in_o)
{
memory_pvt *r = (memory_pvt*)in_o;
#ifdef CELL
int nVal = __sync_fetch_and_add(&r[-1].rc, -1) -1;
#else
int nVal = OSAtomicAdd32Barrier(-1, &r[-1].rc);
#endif
if (nVal == 0)
{
r[-1].kill(in_o);
free(r-1);
}
}
//Retain (extension)
void x_retain(void *in_o)
{
memory_pvt *r = (memory_pvt*)in_o;
#ifdef CELL
__sync_fetch_and_add(&r[-1].rc, 1);
#else
OSAtomicAdd32Barrier(1, &r[-1].rc);
#endif
}
//Handle the key used for per-thread exceptions...
pthread_key_t g_except_key;
pthread_key_t g_error_key;
void x_init()
{
pthread_key_create(&g_except_key, NULL);
pthread_key_create(&g_error_key, NULL);
signal(SIGPIPE, SIG_IGN); //Ignore SIGPIPE...
}
sigjmp_buf *x_setupBuff(sigjmp_buf *in_newBuff)
{
sigjmp_buf *toRet = pthread_getspecific(g_except_key);
if (pthread_setspecific(g_except_key, in_newBuff) != 0)
{
x_raise(errorCreate(NULL, error_create, "Failed setting thread specific data"));
}
return toRet;
}
void x_raise(error *e)
{
sigjmp_buf *jmp = pthread_getspecific(g_except_key);
//No handler, simply abort
if (jmp == NULL)
{
printf("%s\n",errorMsg(e));
abort();
}
errorAssert(pthread_setspecific(g_error_key, e) == 0, error_create,
"Failed setting key to error");
_longjmp(*jmp, 1);
}
error *x_raisedError()
{
return pthread_getspecific(g_error_key);
}
uint64_t unixTime()
{
return time(0);
}
#ifdef CELL
FILE *x_fopen(const char *in_szFile, const char *in_mode)
{
return fopen(in_szFile, in_mode);
}
#endif