rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit f8e2cf9d7def06349b4726d5985123f08c3caf8d
parent 3a79b486935447c58da58a5060eb27b876f582dc
Author: vaplv <vaplv@free.fr>
Date:   Tue, 19 Aug 2014 22:05:14 +0200

Fix memory area overlapping issues in the floatX[Y] functions

Diffstat:
Msrc/floatX.h | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/floatXY.h | 100+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/rsys.h | 6++++++
Msrc/str.c | 10++--------
4 files changed, 119 insertions(+), 81 deletions(-)

diff --git a/src/floatX.h b/src/floatX.h @@ -18,6 +18,9 @@ STATIC_ASSERT(FLOATX_DIMENSION__ > 1, Unexpected_value); #define FLOATX_FUNC__(Func) \ CONCAT(CONCAT(CONCAT(f, FLOATX_DIMENSION__), _), Func) +/* Helper macro */ +#define SIZEOF_FLOATX__ sizeof(float[FLOATX_DIMENSION__]) + #if FLOATX_DIMENSION__ <= 4 static FINLINE float* CONCAT(f, FLOATX_DIMENSION__) @@ -56,15 +59,28 @@ FLOATX_FUNC__(splat)(float* dst, const float val) } static FINLINE float* -FLOATX_FUNC__(set)(float* dst, const float* src) +FLOATX_FUNC__(set__)(float* dst, const float* src) { int i; ASSERT(dst && src); + ASSERT(!MEM_AREA_OVERLAP(dst, SIZEOF_FLOATX__, src, SIZEOF_FLOATX__)); FOR_EACH(i, 0, FLOATX_DIMENSION__) dst[i] = src[i]; return dst; } +static FINLINE float* +FLOATX_FUNC__(set)(float* dst, const float* src) +{ + ASSERT(dst && src); + if(!MEM_AREA_OVERLAP(dst, SIZEOF_FLOATX__, src, SIZEOF_FLOATX__)) { + return FLOATX_FUNC__(set__)(dst, src); + } else { + float tmp[FLOATX_DIMENSION__]; + return FLOATX_FUNC__(set__)(dst, FLOATX_FUNC__(set__)(tmp, src)); + } +} + static FINLINE float FLOATX_FUNC__(dot)(const float* a, const float* b) { @@ -86,6 +102,7 @@ FLOATX_FUNC__(len)(const float* a) static FINLINE float FLOATX_FUNC__(normalize)(float* dst, const float* a) { + float tmp[FLOATX_DIMENSION__]; float len, rcp_len; int i; ASSERT(dst && a); @@ -96,7 +113,8 @@ FLOATX_FUNC__(normalize)(float* dst, const float* a) rcp_len = 1.0f / len; FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] * rcp_len; + tmp[i] = a[i] * rcp_len; + FLOATX_FUNC__(set__)(dst, tmp); return len; } @@ -109,91 +127,100 @@ FLOATX_FUNC__(is_normalized)(const float* a) static FINLINE float* FLOATX_FUNC__(add)(float* dst, const float* a, const float* b) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a && b); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] + b[i]; - return dst; + tmp[i] = a[i] + b[i]; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(addf)(float* dst, const float* a, const float f) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] + f; - return dst; + tmp[i] = a[i] + f; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(sub)(float* dst, const float* a, const float* b) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a && b); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] - b[i]; - return dst; + tmp[i] = a[i] - b[i]; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(subf)(float* dst, const float* a, const float f) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] - f; - return dst; + tmp[i] = a[i] - f; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(mul)(float* dst, const float* a, const float* b) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a && b); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] * b[i]; - return dst; + tmp[i] = a[i] * b[i]; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(mulf)(float* dst, const float* a, const float f) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] * f; - return dst; + tmp[i] = a[i] * f; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(div)(float* dst, const float* a, const float* b) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a && b); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] / b[i]; - return dst; + tmp[i] = a[i] / b[i]; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(divf)(float* dst, const float* a, const float f) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] / f; - return dst; + tmp[i] = a[i] / f; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(minus)(float* dst, const float* a) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = -a[i]; - return dst; + tmp[i] = -a[i]; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float @@ -222,10 +249,11 @@ FLOATX_FUNC__(lerp) } else if(t >= 1.0f) { FLOATX_FUNC__(set)(dst, to); } else { + float tmp[FLOATX_DIMENSION__]; int i; - FOR_EACH(i, 0, FLOATX_DIMENSION__) { - dst[i] = from[i] + t * (to[i] - from[i]); - } + FOR_EACH(i, 0, FLOATX_DIMENSION__) + tmp[i] = from[i] + t * (to[i] - from[i]); + FLOATX_FUNC__(set__)(dst, tmp); } return dst; } @@ -259,21 +287,23 @@ FLOATX_FUNC__(eq_eps)(const float* a, const float* b, const float eps) static FINLINE float* FLOATX_FUNC__(max)(float* dst, const float* a, const float* b) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a && b); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] > b[i] ? a[i] : b[i]; - return dst; + tmp[i] = a[i] > b[i] ? a[i] : b[i]; + return FLOATX_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATX_FUNC__(min)(float* dst, const float* a, const float* b) { + float tmp[FLOATX_DIMENSION__]; int i; ASSERT(dst && a && b); FOR_EACH(i, 0, FLOATX_DIMENSION__) - dst[i] = a[i] < b[i] ? a[i] : b[i]; - return dst; + tmp[i] = a[i] < b[i] ? a[i] : b[i]; + return FLOATX_FUNC__(set__)(dst, tmp); } #undef FLOATX_DIMENSION__ diff --git a/src/floatXY.h b/src/floatXY.h @@ -25,6 +25,9 @@ STATIC_ASSERT #define FLOATY_FUNC__(Func) \ CONCAT(CONCAT(CONCAT(f, FLOATY_DIMENSION__), _), Func) +/* Helper macro */ +#define SIZEOF_FLOATXY__ sizeof(float[FLOATX_DIMENSION__*FLOATY_DIMENSION__]) + static FINLINE float* FLOATXY_FUNC__(splat)(float* dst, const float val) { @@ -37,32 +40,43 @@ FLOATXY_FUNC__(splat)(float* dst, const float val) } static FINLINE float* -FLOATXY_FUNC__(set)(float* dst, const float* src) +FLOATXY_FUNC__(set__)(float* dst, const float* src) { int x, y, i; ASSERT(dst && src); + ASSERT(!MEM_AREA_OVERLAP(dst, SIZEOF_FLOATXY__, src, SIZEOF_FLOATXY__)); i = 0; FOR_EACH(x, 0, FLOATX_DIMENSION__) { - FOR_EACH(y, 0, FLOATY_DIMENSION__) { - dst[i] = src[i]; - ++i; - } - } + FOR_EACH(y, 0, FLOATY_DIMENSION__) { + dst[i] = src[i]; + ++i; + }} return dst; } static FINLINE float* +FLOATXY_FUNC__(set)(float* dst, const float* src) +{ + ASSERT(dst && src); + if(!MEM_AREA_OVERLAP(dst, SIZEOF_FLOATXY__, src, SIZEOF_FLOATXY__)) { + return FLOATXY_FUNC__(set__)(dst, src); + } else { + float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__]; + return FLOATXY_FUNC__(set__)(dst, FLOATXY_FUNC__(set__)(tmp, src)); + } +} + +static FINLINE float* FLOATXY_FUNC__(set_identity)(float* mat) { int x, y, i; ASSERT(mat); i = 0; FOR_EACH(x, 0, FLOATX_DIMENSION__) { - FOR_EACH(y, 0, FLOATY_DIMENSION__) { - mat[i] = x == y ? 1.f : 0.f; - ++i; - } - } + FOR_EACH(y, 0, FLOATY_DIMENSION__) { + mat[i] = x == y ? 1.f : 0.f; + ++i; + }} return mat; } @@ -138,28 +152,31 @@ FLOATXY_FUNC__(col)(float* col, const float* mat, const int icol) static FINLINE float* FLOATXY_FUNC__(add)(float* dst, const float* a, const float* b) { + float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__]; int i; FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) - dst[i] = a[i] + b[i]; - return dst; + tmp[i] = a[i] + b[i]; + return FLOATXY_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATXY_FUNC__(sub)(float* dst, const float* a, const float* b) { + float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__]; int i; FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) - dst[i] = a[i] - b[i]; - return dst; + tmp[i] = a[i] - b[i]; + return FLOATXY_FUNC__(set__)(dst, tmp); } static FINLINE float* FLOATXY_FUNC__(minus)(float* dst, const float* a) { + float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__]; int i; FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) - dst[i] = -a[i]; - return dst; + tmp[i] = -a[i]; + return FLOATXY_FUNC__(set__)(dst, tmp); } static FINLINE char @@ -211,12 +228,12 @@ FLOATXY_FUNC__(CONCAT(mulf, FLOATX_DIMENSION__)) static FINLINE float* FLOATXY_FUNC__(mul)(float* dst, const float* mat, const float b) { + float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__]; int i; ASSERT(dst && mat); - FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) { - dst[i] = mat[i] * b; - } - return dst; + FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) + tmp[i] = mat[i] * b; + return FLOATXY_FUNC__(set__)(dst, tmp);; } static FINLINE float* @@ -243,15 +260,11 @@ FLOATXY_FUNC__(transpose)(float* dst, const float* src) i = 0; FOR_EACH(x, 0, FLOATX_DIMENSION__) { - FOR_EACH(y, 0, FLOATY_DIMENSION__) { - tmp[y * FLOATY_DIMENSION__ + x] = src[i]; - ++i; - } - } - FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) { - dst[i] = tmp[i]; - } - return dst; + FOR_EACH(y, 0, FLOATY_DIMENSION__) { + tmp[y * FLOATY_DIMENSION__ + x] = src[i]; + ++i; + }} + return FLOATXY_FUNC__(set__)(dst, tmp); } static FINLINE float* @@ -265,25 +278,19 @@ FLOATXY_FUNC__(CONCAT(CONCAT(mulf, FLOATX_DIMENSION__), FLOATY_DIMENSION__)) /* Transpose the a matrix */ i = 0; FOR_EACH(x, 0, FLOATX_DIMENSION__) { - FOR_EACH(y, 0, FLOATY_DIMENSION__) { - a_trans[y * FLOATY_DIMENSION__ + x] = a[i]; - ++i; - } - } + FOR_EACH(y, 0, FLOATY_DIMENSION__) { + a_trans[y * FLOATY_DIMENSION__ + x] = a[i]; + ++i; + }} /* Compute the a x b and store the result into tmp */ i = 0; FOR_EACH(x, 0, FLOATX_DIMENSION__) { - FOR_EACH(y, 0, FLOATY_DIMENSION__) { - tmp[i] = FLOATX_FUNC__(dot) - (a_trans + (y * FLOATY_DIMENSION__), b + (x * FLOATY_DIMENSION__)); - ++i; - } - } - /* Copy the tmp matrix into dst */ - FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) { - dst[i] = tmp[i]; - } - return dst; + FOR_EACH(y, 0, FLOATY_DIMENSION__) { + tmp[i] = FLOATX_FUNC__(dot) + (a_trans + (y * FLOATY_DIMENSION__), b + (x * FLOATY_DIMENSION__)); + ++i; + }} + return FLOATXY_FUNC__(set__)(dst, tmp); } #endif /* FLOATX_DIMENSION__ == FLOATY_DIMENSION__ */ @@ -291,4 +298,5 @@ FLOATXY_FUNC__(CONCAT(CONCAT(mulf, FLOATX_DIMENSION__), FLOATY_DIMENSION__)) #undef FLOATXY_FUNC__ #undef FLOATX_DIMENSION__ #undef FLOATY_DIMENSION__ +#undef SIZEOF_FLOATXY__ diff --git a/src/rsys.h b/src/rsys.h @@ -206,6 +206,12 @@ #define OFFSET_PTR(Ptr, Offset) (void*)((uintptr_t)(Ptr) + (Offset)) +#define MEM_AREA_OVERLAP( A, SzA, B, SzB ) \ + (((uintptr_t)(A) >= (uintptr_t)(B) && \ + (uintptr_t)(A) < ((uintptr_t)(B) + (SzB))) || \ + (((uintptr_t)(A) + (SzA)) >= (uintptr_t)(B) && \ + ((uintptr_t)(A) + (SzA)) < ((uintptr_t)(B) + (SzB)))) + #ifdef __cplusplus #define BEGIN_DECLS extern "C" { #define END_DECLS } diff --git a/src/str.c b/src/str.c @@ -1,12 +1,6 @@ #include "str.h" #include <string.h> -#define IS_MEMORY_OVERLAPPED__( A, SzA, B, SzB ) \ - (((uintptr_t)(A) >= (uintptr_t)(B) && \ - (uintptr_t)(A) < ((uintptr_t)(B) + (SzB))) || \ - (((uintptr_t)(A) + (SzA)) >= (uintptr_t)(B) && \ - ((uintptr_t)(A) + (SzA)) < ((uintptr_t)(B) + (SzB)))) - /******************************************************************************* * helper function ******************************************************************************/ @@ -71,7 +65,7 @@ str_insert(struct str* str, const size_t i, const char* cstr) return -1 ; cstr_len = strlen(cstr); - ASSERT(!IS_MEMORY_OVERLAPPED__ + ASSERT(!MEM_AREA_OVERLAP (str->cstr, str->allocated, cstr, (cstr_len + 1) * sizeof(char))); if(i == str->len) { @@ -125,7 +119,7 @@ str_append(struct str* str, const char* cstr) ASSERT(str && cstr); cstr_len = strlen(cstr); - ASSERT(!IS_MEMORY_OVERLAPPED__ + ASSERT(!MEM_AREA_OVERLAP (str->cstr, str->allocated, cstr, (cstr_len + 1) * sizeof(char))); res = ensure_allocated(str, cstr_len + str->len + 1, 1);