util.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
  3. (c) Copyright 2000-2004 Convergence (integrated media) GmbH
  4. All rights reserved.
  5. Written by Denis Oliver Kropp <dok@directfb.org>,
  6. Andreas Hundt <andi@fischlustig.de>,
  7. Sven Neumann <neo@directfb.org>,
  8. Ville Syrjälä <syrjala@sci.fi> and
  9. Claudio Ciccani <klan@users.sf.net>.
  10. This library is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU Lesser General Public
  12. License as published by the Free Software Foundation; either
  13. version 2 of the License, or (at your option) any later version.
  14. This library is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. Lesser General Public License for more details.
  18. You should have received a copy of the GNU Lesser General Public
  19. License along with this library; if not, write to the
  20. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  21. Boston, MA 02111-1307, USA.
  22. */
  23. #ifndef __DIRECT__UTIL_H__
  24. #define __DIRECT__UTIL_H__
  25. #include <unistd.h>
  26. #ifdef _POSIX_PRIORITY_SCHEDULING
  27. #include <sched.h>
  28. #endif
  29. #include <pthread.h>
  30. #include <direct/debug.h>
  31. #include <direct/messages.h>
  32. #ifndef MIN
  33. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  34. #endif
  35. #ifndef MAX
  36. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  37. #endif
  38. #ifndef SIGN
  39. #define SIGN(x) (((x) < 0) ? -1 : (((x) > 0) ? 1 : 0))
  40. #endif
  41. #ifndef ABS
  42. #define ABS(x) ((x) > 0 ? (x) : -(x))
  43. #endif
  44. #ifndef CLAMP
  45. #define CLAMP(x,min,max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x))
  46. #endif
  47. #ifndef BSWAP16
  48. #define BSWAP16(x) (((u16)(x)>>8) | ((u16)(x)<<8))
  49. #endif
  50. #ifndef BSWAP32
  51. #define BSWAP32(x) ((((u32)(x)>>24) & 0x000000ff) | (((u32)(x)>> 8) & 0x0000ff00) | \
  52. (((u32)(x)<< 8) & 0x00ff0000) | (((u32)(x)<<24) & 0xff000000))
  53. #endif
  54. #define D_FLAGS_SET(flags,f) do { (flags) |= (f); } while (0)
  55. #define D_FLAGS_CLEAR(flags,f) do { (flags) &= ~(f); } while (0)
  56. #define D_FLAGS_IS_SET(flags,f) (((flags) & (f)) != 0)
  57. #define D_FLAGS_ARE_SET(flags,f) (((flags) & (f)) == (f))
  58. #define D_FLAGS_ARE_IN(flags,f) (((flags) & ~(f)) == 0)
  59. #define D_FLAGS_INVALID(flags,f) (((flags) & ~(f)) != 0)
  60. #define D_FLAGS_ASSERT(flags,f) D_ASSERT( D_FLAGS_ARE_IN(flags,f) )
  61. #define D_ARRAY_SIZE(array) ((int)(sizeof(array) / sizeof((array)[0])))
  62. #define D_UTIL_SWAP(a,b) \
  63. do { \
  64. const typeof(a) x = (a); (a) = (b); (b) = x; \
  65. } while (0)
  66. #if __GNUC__ >= 3
  67. #define D_CONST_FUNC __attribute__((const))
  68. #else
  69. #define D_CONST_FUNC
  70. #endif
  71. #define D_BITn32(f) (((f) & 0x00000001) ? 0 : \
  72. ((f) & 0x00000002) ? 1 : \
  73. ((f) & 0x00000004) ? 2 : \
  74. ((f) & 0x00000008) ? 3 : \
  75. ((f) & 0x00000010) ? 4 : \
  76. ((f) & 0x00000020) ? 5 : \
  77. ((f) & 0x00000040) ? 6 : \
  78. ((f) & 0x00000080) ? 7 : \
  79. ((f) & 0x00000100) ? 8 : \
  80. ((f) & 0x00000200) ? 9 : \
  81. ((f) & 0x00000400) ? 10 : \
  82. ((f) & 0x00000800) ? 11 : \
  83. ((f) & 0x00001000) ? 12 : \
  84. ((f) & 0x00002000) ? 13 : \
  85. ((f) & 0x00004000) ? 14 : \
  86. ((f) & 0x00008000) ? 15 : \
  87. ((f) & 0x00010000) ? 16 : \
  88. ((f) & 0x00020000) ? 17 : \
  89. ((f) & 0x00040000) ? 18 : \
  90. ((f) & 0x00080000) ? 19 : \
  91. ((f) & 0x00100000) ? 20 : \
  92. ((f) & 0x00200000) ? 21 : \
  93. ((f) & 0x00400000) ? 22 : \
  94. ((f) & 0x00800000) ? 23 : \
  95. ((f) & 0x01000000) ? 24 : \
  96. ((f) & 0x02000000) ? 25 : \
  97. ((f) & 0x04000000) ? 26 : \
  98. ((f) & 0x08000000) ? 27 : \
  99. ((f) & 0x10000000) ? 28 : \
  100. ((f) & 0x20000000) ? 29 : \
  101. ((f) & 0x40000000) ? 30 : \
  102. ((f) & 0x80000000) ? 31 : -1)
  103. /*
  104. * portable sched_yield() implementation
  105. */
  106. #ifdef _POSIX_PRIORITY_SCHEDULING
  107. #define direct_sched_yield() sched_yield()
  108. #else
  109. #define direct_sched_yield() usleep(1)
  110. #endif
  111. /*
  112. * translates errno to DirectResult
  113. */
  114. DirectResult errno2result( int erno );
  115. const char *DirectResultString( DirectResult result );
  116. /*
  117. * duplicates a file descriptor as needed to ensure it's not stdin, stdout, or stderr
  118. */
  119. int direct_safe_dup( int fd );
  120. int direct_try_open( const char *name1, const char *name2, int flags, bool error_msg );
  121. void direct_trim( char **s );
  122. /*
  123. * Set a string with a maximum size including the zero termination.
  124. *
  125. * This acts like a strncpy(d,s,n), but always terminates the string like snprintf(d,n,"%s",s).
  126. *
  127. * Returns dest or NULL if n is zero.
  128. */
  129. static __inline__ char *
  130. direct_snputs( char *dest,
  131. const char *src,
  132. size_t n )
  133. {
  134. char *start = dest;
  135. D_ASSERT( dest != NULL );
  136. D_ASSERT( src != NULL );
  137. if (!n)
  138. return NULL;
  139. for (; n>1 && *src; n--)
  140. *dest++ = *src++;
  141. *dest = 0;
  142. return start;
  143. }
  144. /*
  145. * Encode/Decode Base-64 strings.
  146. */
  147. char *direct_base64_encode( const void *data, int size );
  148. void *direct_base64_decode( const char *string, int *ret_size );
  149. /*
  150. * Compute MD5 sum (store 16-bytes long result in "dst").
  151. */
  152. void direct_md5_sum( void *dst, const void *src, const int len );
  153. /*
  154. * Slow implementation, but quite fast if only low bits are set.
  155. */
  156. static __inline__ int
  157. direct_util_count_bits( unsigned int mask )
  158. {
  159. register int ret = 0;
  160. while (mask) {
  161. ret += mask & 1;
  162. mask >>= 1;
  163. }
  164. return ret;
  165. }
  166. /*
  167. * Generic alignment routine.
  168. */
  169. static __inline__ int
  170. direct_util_align( int value,
  171. int alignment )
  172. {
  173. if (alignment > 1) {
  174. int tail = value % alignment;
  175. if (tail)
  176. value += alignment - tail;
  177. }
  178. return value;
  179. }
  180. /*
  181. * Utility function to initialize recursive mutexes.
  182. */
  183. int direct_util_recursive_pthread_mutex_init( pthread_mutex_t *mutex );
  184. /* floor and ceil implementation to get rid of libm */
  185. /*
  186. IEEE floor for computers that round to nearest or even.
  187. 'f' must be between -4194304 and 4194303.
  188. This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
  189. but uses some IEEE specific tricks for better speed.
  190. */
  191. static __inline__ int
  192. D_IFLOOR(float f)
  193. {
  194. int ai, bi;
  195. double af, bf;
  196. af = (3 << 22) + 0.5 + (double)f;
  197. bf = (3 << 22) + 0.5 - (double)f;
  198. #if defined(__GNUC__) && defined(__i386__)
  199. /*
  200. GCC generates an extra fstp/fld without this.
  201. */
  202. __asm__ __volatile__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
  203. __asm__ __volatile__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
  204. #else
  205. {
  206. union { int i; float f; } u;
  207. u.f = af; ai = u.i;
  208. u.f = bf; bi = u.i;
  209. }
  210. #endif
  211. return (ai - bi) >> 1;
  212. }
  213. /*
  214. IEEE ceil for computers that round to nearest or even.
  215. 'f' must be between -4194304 and 4194303.
  216. This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
  217. but uses some IEEE specific tricks for better speed.
  218. */
  219. static __inline__ int
  220. D_ICEIL(float f)
  221. {
  222. int ai, bi;
  223. double af, bf;
  224. af = (3 << 22) + 0.5 + (double)f;
  225. bf = (3 << 22) + 0.5 - (double)f;
  226. #if defined(__GNUC__) && defined(__i386__)
  227. /*
  228. GCC generates an extra fstp/fld without this.
  229. */
  230. __asm__ __volatile__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
  231. __asm__ __volatile__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
  232. #else
  233. {
  234. union { int i; float f; } u;
  235. u.f = af; ai = u.i;
  236. u.f = bf; bi = u.i;
  237. }
  238. #endif
  239. return (ai - bi + 1) >> 1;
  240. }
  241. static __inline__ int
  242. direct_log2( int val )
  243. {
  244. register int ret = 0;
  245. while (val >> ++ret);
  246. if ((1 << --ret) < val)
  247. ret++;
  248. return ret;
  249. }
  250. #endif