1
/* Copyright (c) 2015-2018, Linaro Limited
2
 * All rights reserved.
3
 *
4
 * SPDX-License-Identifier:	BSD-3-Clause
5
 */
6

7
#include <stdio.h>
8
#include <string.h>
9
#include <malloc.h>
10

11
#include <odp/helper/odph_lineartable.h>
12
#include <odp/helper/odph_debug.h>
13
#include <odp_api.h>
14

15
#define     ODPH_SUCCESS	0
16
#define     ODPH_FAIL		-1
17

18
/** @magic word, write to the first byte of the memory block
19
 *  to indicate this block is used by a linear table structure
20
 */
21
#define     ODPH_LINEAR_TABLE_MAGIC_WORD   0xEFEFFEFE
22

23
/** @internal table struct
24
 *   For linear table, value is orgnized as a big array,
25
 *   and key is the index of this array, so we just need to record the
26
 *   content of value, and make sure the key won't overflow
27
 */
28
typedef struct {
29
	uint32_t magicword; /**< for check */
30
	uint32_t init_cap; /**< input param of capacity */
31
	/** given the capacity, caculate out the max supported nodes number */
32
	uint32_t node_sum;
33
	/** size of a lineartable element,including the rwlock in the head */
34
	uint32_t value_size;
35
	void *value_array; /**< value pool in array format */
36
	char name[ODPH_TABLE_NAME_LEN]; /**< name of the table */
37
} odph_linear_table_imp;
38

39
/** Note: for linear table, key must be an number, its size is fixed 4.
40
 *  So, we ignore the input key_size here
41
 */
42

43 0
odph_table_t odph_linear_table_create(const char *name, uint32_t capacity,
44
				      uint32_t un ODP_UNUSED,
45
				      uint32_t value_size)
46
{
47
	uint32_t idx;
48
	uint32_t node_num;
49
	odp_shm_t shmem;
50
	odph_linear_table_imp *tbl;
51

52 0
	if (strlen(name) >= ODPH_TABLE_NAME_LEN || capacity < 1 ||
53 0
	    capacity >= 0x1000 || value_size == 0) {
54 0
		printf("create para input error or less than !");
55 0
		return NULL;
56
	}
57
	/* check name confict in shm*/
58 0
	if (odp_shm_lookup(name) != ODP_SHM_INVALID) {
59 0
		ODPH_DBG("name already exist\n");
60 0
		return NULL;
61
	}
62

63
	/* alloc memory from shm */
64 0
	shmem = odp_shm_reserve(name, capacity << 20, 64, ODP_SHM_SW_ONLY);
65 0
	if (shmem == ODP_SHM_INVALID) {
66 0
		ODPH_DBG("shm reserve fail\n");
67 0
		return NULL;
68
	}
69 0
	tbl = (odph_linear_table_imp *)odp_shm_addr(shmem);
70

71
	/* clean this block of memory */
72 0
	memset(tbl, 0, capacity << 20);
73

74 0
	tbl->init_cap = capacity < 20;
75

76 0
	strncpy(tbl->name, name, ODPH_TABLE_NAME_LEN - 1);
77

78
	/* for linear table, the key is just the index, without confict
79
	 * so we just need to record the value content
80
	 * there is a rwlock in the head of every node
81
	 */
82

83 0
	tbl->value_size = value_size + sizeof(odp_rwlock_t);
84

85 0
	node_num = tbl->init_cap / tbl->value_size;
86 0
	tbl->node_sum = node_num;
87

88 0
	tbl->value_array = (void *)((char *)tbl
89
			+ sizeof(odph_linear_table_imp));
90

91
	/* initialize rwlock*/
92 0
	for (idx = 0; idx < tbl->node_sum; idx++) {
93
		odp_rwlock_t *lock;
94

95 0
		lock = (odp_rwlock_t *)(void *)((char *)tbl->value_array
96 0
		       + idx * tbl->value_size);
97 0
		odp_rwlock_init(lock);
98
	}
99

100 0
	tbl->magicword = ODPH_LINEAR_TABLE_MAGIC_WORD;
101

102 0
	return (odph_table_t)(tbl);
103
}
104

