summaryrefslogtreecommitdiff
path: root/xcache/xc_shm.c
blob: 2bd05ffd10ba25e8564abceee47d915636299b86 (plain)
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
#ifdef TEST
#	ifdef HAVE_CONFIG_H
#		include <config.h>
#	endif
#	include <limits.h>
#	include <stdio.h>
#else
#	include "xcache.h"
#endif
#include "xc_shm.h"

#include <assert.h>
#include <stdlib.h>
#include <string.h>

struct _xc_shm_scheme_t {
	const char            *name;
	const xc_shm_vtable_t *vtable;
};
static xc_shm_scheme_t xc_shm_schemes[10];

void xc_shm_init_modules() /* {{{ */
{
	extern void xc_allocator_init();
#ifdef HAVE_XCACHE_TEST
	extern void xc_shm_malloc_register();
#endif
	extern void xc_shm_mmap_register();

	memset(xc_shm_schemes, 0, sizeof(xc_shm_schemes));
	xc_allocator_init();
#ifdef HAVE_XCACHE_TEST
	xc_shm_malloc_register();
#endif
	xc_shm_mmap_register();
}
/* }}} */
int xc_shm_scheme_register(const char *name, const xc_shm_vtable_t *vtable) /* {{{ */
{
	int i;
	for (i = 0; i < 10; i ++) {
		if (!xc_shm_schemes[i].name) {
			xc_shm_schemes[i].name = name;
			xc_shm_schemes[i].vtable = vtable;
			return 1;
		}
	}
	return 0;
}
/* }}} */
const xc_shm_vtable_t *xc_shm_scheme_find(const char *name) /* {{{ */
{
	int i;
	for (i = 0; i < 10 && xc_shm_schemes[i].name; i ++) {
		if (strcmp(xc_shm_schemes[i].name, name) == 0) {
			return xc_shm_schemes[i].vtable;
		}
	}
	return NULL;
}
/* }}} */
xc_shm_scheme_t *xc_shm_scheme_first() /* {{{ */
{
	return xc_shm_schemes;
}
/* }}} */
xc_shm_scheme_t *xc_shm_scheme_next(xc_shm_scheme_t *scheme) /* {{{ */
{
	scheme ++;
	return scheme->name ? scheme : NULL;
}
/* }}} */
const char *xc_shm_scheme_name(xc_shm_scheme_t *scheme) /* {{{ */
{
	assert(scheme);
	return scheme->name;
}
/* }}} */
xc_shm_t *xc_shm_init(const char *type, xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2) /* {{{ */
{
	const xc_shm_vtable_t *vtable = xc_shm_scheme_find(type);

	if (vtable) {
		xc_shm_t *shm = vtable->init(size, readonly_protection, arg1, arg2);
		if (shm) {
			shm->vtable = vtable;
		}
		return shm;
	}

	return NULL;
}
/* }}} */
void xc_shm_destroy(xc_shm_t *shm) /* {{{ */
{
	shm->vtable->destroy(shm);
}
/* }}} */

int xc_shm_can_readonly(const xc_shm_t *shm) /* {{{ */
{
	return ((xc_shm_base_t *)shm)->readonlydiff != 0;
}
/* }}} */
void *xc_shm_to_readwrite(const xc_shm_t *shm_, void *p) /* {{{ */
{
	const xc_shm_base_t *shm = (const xc_shm_base_t *) shm_;

	if (shm->readonlydiff) {
		assert(shm->vtable->is_readonly(shm_, p));
		p = ((char *) p) - shm->readonlydiff;
	}
	assert(shm->vtable->is_readwrite(shm_, p));
	return p;
}
/* }}} */
void *xc_shm_to_readonly(const xc_shm_t *shm_, void *p) /* {{{ */
{
	const xc_shm_base_t *shm = (const xc_shm_base_t *) shm_;

	assert(shm->vtable->is_readwrite(shm_, p));
	if (shm->readonlydiff) {
		p = ((char *) p) + shm->readonlydiff;
		assert(shm->vtable->is_readonly(shm_, p));
	}
	return p;
}
/* }}} */