0
|
1 |
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
2 |
// All rights reserved.
|
|
3 |
// This component and the accompanying materials are made available
|
|
4 |
// under the terms of the License "Eclipse Public License v1.0"
|
|
5 |
// which accompanies this distribution, and is available
|
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
7 |
//
|
|
8 |
// Initial Contributors:
|
|
9 |
// Nokia Corporation - initial contribution.
|
|
10 |
//
|
|
11 |
// Contributors:
|
|
12 |
//
|
|
13 |
// Description:
|
|
14 |
// e32test\system\t_atomic.h
|
|
15 |
//
|
|
16 |
//
|
|
17 |
|
|
18 |
#include <e32atomics.h>
|
|
19 |
|
|
20 |
#ifdef __VC32__
|
|
21 |
#pragma warning( disable : 4244 ) /* conversion to shorter type - possible loss of data */
|
|
22 |
#endif
|
|
23 |
|
|
24 |
const TInt KMaxThreads = 8;
|
|
25 |
|
|
26 |
#ifdef __KERNEL_MODE__
|
|
27 |
#include <kernel/kernel.h>
|
|
28 |
#undef DEBUGPRINT
|
|
29 |
#define DEBUGPRINT Kern::Printf
|
|
30 |
#else
|
|
31 |
extern void UPrintf(const char*, ...);
|
|
32 |
#undef DEBUGPRINT
|
|
33 |
#define DEBUGPRINT UPrintf
|
|
34 |
#endif
|
|
35 |
|
|
36 |
#undef __INT64_ALIGNED__
|
|
37 |
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__EABI__)
|
|
38 |
#define __INT64_ALIGNED__
|
|
39 |
#endif
|
|
40 |
|
|
41 |
#ifdef __INT64_ALIGNED__
|
|
42 |
typedef TUint64 TUint64A;
|
|
43 |
typedef TInt64 TInt64A;
|
|
44 |
#else
|
|
45 |
|
|
46 |
class TUint64A
|
|
47 |
{
|
|
48 |
public:
|
|
49 |
inline const TUint64* operator&() const
|
|
50 |
{ return ((const TUint64*)((T_UintPtr(this)+7)&~7)); }
|
|
51 |
inline TUint64* operator&()
|
|
52 |
{ return ((TUint64*)((T_UintPtr(this)+7)&~7)); }
|
|
53 |
private:
|
|
54 |
TUint64 i_Data[2];
|
|
55 |
};
|
|
56 |
|
|
57 |
class TInt64A
|
|
58 |
{
|
|
59 |
public:
|
|
60 |
inline const TInt64* operator&() const
|
|
61 |
{ return ((const TInt64*)((T_UintPtr(this)+7)&~7)); }
|
|
62 |
inline TInt64* operator&()
|
|
63 |
{ return ((TInt64*)((T_UintPtr(this)+7)&~7)); }
|
|
64 |
private:
|
|
65 |
TUint64 i_Data[2];
|
|
66 |
};
|
|
67 |
|
|
68 |
#endif
|
|
69 |
|
|
70 |
struct TDGBase
|
|
71 |
{
|
|
72 |
TInt Execute();
|
|
73 |
void Dump(const char*);
|
|
74 |
|
|
75 |
TUint64 i0;
|
|
76 |
TUint64 i1;
|
|
77 |
TUint64 i2;
|
|
78 |
TUint64 i3;
|
|
79 |
TInt iIndex;
|
|
80 |
};
|
|
81 |
|
|
82 |
struct TAtomicAction
|
|
83 |
{
|
|
84 |
TUint64 i0; // first parameter to operation
|
|
85 |
TUint64 i1; // second parameter to operation
|
|
86 |
TUint64 i2; // third parameter to operation
|
|
87 |
TInt iIndex; // index of atomic function
|
|
88 |
TInt iThread; // thread identifier
|
|
89 |
};
|
|
90 |
|
|
91 |
struct TPerThread
|
|
92 |
{
|
|
93 |
TUint64 iDiff; // accumulated difference
|
|
94 |
TUint64 iXor; // accumulated XOR
|
|
95 |
TUint64 iFailCount; // failure count for CAS operations
|
|
96 |
TUint64 iCount; // iteration count
|
|
97 |
};
|
|
98 |
|
|
99 |
extern "C" TInt DoAtomicAction(TAny* aPtr, TPerThread* aT, TAtomicAction& aA);
|
|
100 |
|
|
101 |
enum TMemoryOrder
|
|
102 |
{
|
|
103 |
EOrderRelaxed=0,
|
|
104 |
EOrderAcquire=1,
|
|
105 |
EOrderRelease=2,
|
|
106 |
EOrderOrdered=3,
|
|
107 |
};
|
|
108 |
|
|
109 |
enum TAtomicFunc
|
|
110 |
{
|
|
111 |
EAtomicFuncLOAD=0,
|
|
112 |
EAtomicFuncSTORE=1,
|
|
113 |
EAtomicFuncSWP=2,
|
|
114 |
EAtomicFuncADD=3,
|
|
115 |
EAtomicFuncAND=4,
|
|
116 |
EAtomicFuncIOR=5,
|
|
117 |
EAtomicFuncXOR=6,
|
|
118 |
EAtomicFuncAXO=7,
|
|
119 |
EAtomicFuncTAU=8,
|
|
120 |
EAtomicFuncTAS=9,
|
|
121 |
EAtomicFuncCAS=10,
|
|
122 |
EAtomicFuncN
|
|
123 |
};
|
|
124 |
|
|
125 |
enum TFuncType
|
|
126 |
{
|
|
127 |
EFuncTypeInvalid=0,
|
|
128 |
EFuncTypeLoad=1,
|
|
129 |
EFuncTypeRmw1=2,
|
|
130 |
EFuncTypeRmw2=3,
|
|
131 |
EFuncTypeRmw3=4,
|
|
132 |
EFuncTypeCas=5,
|
|
133 |
};
|
|
134 |
|
|
135 |
#define FUNCS_PER_SIZE (TUint(EAtomicFuncN)*4)
|
|
136 |
#define TOTAL_FUNCS (FUNCS_PER_SIZE*4)
|
|
137 |
#define INDEXES_PER_SIZE (16*4)
|
|
138 |
#define TOTAL_INDEXES (INDEXES_PER_SIZE*4)
|
|
139 |
|
|
140 |
#define FUNCATTR(func,size,ord,type) ((TUint(func)<<24)|(TUint(size)<<16)|(TUint(ord)<<8)|(TUint(type)))
|
|
141 |
#define ATTR_TO_TYPE(attr) ((attr)&0xff)
|
|
142 |
#define ATTR_TO_ORD(attr) (((attr)>>8)&0xff)
|
|
143 |
#define ATTR_TO_SIZE(attr) (((attr)>>16)&0xff)
|
|
144 |
#define ATTR_TO_FUNC(attr) (((attr)>>24)&0xff)
|
|
145 |
#define FUNCATTR2(func,size,type) \
|
|
146 |
FUNCATTR(func,size,EOrderRelaxed,type), FUNCATTR(func,size,EOrderAcquire,type), FUNCATTR(func,size,EOrderRelease,type), FUNCATTR(func,size,EOrderOrdered,type)
|
|
147 |
#define FUNCATTR2A(func,size,type) \
|
|
148 |
0, FUNCATTR(func,size,EOrderAcquire,type), 0, 0
|
|
149 |
#define FUNCATTR2B(func,size,type) \
|
|
150 |
0, 0, FUNCATTR(func,size,EOrderRelease,type), FUNCATTR(func,size,EOrderOrdered,type)
|
|
151 |
#define FUNCATTR3(size) \
|
|
152 |
FUNCATTR2A(EAtomicFuncLOAD,size,EFuncTypeLoad), \
|
|
153 |
FUNCATTR2B(EAtomicFuncSTORE,size,EFuncTypeRmw1), \
|
|
154 |
FUNCATTR2(EAtomicFuncSWP,size,EFuncTypeRmw1), \
|
|
155 |
FUNCATTR2(EAtomicFuncADD,size,EFuncTypeRmw1), \
|
|
156 |
FUNCATTR2(EAtomicFuncAND,size,EFuncTypeRmw1), \
|
|
157 |
FUNCATTR2(EAtomicFuncIOR,size,EFuncTypeRmw1), \
|
|
158 |
FUNCATTR2(EAtomicFuncXOR,size,EFuncTypeRmw1), \
|
|
159 |
FUNCATTR2(EAtomicFuncAXO,size,EFuncTypeRmw2), \
|
|
160 |
FUNCATTR2(EAtomicFuncTAU,size,EFuncTypeRmw3), \
|
|
161 |
FUNCATTR2(EAtomicFuncTAS,size,EFuncTypeRmw3), \
|
|
162 |
FUNCATTR2(EAtomicFuncCAS,size,EFuncTypeCas), \
|
|
163 |
0, 0, 0, 0, \
|
|
164 |
0, 0, 0, 0, \
|
|
165 |
0, 0, 0, 0, \
|
|
166 |
0, 0, 0, 0, \
|
|
167 |
0, 0, 0, 0
|
|
168 |
|
|
169 |
|
|
170 |
#define __DO_STRINGIFY__(x) #x
|
|
171 |
#define __STRINGIFY__(x) __DO_STRINGIFY__(x)
|
|
172 |
#define __concat3__(a,b,c) a##b##c
|
|
173 |
#define __concat5__(a,b,c,d,e) a##b##c##d##e
|
|
174 |
#define FUNCNAME(func,size,ord) __STRINGIFY__(__concat3__(func,size,ord))
|
|
175 |
#define ATOMICFUNC(func,size,ord) __concat5__(__e32_atomic_,func,_,ord,size)
|
|
176 |
#define CONTROLFUNC(func,size,ord) __concat3__(__nonatomic_,func,size)
|
|
177 |
#define FUNCNAME2(func,size) FUNCNAME(func,size,rlx), FUNCNAME(func,size,acq), FUNCNAME(func,size,rel), FUNCNAME(func,size,ord)
|
|
178 |
#define FUNCNAME3(size) \
|
|
179 |
FUNCNAME2(load,size), \
|
|
180 |
FUNCNAME2(store,size), \
|
|
181 |
FUNCNAME2(swp,size), \
|
|
182 |
FUNCNAME2(add,size), \
|
|
183 |
FUNCNAME2(and,size), \
|
|
184 |
FUNCNAME2(ior,size), \
|
|
185 |
FUNCNAME2(xor,size), \
|
|
186 |
FUNCNAME2(axo,size), \
|
|
187 |
FUNCNAME2(tau,size), \
|
|
188 |
FUNCNAME2(tas,size), \
|
|
189 |
FUNCNAME2(cas,size), \
|
|
190 |
"", "", "", "", \
|
|
191 |
"", "", "", "", \
|
|
192 |
"", "", "", "", \
|
|
193 |
"", "", "", "", \
|
|
194 |
"", "", "", ""
|
|
195 |
|
|
196 |
|
|
197 |
#define ATOMICFUNC2(func,size) (PFV)&ATOMICFUNC(func,size,rlx), (PFV)&ATOMICFUNC(func,size,acq), (PFV)&ATOMICFUNC(func,size,rel), (PFV)&ATOMICFUNC(func,size,ord)
|
|
198 |
#define ATOMICFUNC2A(func,size) 0, (PFV)&ATOMICFUNC(func,size,acq), 0, 0
|
|
199 |
#define ATOMICFUNC2B(func,size) 0, 0, (PFV)&ATOMICFUNC(func,size,rel), (PFV)&ATOMICFUNC(func,size,ord)
|
|
200 |
#define ATOMICFUNC3(size) \
|
|
201 |
ATOMICFUNC2A(load,size), \
|
|
202 |
ATOMICFUNC2B(store,size), \
|
|
203 |
ATOMICFUNC2(swp,size), \
|
|
204 |
ATOMICFUNC2(add,size), \
|
|
205 |
ATOMICFUNC2(and,size), \
|
|
206 |
ATOMICFUNC2(ior,size), \
|
|
207 |
ATOMICFUNC2(xor,size), \
|
|
208 |
ATOMICFUNC2(axo,size), \
|
|
209 |
ATOMICFUNC2(tau,size), \
|
|
210 |
ATOMICFUNC2(tas,size), \
|
|
211 |
ATOMICFUNC2(cas,size), \
|
|
212 |
0, 0, 0, 0, \
|
|
213 |
0, 0, 0, 0, \
|
|
214 |
0, 0, 0, 0, \
|
|
215 |
0, 0, 0, 0, \
|
|
216 |
0, 0, 0, 0
|
|
217 |
|
|
218 |
|
|
219 |
#define CONTROLFUNC2(func,size) (PFV)&CONTROLFUNC(func,size,rlx), (PFV)&CONTROLFUNC(func,size,acq), (PFV)&CONTROLFUNC(func,size,rel), (PFV)&CONTROLFUNC(func,size,ord)
|
|
220 |
#define CONTROLFUNC2A(func,size) 0, (PFV)&CONTROLFUNC(func,size,acq), 0, 0
|
|
221 |
#define CONTROLFUNC2B(func,size) 0, 0, (PFV)&CONTROLFUNC(func,size,rel), (PFV)&CONTROLFUNC(func,size,ord)
|
|
222 |
#define CONTROLFUNC3(size) \
|
|
223 |
CONTROLFUNC2A(load,size), \
|
|
224 |
CONTROLFUNC2B(store,size), \
|
|
225 |
CONTROLFUNC2(swp,size), \
|
|
226 |
CONTROLFUNC2(add,size), \
|
|
227 |
CONTROLFUNC2(and,size), \
|
|
228 |
CONTROLFUNC2(ior,size), \
|
|
229 |
CONTROLFUNC2(xor,size), \
|
|
230 |
CONTROLFUNC2(axo,size), \
|
|
231 |
CONTROLFUNC2(tau,size), \
|
|
232 |
CONTROLFUNC2(tas,size), \
|
|
233 |
CONTROLFUNC2(cas,size), \
|
|
234 |
0, 0, 0, 0, \
|
|
235 |
0, 0, 0, 0, \
|
|
236 |
0, 0, 0, 0, \
|
|
237 |
0, 0, 0, 0, \
|
|
238 |
0, 0, 0, 0
|
|
239 |
|
|
240 |
|
|
241 |
#ifdef __INCLUDE_FUNC_NAMES__
|
|
242 |
extern "C" const char* FuncName[] =
|
|
243 |
{
|
|
244 |
FUNCNAME3(8),
|
|
245 |
FUNCNAME3(16),
|
|
246 |
FUNCNAME3(32),
|
|
247 |
FUNCNAME3(64)
|
|
248 |
};
|
|
249 |
#endif
|
|
250 |
|
|
251 |
typedef void (*PFV)();
|
|
252 |
|
|
253 |
#ifdef __INCLUDE_ATOMIC_FUNCTIONS__
|
|
254 |
extern "C" const PFV AtomicFuncPtr[] =
|
|
255 |
{
|
|
256 |
ATOMICFUNC3(8),
|
|
257 |
ATOMICFUNC3(16),
|
|
258 |
ATOMICFUNC3(32),
|
|
259 |
ATOMICFUNC3(64)
|
|
260 |
};
|
|
261 |
#endif
|
|
262 |
|
|
263 |
#ifdef __INCLUDE_CONTROL_FUNCTIONS__
|
|
264 |
extern "C" {
|
|
265 |
|
|
266 |
// Simulated versions of atomic functions without the atomicity
|
|
267 |
extern TUint8 __nonatomic_load8(const volatile TAny* a);
|
|
268 |
extern TUint8 __nonatomic_store8(volatile TAny* a, TUint8 v);
|
|
269 |
extern TUint8 __nonatomic_swp8(volatile TAny* a, TUint8 v);
|
|
270 |
extern TBool __nonatomic_cas8(volatile TAny* a, TUint8* q, TUint8 v);
|
|
271 |
extern TUint8 __nonatomic_add8(volatile TAny* a, TUint8 v);
|
|
272 |
extern TUint8 __nonatomic_and8(volatile TAny* a, TUint8 v);
|
|
273 |
extern TUint8 __nonatomic_ior8(volatile TAny* a, TUint8 v);
|
|
274 |
extern TUint8 __nonatomic_xor8(volatile TAny* a, TUint8 v);
|
|
275 |
extern TUint8 __nonatomic_axo8(volatile TAny* a, TUint8 u, TUint8 v);
|
|
276 |
extern TUint8 __nonatomic_tau8(volatile TAny* a, TUint8 t, TUint8 u, TUint8 v);
|
|
277 |
extern TInt8 __nonatomic_tas8(volatile TAny* a, TInt8 t, TInt8 u, TInt8 v);
|
|
278 |
|
|
279 |
extern TUint16 __nonatomic_load16(const volatile TAny* a);
|
|
280 |
extern TUint16 __nonatomic_store16(volatile TAny* a, TUint16 v);
|
|
281 |
extern TUint16 __nonatomic_swp16(volatile TAny* a, TUint16 v);
|
|
282 |
extern TBool __nonatomic_cas16(volatile TAny* a, TUint16* q, TUint16 v);
|
|
283 |
extern TUint16 __nonatomic_add16(volatile TAny* a, TUint16 v);
|
|
284 |
extern TUint16 __nonatomic_and16(volatile TAny* a, TUint16 v);
|
|
285 |
extern TUint16 __nonatomic_ior16(volatile TAny* a, TUint16 v);
|
|
286 |
extern TUint16 __nonatomic_xor16(volatile TAny* a, TUint16 v);
|
|
287 |
extern TUint16 __nonatomic_axo16(volatile TAny* a, TUint16 u, TUint16 v);
|
|
288 |
extern TUint16 __nonatomic_tau16(volatile TAny* a, TUint16 t, TUint16 u, TUint16 v);
|
|
289 |
extern TInt16 __nonatomic_tas16(volatile TAny* a, TInt16 t, TInt16 u, TInt16 v);
|
|
290 |
|
|
291 |
extern TUint32 __nonatomic_load32(const volatile TAny* a);
|
|
292 |
extern TUint32 __nonatomic_store32(volatile TAny* a, TUint32 v);
|
|
293 |
extern TUint32 __nonatomic_swp32(volatile TAny* a, TUint32 v);
|
|
294 |
extern TBool __nonatomic_cas32(volatile TAny* a, TUint32* q, TUint32 v);
|
|
295 |
extern TUint32 __nonatomic_add32(volatile TAny* a, TUint32 v);
|
|
296 |
extern TUint32 __nonatomic_and32(volatile TAny* a, TUint32 v);
|
|
297 |
extern TUint32 __nonatomic_ior32(volatile TAny* a, TUint32 v);
|
|
298 |
extern TUint32 __nonatomic_xor32(volatile TAny* a, TUint32 v);
|
|
299 |
extern TUint32 __nonatomic_axo32(volatile TAny* a, TUint32 u, TUint32 v);
|
|
300 |
extern TUint32 __nonatomic_tau32(volatile TAny* a, TUint32 t, TUint32 u, TUint32 v);
|
|
301 |
extern TInt32 __nonatomic_tas32(volatile TAny* a, TInt32 t, TInt32 u, TInt32 v);
|
|
302 |
|
|
303 |
extern TUint64 __nonatomic_load64(const volatile TAny* a);
|
|
304 |
extern TUint64 __nonatomic_store64(volatile TAny* a, TUint64 v);
|
|
305 |
extern TUint64 __nonatomic_swp64(volatile TAny* a, TUint64 v);
|
|
306 |
extern TBool __nonatomic_cas64(volatile TAny* a, TUint64* q, TUint64 v);
|
|
307 |
extern TUint64 __nonatomic_add64(volatile TAny* a, TUint64 v);
|
|
308 |
extern TUint64 __nonatomic_and64(volatile TAny* a, TUint64 v);
|
|
309 |
extern TUint64 __nonatomic_ior64(volatile TAny* a, TUint64 v);
|
|
310 |
extern TUint64 __nonatomic_xor64(volatile TAny* a, TUint64 v);
|
|
311 |
extern TUint64 __nonatomic_axo64(volatile TAny* a, TUint64 u, TUint64 v);
|
|
312 |
extern TUint64 __nonatomic_tau64(volatile TAny* a, TUint64 t, TUint64 u, TUint64 v);
|
|
313 |
extern TInt64 __nonatomic_tas64(volatile TAny* a, TInt64 t, TInt64 u, TInt64 v);
|
|
314 |
|
|
315 |
} // extern "C"
|
|
316 |
|
|
317 |
|
|
318 |
extern "C" const PFV ControlFuncPtr[] =
|
|
319 |
{
|
|
320 |
CONTROLFUNC3(8),
|
|
321 |
CONTROLFUNC3(16),
|
|
322 |
CONTROLFUNC3(32),
|
|
323 |
CONTROLFUNC3(64)
|
|
324 |
};
|
|
325 |
#endif
|
|
326 |
|
|
327 |
#ifdef __INCLUDE_FUNCTION_ATTRIBUTES__
|
|
328 |
extern "C" const TUint FuncAttr[] =
|
|
329 |
{
|
|
330 |
FUNCATTR3(1),
|
|
331 |
FUNCATTR3(2),
|
|
332 |
FUNCATTR3(4),
|
|
333 |
FUNCATTR3(8)
|
|
334 |
};
|
|
335 |
#endif
|
|
336 |
|
|
337 |
template<class T>
|
|
338 |
struct TLoadFn // load
|
|
339 |
{
|
|
340 |
typedef T (*F)(const volatile TAny*);
|
|
341 |
};
|
|
342 |
|
|
343 |
template<class T>
|
|
344 |
struct TRmw1Fn // store, swp, add, and, ior, xor
|
|
345 |
{
|
|
346 |
typedef T (*F)(volatile TAny*, T);
|
|
347 |
};
|
|
348 |
|
|
349 |
template<class T>
|
|
350 |
struct TRmw2Fn // axo
|
|
351 |
{
|
|
352 |
typedef T (*F)(volatile TAny*, T, T);
|
|
353 |
};
|
|
354 |
|
|
355 |
template<class T>
|
|
356 |
struct TRmw3Fn // tau, tas
|
|
357 |
{
|
|
358 |
typedef T (*F)(volatile TAny*, T, T, T);
|
|
359 |
};
|
|
360 |
|
|
361 |
template<class T>
|
|
362 |
struct TCasFn // cas
|
|
363 |
{
|
|
364 |
typedef TBool (*F)(volatile TAny*, T*, T);
|
|
365 |
};
|
|
366 |
|
|
367 |
class TEnclosed
|
|
368 |
{
|
|
369 |
public:
|
|
370 |
TEnclosed(TInt aSize);
|
|
371 |
TAny* Ptr();
|
|
372 |
TInt Next();
|
|
373 |
void Init();
|
|
374 |
TInt Verify();
|
|
375 |
TInt Offset() const {return iOffset;}
|
|
376 |
private:
|
|
377 |
TUint64* iData;
|
|
378 |
TUint64* iBackup;
|
|
379 |
TUint64 i_Data[17];
|
|
380 |
TInt iOffset;
|
|
381 |
TInt iSize;
|
|
382 |
};
|
|
383 |
|
|
384 |
template<class T>
|
|
385 |
class Transform
|
|
386 |
{
|
|
387 |
public:
|
|
388 |
inline static T A();
|
|
389 |
inline static T B();
|
|
390 |
static T F(T aOrig); // return Ax+B mod M (M=2^n, n=number of bits in T)
|
|
391 |
static T Pow(T aBase, TUint64 aExp); // return aBase^aExp mod M
|
|
392 |
static T PowerSum(T aBase, TUint64 aExp); // return 1 + T + T^2 + ... + T^(aExp-1) mod M
|
|
393 |
static T F_iter(T aOrig, TUint64 aCount); // return result of applying F iterated aCount times to aOrig
|
|
394 |
};
|
|
395 |
|
|
396 |
TEMPLATE_SPECIALIZATION inline TUint8 Transform<TUint8>::A()
|
|
397 |
{ return 19; }
|
|
398 |
TEMPLATE_SPECIALIZATION inline TUint8 Transform<TUint8>::B()
|
|
399 |
{ return 29; }
|
|
400 |
|
|
401 |
TEMPLATE_SPECIALIZATION inline TUint16 Transform<TUint16>::A()
|
|
402 |
{ return 487; }
|
|
403 |
TEMPLATE_SPECIALIZATION inline TUint16 Transform<TUint16>::B()
|
|
404 |
{ return 12983; }
|
|
405 |
|
|
406 |
TEMPLATE_SPECIALIZATION inline TUint32 Transform<TUint32>::A()
|
|
407 |
{ return 29943829; }
|
|
408 |
TEMPLATE_SPECIALIZATION inline TUint32 Transform<TUint32>::B()
|
|
409 |
{ return 104729; }
|
|
410 |
|
|
411 |
TEMPLATE_SPECIALIZATION inline TUint64 Transform<TUint64>::A()
|
|
412 |
{ return UI64LIT(2862933555777941757); }
|
|
413 |
TEMPLATE_SPECIALIZATION inline TUint64 Transform<TUint64>::B()
|
|
414 |
{ return UI64LIT(104917093); }
|
|
415 |
|
|
416 |
template<class T>
|
|
417 |
T Transform<T>::F(T aOrig)
|
|
418 |
{
|
|
419 |
return (T)(aOrig * Transform<T>::A() + Transform<T>::B());
|
|
420 |
}
|
|
421 |
|
|
422 |
template<class T>
|
|
423 |
T Transform<T>::Pow(T aBase, TUint64 aExp)
|
|
424 |
{
|
|
425 |
T result(1);
|
|
426 |
T multiplier(aBase);
|
|
427 |
while (aExp)
|
|
428 |
{
|
|
429 |
if (aExp&1)
|
|
430 |
result *= multiplier;
|
|
431 |
aExp >>= 1;
|
|
432 |
if (aExp)
|
|
433 |
multiplier *= multiplier;
|
|
434 |
}
|
|
435 |
return (T)result;
|
|
436 |
}
|
|
437 |
|
|
438 |
template<class T>
|
|
439 |
T Transform<T>::PowerSum(T aBase, TUint64 aExp)
|
|
440 |
{
|
|
441 |
T result(0);
|
|
442 |
T multiplier(aBase);
|
|
443 |
T inter(1);
|
|
444 |
while (aExp)
|
|
445 |
{
|
|
446 |
if (aExp&1)
|
|
447 |
{
|
|
448 |
result *= multiplier;
|
|
449 |
result += inter;
|
|
450 |
}
|
|
451 |
aExp >>= 1;
|
|
452 |
if (aExp)
|
|
453 |
{
|
|
454 |
inter *= (multiplier + 1);
|
|
455 |
multiplier *= multiplier;
|
|
456 |
}
|
|
457 |
}
|
|
458 |
return (T)result;
|
|
459 |
}
|
|
460 |
|
|
461 |
template<class T>
|
|
462 |
T Transform<T>::F_iter(T aOrig, TUint64 aCount)
|
|
463 |
{
|
|
464 |
return (T)(Pow(A(),aCount)*aOrig + PowerSum(A(),aCount)*B());
|
|
465 |
}
|
|
466 |
|
|
467 |
|
|
468 |
|
|
469 |
#ifdef __EPOC32__
|
|
470 |
_LIT(KAtomicTestLddName,"D_ATOMIC");
|
|
471 |
|
|
472 |
class RTestAtomic : public RBusLogicalChannel
|
|
473 |
{
|
|
474 |
public:
|
|
475 |
enum TControl
|
|
476 |
{
|
|
477 |
ETDGExecuteK=0,
|
|
478 |
EInitialise=1,
|
|
479 |
ERetrieve=2,
|
|
480 |
ESetCurrentThreadTimeslice=3,
|
|
481 |
ESwitchExecTables=4,
|
|
482 |
EGetKernelMemoryAddress=5,
|
|
483 |
EMaxControl
|
|
484 |
};
|
|
485 |
|
|
486 |
#ifndef __KERNEL_MODE__
|
|
487 |
public:
|
|
488 |
inline TInt Open()
|
|
489 |
{ return DoCreate(KAtomicTestLddName,TVersion(),KNullUnit,NULL,NULL); }
|
|
490 |
public:
|
|
491 |
inline TInt TDGExecuteK(TDGBase& a)
|
|
492 |
{ return DoControl(ETDGExecuteK, &a); }
|
|
493 |
inline TInt Initialise(TUint64 aValue)
|
|
494 |
{ return DoControl(EInitialise, &aValue); }
|
|
495 |
inline TUint64 Retrieve()
|
|
496 |
{ TUint64 x; DoControl(ERetrieve, &x); return x; }
|
|
497 |
inline TInt SetCurrentThreadTimeslice(TInt aTimeslice)
|
|
498 |
{ return DoControl(ESetCurrentThreadTimeslice, (TAny*)aTimeslice); }
|
|
499 |
inline TInt SwitchExecTables(TInt aThread)
|
|
500 |
{ return DoControl(ESwitchExecTables, (TAny*)aThread); }
|
|
501 |
inline TAny* KernelMemoryAddress()
|
|
502 |
{ return (TAny*)DoControl(EGetKernelMemoryAddress); }
|
|
503 |
|
|
504 |
static TInt GetThreadInfo(TPerThread& aInfo);
|
|
505 |
static TInt SetThreadInfo(const TPerThread& aInfo);
|
|
506 |
static TInt AtomicAction(TAtomicAction& aAction);
|
|
507 |
static TInt RestoreExecTable();
|
|
508 |
#endif
|
|
509 |
};
|
|
510 |
#endif
|
|
511 |
|
|
512 |
|