105 0
int odph_linear_table_destroy(odph_table_t table)
106
{
107
	int ret;
108 0
	odph_linear_table_imp *linear_tbl = NULL;
109

110 0
	if (table != NULL) {
111 0
		linear_tbl = (odph_linear_table_imp *)(void *)table;
112

113
		/* check magicword, make sure the memory is used by a table */
114 0
		if (linear_tbl->magicword != ODPH_LINEAR_TABLE_MAGIC_WORD)
115 0
			return ODPH_FAIL;
116

117 0
		ret = odp_shm_free(odp_shm_lookup(linear_tbl->name));
118 0
		if (ret != 0) {
119 0
			ODPH_DBG("free fail\n");
120 0
			return ret;
121
		}
122

123 0
		return ODPH_SUCCESS;
124
	}
125 0
	return ODPH_FAIL;
126
}
127

128 0
odph_table_t odph_linear_table_lookup(const char *name)
129
{
130 0
	odph_linear_table_imp *tbl = NULL;
131
	odp_shm_t shm;
132

133 0
	if (name == NULL || strlen(name) >= ODPH_TABLE_NAME_LEN)
134 0
		return NULL;
135

136 0
	shm = odp_shm_lookup(name);
137 0
	if (shm != ODP_SHM_INVALID)
138 0
		tbl = (odph_linear_table_imp *)odp_shm_addr(shm);
139

140
	/* check magicword to make sure the memory block is used by a table */
141 0
	if (tbl != NULL &&
142 0
	    tbl->magicword == ODPH_LINEAR_TABLE_MAGIC_WORD &&
143 0
	    strcmp(tbl->name, name) == 0)
144 0
		return (odph_table_t)tbl;
145

146 0
	return NULL;
147
}
148

149
/* should make sure the input table exists and is available */
150 0
static int odph_lineartable_put_value(odph_table_t table,
151
				      void *key, void *value)
152
{
153
	odph_linear_table_imp *tbl;
154 0
	uint32_t ikey = 0;
155 0
	void *entry = NULL;
156 0
	odp_rwlock_t *lock = NULL;
157

158 0
	if (table == NULL || key == NULL || value == NULL)
159 0
		return ODPH_FAIL;
160

161 0
	tbl = (odph_linear_table_imp *)(void *)table;
162 0
	ikey = *(uint32_t *)key;
163 0
	if (ikey >= tbl->node_sum)
164 0
		return ODPH_FAIL;
165

166 0
	entry = (void *)((char *)tbl->value_array + ikey * tbl->value_size);
167 0
	lock = (odp_rwlock_t *)entry;
168 0
	entry = (char *)entry + sizeof(odp_rwlock_t);
169

170 0
	odp_rwlock_write_lock(lock);
171

172 0
	memcpy(entry, value, tbl->value_size - sizeof(odp_rwlock_t));
173

174 0
	odp_rwlock_write_unlock(lock);
175

176 0
	return ODPH_SUCCESS;
177
}
178

179
/* should make sure the input table exists and is available */
180 0
static int odph_lineartable_get_value(odph_table_t table,
181
				      void *key, void *buffer,
182
				      uint32_t buffer_size ODP_UNUSED)
183
{
184
	odph_linear_table_imp *tbl;
185 0
	uint32_t ikey = 0;
186 0
	void *entry = NULL;
187 0
	odp_rwlock_t *lock = NULL;
188

189 0
	if (table == NULL || key == NULL || buffer == NULL)
190 0
		return ODPH_FAIL;
191

192 0
	tbl = (odph_linear_table_imp *)(void *)table;
193 0
	ikey = *(uint32_t *)key;
194 0
	if (ikey >= tbl->node_sum)
195 0
		return ODPH_FAIL;
196

197 0
	entry = (void *)((char *)tbl->value_array + ikey * tbl->value_size);
198 0
	lock = (odp_rwlock_t *)entry;
199 0
	entry = (char *)entry + sizeof(odp_rwlock_t);
200

201 0
	odp_rwlock_read_lock(lock);
202

203 0
	memcpy(buffer, entry, tbl->value_size - sizeof(odp_rwlock_t));
204

205 0
	odp_rwlock_read_unlock(lock);
206

207 0
	return ODPH_SUCCESS;
208
}
209

210
odph_table_ops_t odph_linear_table_ops = {
211
	odph_linear_table_create,
212
	odph_linear_table_lookup,
213
	odph_linear_table_destroy,
214
	odph_lineartable_put_value,
215
	odph_lineartable_get_value,
216
	NULL,
217
	};
218

Read our documentation on viewing source code .

Loading