source: UsbWattMeter/trunk/tlsf-3.0/tlsfbits.h@ 164

Last change on this file since 164 was 164, checked in by coas-nagasima, 6 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-chdr
File size: 4.1 KB
Line 
1#ifndef INCLUDED_tlsfbits
2#define INCLUDED_tlsfbits
3
4#if defined(__cplusplus)
5#define tlsf_decl inline
6#else
7#define tlsf_decl static
8#endif
9
10/*
11** Architecture-specific bit manipulation routines.
12**
13** TLSF achieves O(1) cost for malloc and free operations by limiting
14** the search for a free block to a free list of guaranteed size
15** adequate to fulfill the request, combined with efficient free list
16** queries using bitmasks and architecture-specific bit-manipulation
17** routines.
18**
19** Most modern processors provide instructions to count leading zeroes
20** in a word, find the lowest and highest set bit, etc. These
21** specific implementations will be used when available, falling back
22** to a reasonably efficient generic implementation.
23**
24** NOTE: TLSF spec relies on ffs/fls returning value 0..31.
25** ffs/fls return 1-32 by default, returning 0 for error.
26*/
27
28/*
29** Detect whether or not we are building for a 32- or 64-bit (LP/LLP)
30** architecture. There is no reliable portable method at compile-time.
31*/
32#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \
33 || defined (_WIN64) || defined (__LP64__) || defined (__LLP64__)
34#define TLSF_64BIT
35#endif
36
37/*
38** gcc 3.4 and above have builtin support, specialized for architecture.
39** Some compilers masquerade as gcc; patchlevel test filters them out.
40*/
41#if defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
42 && defined (__GNUC_PATCHLEVEL__)
43
44tlsf_decl int tlsf_ffs(unsigned int word)
45{
46 return __builtin_ffs(word) - 1;
47}
48
49tlsf_decl int tlsf_fls(unsigned int word)
50{
51 const int bit = word ? 32 - __builtin_clz(word) : 0;
52 return bit - 1;
53}
54
55#elif defined (_MSC_VER) && (_MSC_VER >= 1400) && (defined (_M_IX86) || defined (_M_X64))
56/* Microsoft Visual C++ support on x86/X64 architectures. */
57
58#include <intrin.h>
59
60#pragma intrinsic(_BitScanReverse)
61#pragma intrinsic(_BitScanForward)
62
63tlsf_decl int tlsf_fls(unsigned int word)
64{
65 unsigned long index;
66 return _BitScanReverse(&index, word) ? index : -1;
67}
68
69tlsf_decl int tlsf_ffs(unsigned int word)
70{
71 unsigned long index;
72 return _BitScanForward(&index, word) ? index : -1;
73}
74
75#elif defined (_MSC_VER) && defined (_M_PPC)
76/* Microsoft Visual C++ support on PowerPC architectures. */
77
78#include <ppcintrinsics.h>
79
80tlsf_decl int tlsf_fls(unsigned int word)
81{
82 const int bit = 32 - _CountLeadingZeros(word);
83 return bit - 1;
84}
85
86tlsf_decl int tlsf_ffs(unsigned int word)
87{
88 const unsigned int reverse = word & (~word + 1);
89 const int bit = 32 - _CountLeadingZeros(reverse);
90 return bit - 1;
91}
92
93#elif defined (__ARMCC_VERSION)
94/* RealView Compilation Tools for ARM */
95
96tlsf_decl int tlsf_ffs(unsigned int word)
97{
98 const unsigned int reverse = word & (~word + 1);
99 const int bit = 32 - __clz(reverse);
100 return bit - 1;
101}
102
103tlsf_decl int tlsf_fls(unsigned int word)
104{
105 const int bit = word ? 32 - __clz(word) : 0;
106 return bit - 1;
107}
108
109#elif defined (__ghs__)
110/* Green Hills support for PowerPC */
111
112#include <ppc_ghs.h>
113
114tlsf_decl int tlsf_ffs(unsigned int word)
115{
116 const unsigned int reverse = word & (~word + 1);
117 const int bit = 32 - __CLZ32(reverse);
118 return bit - 1;
119}
120
121tlsf_decl int tlsf_fls(unsigned int word)
122{
123 const int bit = word ? 32 - __CLZ32(word) : 0;
124 return bit - 1;
125}
126
127#else
128/* Fall back to generic implementation. */
129
130tlsf_decl int tlsf_fls_generic(unsigned int word)
131{
132 int bit = 32;
133
134 if (!word) bit -= 1;
135 if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; }
136 if (!(word & 0xff000000)) { word <<= 8; bit -= 8; }
137 if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; }
138 if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; }
139 if (!(word & 0x80000000)) { word <<= 1; bit -= 1; }
140
141 return bit;
142}
143
144/* Implement ffs in terms of fls. */
145tlsf_decl int tlsf_ffs(unsigned int word)
146{
147 return tlsf_fls_generic(word & (~word + 1)) - 1;
148}
149
150tlsf_decl int tlsf_fls(unsigned int word)
151{
152 return tlsf_fls_generic(word) - 1;
153}
154
155#endif
156
157/* Possibly 64-bit version of tlsf_fls. */
158#if defined (TLSF_64BIT)
159tlsf_decl int tlsf_fls_sizet(size_t size)
160{
161 int high = (int)(size >> 32);
162 int bits = 0;
163 if (high)
164 {
165 bits = 32 + tlsf_fls(high);
166 }
167 else
168 {
169 bits = tlsf_fls((int)size & 0xffffffff);
170
171 }
172 return bits;
173}
174#else
175#define tlsf_fls_sizet tlsf_fls
176#endif
177
178#undef tlsf_decl
179
180#endif
Note: See TracBrowser for help on using the repository browser.