src/libale: Rearrange and comment for memory table definition.
[libale.git] / src / libale.h
blob4cc74f7a3caa2f750d94627df1e10aa6f29b49a6
1 /*
2 * Copyright 2008, 2009 David Hilvert <dhilvert@gmail.com>
4 * This file is part of libale.
6 * libale is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU Affero General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
9 * any later version.
11 * libale is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
14 * more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with libale. If not, see <http://www.gnu.org/licenses/>.
20 #include <ale.h>
22 #include <stdlib.h>
25 * Abstract types used internally by host code (cf. ale_context_get_*_type for
26 * preferred computational types).
29 typedef double ale_pos;
30 typedef double ale_accum;
31 typedef double ale_real;
33 typedef struct { ale_pos x[3]; } point;
35 static point point2(ale_pos x0, ale_pos x1) {
36 point p;
38 p.x[0] = x0;
39 p.x[1] = x1;
40 p.x[2] = 0;
43 static point point3(ale_pos x0, ale_pos x1, ale_pos x2) {
44 point p;
46 p.x[0] = x0;
47 p.x[1] = x1;
48 p.x[2] = x2;
51 static point point_posinf(int dim) {
52 int d;
53 point p;
55 /* Division logic from ALE d2::point::posinf */
57 ale_pos a = +1;
58 ale_pos z = +0;
60 a = a / z;
62 for (d = 0; d < 3; d++)
63 p.x[d] = (d < dim) ? a : 0;
65 return p;
68 static point point_neginf(int dim) {
69 int d;
70 point p = point_posinf(dim);
72 for (d = 0; d < dim && d < 3; d++)
73 p.x[d] = -p.x[d];
75 return p;
79 * Element of the device memory table.
81 * XXX: this might be better done as a table with struct { ale_context c; cl_mem m[0]; };
84 typedef union {
85 cl_mem memory;
86 ale_context context;
87 } mem_table_entry;
90 * Get ale_context associated with a table index from an ALE_POINTER to device
91 * memory.
94 static ale_context api_to_ac(cl_long index) {
95 mem_table_entry *p = (mem_table_entry *) (((char *) NULL) + index);
98 * Get the slot just prior to an invalid cl_mem (marking the start of
99 * the cl_mem table.
102 while (p->memory != ((cl_mem) 0))
103 p--;
105 p--;
107 return p->context;
111 * Macro for obtaining a pointer from ALE_POINTER type.
114 #define P(x) x.p
117 * Macro for obtaining an ale_context associated with an ALE_POINTER to device
118 * memory.
121 #define C(x) api_to_ac(x.t.index)
124 * Macro for obtaining a pointer to host-mapped memory from an ALE_POINTER
125 * type to device memory.
128 #warning map macro not yet defined
129 #define Q(x) /* not yet defined */
132 * Macro for unmapping a previously mapped ALE_POINTER with p = Q(x).
135 #warning unmap macro not yet defined
136 #define R(x, p) /* not yet defined */
139 * Macro for NULL ALE_POINTER.
142 #define N(TYPEP) TYPEP ## _NULL()
145 * Macros for common API type elements and functions.
149 * We do our own reference counting, since there's no obvious
150 * way to perform destruction operations in the case of CL
151 * reference counts. (E.g., the spec explicitly states that
152 * obtained reference count values are unsuitable for uses
153 * other than debugging.
156 #define TYPE_COMMON_ELEMENTS \
157 unsigned int refcount;
159 #define TYPE_STRUCTURE(TYPENAME, TYPE_ELEMENTS) \
160 struct _ ## TYPENAME { \
161 TYPE_COMMON_ELEMENTS \
162 TYPE_ELEMENTS \
165 #define TYPE_HOST_COMMON_FUNCTIONS(TYPENAME, DESTRUCTOR) \
166 int TYPENAME ## _valid(TYPENAME xarg) { \
167 if (P(xarg) == NULL || P(xarg)->refcount == 0) \
168 return 0; \
169 return 1; \
172 int TYPENAME ## _retain(TYPENAME xarg) { \
173 if (!TYPENAME ## _valid(xarg)) \
174 return ALE_UNSPECIFIED_FAILURE; \
175 if (!(P(xarg)->refcount + 1 > 0)) \
176 return ALE_UNSPECIFIED_FAILURE; \
177 P(xarg)->refcount++; \
178 return ALE_SUCCESS; \
181 static TYPENAME TYPENAME ## _alloc() { \
182 TYPENAME retval; \
183 P(retval) = (struct _ ## TYPENAME *) malloc(sizeof(struct _ ## TYPENAME)); \
184 if (P(retval)) \
185 P(retval)->refcount = 1; \
186 return retval; \
189 static void TYPENAME ## _free(TYPENAME this) { \
190 DESTRUCTOR \
193 int TYPENAME ## _release(TYPENAME xarg) { \
194 if (!TYPENAME ## _valid(xarg)) \
195 return ALE_UNSPECIFIED_FAILURE; \
196 P(xarg)->refcount--; \
197 if (P(xarg)->refcount == 0) {\
198 TYPENAME ## _free(xarg); \
199 free(P(xarg)); \
201 return ALE_SUCCESS; \
204 #warning TYPE_COMMON_FUNCTIONS not yet differentiated from TYPE_HOST_COMMON_FUNCTIONS
205 #define TYPE_COMMON_FUNCTIONS(TYPENAME, DESTRUCTOR) \
206 int TYPENAME ## _valid(TYPENAME xarg) { \
207 if (P(xarg) == NULL || P(xarg)->refcount == 0) \
208 return 0; \
209 return 1; \
212 int TYPENAME ## _retain(TYPENAME xarg) { \
213 if (!TYPENAME ## _valid(xarg)) \
214 return ALE_UNSPECIFIED_FAILURE; \
215 if (!(P(xarg)->refcount + 1 > 0)) \
216 return ALE_UNSPECIFIED_FAILURE; \
217 P(xarg)->refcount++; \
218 return ALE_SUCCESS; \
221 static TYPENAME TYPENAME ## _alloc() { \
222 TYPENAME retval; \
223 P(retval) = (struct _ ## TYPENAME *) malloc(sizeof(struct _ ## TYPENAME)); \
224 if (P(retval)) \
225 P(retval)->refcount = 1; \
226 return retval; \
229 static void TYPENAME ## _free(TYPENAME this) { \
230 DESTRUCTOR \
233 int TYPENAME ## _release(TYPENAME xarg) { \
234 if (!TYPENAME ## _valid(xarg)) \
235 return ALE_UNSPECIFIED_FAILURE; \
236 P(xarg)->refcount--; \
237 if (P(xarg)->refcount == 0) {\
238 TYPENAME ## _free(xarg); \
239 free(P(xarg)); \
241 return ALE_SUCCESS; \
244 #define TYPE_HOST(TYPENAME, TYPE_ELEMENTS, DESTRUCTOR) \
245 TYPE_STRUCTURE(TYPENAME, TYPE_ELEMENTS) \
246 TYPE_HOST_COMMON_FUNCTIONS(TYPENAME, DESTRUCTOR)
248 #define TYPE(TYPENAME, TYPE_ELEMENTS, DESTRUCTOR) \
249 ALE_DATA_TYPE(_ ## TYPENAME ## _def, TYPE_STRUCTURE(TYPENAME, TYPE_ELEMENTS) ) \
250 TYPE_COMMON_FUNCTIONS(TYPENAME, DESTRUCTOR)
253 * Macros for API parameter operations.
256 #define PARAMETER_R(OBJECT_TYPE, PARAMETER_NAME, PARAMETER_TYPE) \
257 PARAMETER_TYPE OBJECT_TYPE ## _get_ ## PARAMETER_NAME (OBJECT_TYPE object) { \
258 if (!OBJECT_TYPE ## _valid(object)) \
259 return ((PARAMETER_TYPE) 0); \
260 return object->PARAMETER_NAME; \
263 #define PARAMETER_W(OBJECT_TYPE, PARAMETER_NAME, PARAMETER_TYPE) \
264 int OBJECT_TYPE ## _set_ ## PARAMETER_NAME (OBJECT_TYPE object, PARAMETER_TYPE value){ \
265 if (!OBJECT_TYPE ## _valid(object)) \
266 return ALE_UNSPECIFIED_FAILURE; \
267 object->PARAMETER_NAME = value; \
268 return ALE_SUCCESS; \
271 #define PARAMETER_RW(OBJECT_TYPE, PARAMETER_NAME, PARAMETER_TYPE) \
272 PARAMETER_R(OBJECT_TYPE, PARAMETER_NAME, PARAMETER_TYPE) \
273 PARAMETER_W(OBJECT_TYPE, PARAMETER_NAME, PARAMETER_TYPE)
276 * Detemine type size.
279 static int type_size(int type) {
280 if (type == ALE_TYPE_UINT_8)
281 return 1;
282 if (type == ALE_TYPE_UINT_16)
283 return 2;
284 if (type == ALE_TYPE_FLOAT_32 || type == ALE_TYPE_UINT_32)
285 return 4;
286 if (type == ALE_TYPE_FLOAT_64 || type == ALE_TYPE_UINT_64)
287 return 8;