summaryrefslogtreecommitdiffhomepage
path: root/include/dalist/dalist.h
blob: a4783062ceaad1838193f6b15345b736b47d27cf (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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#ifndef DALIST_H
#define DALIST_H

#include "dalist_api.h"

#ifdef __cplusplus
extern "C" {
#endif

/* dalist node types */
enum dalist_node_types {
	DALIST_NODE,
	DALIST_NODE_EX,
};


/* dalist caller-provided memory allocation methods */
enum dalist_memfn {
	DALIST_MEMFN_CUSTOM,
	DALIST_MEMFN_MMAP,
	DALIST_MEMFN_MALLOC,
	DALIST_MEMFN_NT_ALLOCATE_VIRTUAL_MEMORY,
};


/* dalist debug environments */
enum dalist_dbgenv {
	DALIST_DEBUG_ENV_POSIX,
	DALIST_DEBUG_ENV_NT,
};


/* dalist return values */
#define DALIST_OK			(0x0)
#define DALIST_EINTERNAL		(0xD0000000)	/* internal error */
#define DALIST_EMEMFN			(0xD0000001)	/* memory allocation error */
#define DALIST_EMEMBLOCK		(0xD0000002)	/* invalid memory block */
#define DALIST_ELIST			(0xD0000003)	/* invalid list */
#define DALIST_ENODE			(0xD0000004)	/* invalid node */
#define DALIST_EPARAMMIX		(0xD0000005)	/* invalid parameter mix */
#define DALIST_EKEYEXISTS		(0xD0000006)	/* key already exists */
#define DALIST_ELISTNOTEMPTY		(0xD0000007)	/* null insertion point with non-empty list */

/* dalist debug return values */
#define DALIST_EDEBUGSTRUCT		(0xD0001000)	/* invalid debug structure */
#define DALIST_EDEBUGENV		(0xD0001001)	/* invalid debug environment */
#define DALIST_EDEBUGSPRINTF		(0xD0001002)	/* invalid debug pointer to sprintf */
#define DALIST_EDEBUGWRITE		(0xD0001003)	/* invalid debug pointer to write (posix) */
#define DALIST_EDEBUGWRITEFILE		(0xD0001004)	/* invalid debug pointer to zw_write_file (nt) */


/* dalist node flag bits */
#define DALIST_NODE_TYPE_NONE		(0x00u)
#define DALIST_NODE_TYPE_EXISTING	(0x01u)
#define DALIST_NODE_TYPE_NEW		(0x02u)
#define DALIST_NODE_TYPE_DELETED	(0x04u)
#define DALIST_NODE_MEM_BLOCK_BASE	(0x80u)


struct dalist_node {
	struct dalist_node *	prev;
	struct dalist_node *	next;
	uintptr_t		any;
};


struct dalist {
	struct dalist_node *	head;
	struct dalist_node *	tail;
};


struct dalist_node_ex {
	struct dalist_node_ex *	prev;
	struct dalist_node_ex *	next;
	uintptr_t		key;
	uintptr_t		flags;
	uintptr_t		dblock;
};


struct dalist_debug;

struct dalist_ex {
	void *			head;		/************************************/
	void *			tail;		/* head, tail, free:                */
	void *			free;		/* dalist_node when dblock_size is  */
	uintptr_t *		bookmarks;	/* zero, dalist_node_ex otherwise.  */
	size_t			dblock_size;	/*                                  */
	size_t			lblock_size;	/* lblock_size:                     */
	void *			memfn_ptr;	/* used when memfn_method is mmap   */
	enum dalist_memfn	memfn_method;	/* or nt_allocate_virtual_memory    */
	int			memfn_status;	/* as the system call's alloc_size  */
	int			mmap_prot;	/* argument.                        */
	int			mmap_flags;	/*                                  */
	int			mmap_fildes;	/*                                  */
	intptr_t		mmap_offset;	/************************************/
	struct dalist_debug *	debug;

	struct dalist_info {
		uintptr_t	list_nodes;
		uintptr_t	free_nodes;
		uintptr_t	bookmark_from;
		uintptr_t	bookmark_to;
		uintptr_t	bookmark_key_min;
		uintptr_t	bookmark_key_max;
		uintptr_t	nodes_below_first_bookmark;
		uintptr_t	nodes_above_last_bookmark;
	} info;
};


/* signatures for caller-provided debug output functions */
typedef int	__cdecl	  dalist_sprintf(char * buffer, const char * format, ...);
typedef ssize_t	__cdecl	  dalist_write(int fildes, const void *buf, size_t nbyte);
typedef int32_t __stdcall dalist_write_file(
	void *		hfile,
	void *		hevent,
	void *		apc_routine,
	void * 		apc_context,
	void * 		io_status_block,
	void * 		buffer,
	uint32_t	bytes_sent,
	int64_t *	byte_offset,
	uint32_t *	key);


/* debug */
struct dalist_debug {
	enum dalist_dbgenv	dbgenv;
	dalist_sprintf *	sprintf;	/* required (all) */
	dalist_write *		write;		/* required (posix only) */
	dalist_write_file *	zw_write_file;	/* required (nt only) */
};


/* signatures for caller-provided memory allocation functions */
typedef void * __cdecl dalist_memfn_mmap(
	void *		addr,
	size_t		alloc_size,
	int		prot,
	int		flags,
	int		fildes,
	intptr_t	offset);


typedef void * __cdecl dalist_memfn_malloc(
	size_t		alloc_size);


typedef int32_t __stdcall dalist_memfn_nt_allocvm(
	void *		hprocess,
	void **		base_address,
	uint32_t	zero_bits,
	size_t *	alloc_size,
	uint32_t	alloc_type,
	uint32_t	protect);


/**
 *  dalist_memfn_custom:
 *  must return either DALIST_OK or DALIST_EMEMFN;
 *  may update the list's memfn_status member
**/
typedef int __cdecl dalist_memfn_custom(
	struct dalist_ex *	dlist,
	void **			addr,
	size_t *		alloc_size);

dalist_api
int dalist_init(struct dalist *	dlist);

dalist_api
int dalist_init_ex(
	struct dalist_ex *	dlist,
	size_t			dblock_size,
	size_t			lblock_size,
	void *			memfn_ptr,
	enum dalist_memfn	memfn_method);

dalist_api
int dalist_insert_before(
	struct dalist *		dlist,
	struct dalist_node *	lnode,
	struct dalist_node *	nnode);

dalist_api
int dalist_insert_after(
	struct dalist *		dlist,
	struct dalist_node *	lnode,
	struct dalist_node *	nnode);

dalist_api
int dalist_get_free_node(
	struct dalist_ex *	dlist,
	void **			fnode);

dalist_api
int dalist_deposit_free_node(
	struct dalist_ex *	dlist,
	void *			fnode);

dalist_api
int dalist_deposit_memory_block(
	struct dalist_ex *	dlist,
	void *			addr,
	size_t			alloc_size);

dalist_api
int dalist_unlink_node(
	struct dalist *		dlist,
	struct dalist_node *	node);

dalist_api
int dalist_unlink_node_ex(
	struct dalist_ex *	dlist,
	struct dalist_node_ex *	node);

dalist_api
int dalist_discard_node(
	struct dalist_ex *	dlist,
	struct dalist_node_ex *	node);

dalist_api
int dalist_get_node_by_key(
	struct dalist_ex *	dlist,
	struct dalist_node_ex **node,
	uintptr_t		key,
	uintptr_t		get_flags,
	uintptr_t *		node_flags);

dalist_api
int dalist_insert_node_by_key(
	struct dalist_ex *	dlist,
	struct dalist_node_ex *	node);

/* debug routines */
dalist_api
int dalist_debug_setup(
	struct dalist_ex *	dlist,
	struct dalist_debug *	dlist_debug,
	enum dalist_dbgenv	dbgenv,
	dalist_sprintf *	pfn_sprintf,
	dalist_write *		pfn_write,
	dalist_write_file *	pfn_write_file);

dalist_api
int dalist_debug_print(
	struct dalist_ex *	dlist,
	intptr_t		fildes_or_hfile);


#ifdef __cplusplus
}
#endif
#endif