1 martin 1.16 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.17 //
|
3 martin 1.16 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.17 //
|
10 martin 1.16 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.17 //
|
17 martin 1.16 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.17 //
|
20 martin 1.16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.17 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.17 //
|
28 martin 1.16 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #ifndef Pegasus_AtomicInt_h
33 #define Pegasus_AtomicInt_h
34
35 #include <Pegasus/Common/Config.h>
36
|
37 mike 1.9 //==============================================================================
38 //
39 // class AtomicIntTemplate<>
40 //
41 //==============================================================================
|
42 mike 1.2
43 PEGASUS_NAMESPACE_BEGIN
44
45 template<class ATOMIC_TYPE>
46 class AtomicIntTemplate
47 {
48 public:
49
50 // Constructor.
51 AtomicIntTemplate(Uint32 n = 0);
52
53 // Destructor.
54 ~AtomicIntTemplate();
55
56 // Sets value.
57 void set(Uint32 n);
58
59 // Gets value.
60 Uint32 get() const;
61
62 // Increment.
63 mike 1.2 void inc();
64
65 // Decrement.
66 void dec();
67
68 // Decrements and returns true if it is zero.
69 bool decAndTestIfZero();
70
71 // Assignment.
72 AtomicIntTemplate& operator=(Uint32 n) { set(n); return* this; }
73
74 // Post-increment.
75 void operator++(int) { inc(); }
76
77 // Post-decrement.
78 void operator--(int) { dec(); }
79
80 private:
81
82 // Note: These methods are intentionally hidden (and should not be called).
83 // The implementation is much easier without having to implement these for
84 mike 1.2 // every platform.
|
85 kumpf 1.7 AtomicIntTemplate(const AtomicIntTemplate&);
86 AtomicIntTemplate& operator=(const AtomicIntTemplate&);
87 Boolean operator==(Uint32) const;
88 void operator++();
89 void operator--();
|
90 mike 1.2
91 typedef AtomicIntTemplate<ATOMIC_TYPE> This;
92
93 ATOMIC_TYPE _rep;
94 };
95
96 PEGASUS_NAMESPACE_END
97
|
98 mike 1.9 //==============================================================================
99 //
100 // PEGASUS_PLATFORM_LINUX_IX86_GNU
|
101 mike 1.11 // PEGASUS_PLATFORM_DARWIN_IX86_GNU
|
102 mike 1.9 //
103 //==============================================================================
104
|
105 mike 1.11 #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) || \
106 defined(PEGASUS_PLATFORM_DARWIN_IX86_GNU)
|
107 mike 1.9 # define PEGASUS_ATOMIC_INT_DEFINED
108
109 // Note: this lock can be eliminated for single processor systems.
110 # define PEGASUS_ATOMIC_LOCK "lock ; "
111
112 PEGASUS_NAMESPACE_BEGIN
113
114 struct AtomicType
115 {
|
116 kumpf 1.10 volatile int n;
|
117 mike 1.9 };
118
119 PEGASUS_TEMPLATE_SPECIALIZATION
120 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
121 {
122 _rep.n = n;
123 }
124
125 PEGASUS_TEMPLATE_SPECIALIZATION
126 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
127 {
128 }
129
130 PEGASUS_TEMPLATE_SPECIALIZATION
131 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
132 {
133 return _rep.n;
134 }
135
136 PEGASUS_TEMPLATE_SPECIALIZATION
137 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
138 mike 1.9 {
139 _rep.n = n;
140 }
141
142 PEGASUS_TEMPLATE_SPECIALIZATION
143 inline void AtomicIntTemplate<AtomicType>::inc()
144 {
145 asm volatile(
|
146 kumpf 1.10 PEGASUS_ATOMIC_LOCK "incl %0"
147 :"=m" (_rep.n)
148 :"m" (_rep.n));
|
149 mike 1.9 }
150
151 PEGASUS_TEMPLATE_SPECIALIZATION
152 inline void AtomicIntTemplate<AtomicType>::dec()
153 {
154 asm volatile(
155 PEGASUS_ATOMIC_LOCK "decl %0"
156 :"=m" (_rep.n)
157 :"m" (_rep.n));
158 }
159
160 PEGASUS_TEMPLATE_SPECIALIZATION
161 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
162 {
163 unsigned char c;
164
165 asm volatile(
|
166 kumpf 1.10 PEGASUS_ATOMIC_LOCK "decl %0; sete %1"
167 :"=m" (_rep.n), "=qm" (c)
168 :"m" (_rep.n) : "memory");
|
169 mike 1.9
170 return c != 0;
171 }
172
173 typedef AtomicIntTemplate<AtomicType> AtomicInt;
174
175 PEGASUS_NAMESPACE_END
176
177 #endif /* PEGASUS_PLATFORM_LINUX_IX86_GNU */
178
179 //==============================================================================
180 //
181 // PEGASUS_PLATFORM_LINUX_X86_64_GNU
182 //
183 //==============================================================================
184
185 #if defined(PEGASUS_PLATFORM_LINUX_X86_64_GNU)
186 # define PEGASUS_ATOMIC_INT_DEFINED
187
188 // Note: this lock can be eliminated for single processor systems.
189 # define PEGASUS_ATOMIC_LOCK "lock ; "
190 mike 1.9
191 PEGASUS_NAMESPACE_BEGIN
192
193 struct AtomicType
194 {
|
195 kumpf 1.10 volatile int n;
|
196 mike 1.9 };
197
198 PEGASUS_TEMPLATE_SPECIALIZATION
199 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
200 {
201 _rep.n = n;
202 }
203
204 PEGASUS_TEMPLATE_SPECIALIZATION
205 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
206 {
207 }
208
209 PEGASUS_TEMPLATE_SPECIALIZATION
210 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
211 {
212 return _rep.n;
213 }
214
215 PEGASUS_TEMPLATE_SPECIALIZATION
216 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
217 mike 1.9 {
218 _rep.n = n;
219 }
220
221 PEGASUS_TEMPLATE_SPECIALIZATION
222 inline void AtomicIntTemplate<AtomicType>::inc()
223 {
224 asm volatile(
|
225 kumpf 1.10 PEGASUS_ATOMIC_LOCK "incl %0"
226 :"=m" (_rep.n)
227 :"m" (_rep.n));
|
228 mike 1.9 }
229
230 PEGASUS_TEMPLATE_SPECIALIZATION
231 inline void AtomicIntTemplate<AtomicType>::dec()
232 {
233 asm volatile(
234 PEGASUS_ATOMIC_LOCK "decl %0"
235 :"=m" (_rep.n)
236 :"m" (_rep.n));
237 }
238
239 PEGASUS_TEMPLATE_SPECIALIZATION
240 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
241 {
242 unsigned char c;
243
244 asm volatile(
|
245 kumpf 1.10 PEGASUS_ATOMIC_LOCK "decl %0; sete %1"
246 :"=m" (_rep.n), "=qm" (c)
247 :"m" (_rep.n) : "memory");
|
248 mike 1.9
249 return c != 0;
250 }
251
252 typedef AtomicIntTemplate<AtomicType> AtomicInt;
253
254 PEGASUS_NAMESPACE_END
255
256 #endif /* PEGASUS_PLATFORM_LINUX_X86_64_GNU */
257
258 //==============================================================================
259 //
260 // PEGASUS_PLATFORM_LINUX_IA64_GNU
261 //
262 //==============================================================================
263
264 #if defined(PEGASUS_PLATFORM_LINUX_IA64_GNU)
265 # define PEGASUS_ATOMIC_INT_DEFINED
266
267 PEGASUS_NAMESPACE_BEGIN
268
269 mike 1.9 struct AtomicType
270 {
271 volatile int n;
272 };
273
274 PEGASUS_TEMPLATE_SPECIALIZATION
275 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
276 {
277 _rep.n = (int)n;
278 }
279
280 PEGASUS_TEMPLATE_SPECIALIZATION
281 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
282 {
283 // Nothing to do!
284 }
285
286 PEGASUS_TEMPLATE_SPECIALIZATION
287 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
288 {
289 return (Uint32)_rep.n;
290 mike 1.9 }
291
292 PEGASUS_TEMPLATE_SPECIALIZATION
293 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
294 {
295 _rep.n = (int)n;
296 }
297
298 PEGASUS_TEMPLATE_SPECIALIZATION
299 inline void AtomicIntTemplate<AtomicType>::inc()
300 {
301 unsigned long tmp;
302 volatile int* v = &_rep.n;
303
304 asm volatile(
|
305 kumpf 1.10 "fetchadd4.rel %0=[%1],%2"
306 : "=r"(tmp)
307 : "r"(v), "i"(1)
308 : "memory");
|
309 mike 1.9 }
310
311 PEGASUS_TEMPLATE_SPECIALIZATION
312 inline void AtomicIntTemplate<AtomicType>::dec()
313 {
314 unsigned long tmp;
315 volatile int* v = &_rep.n;
316
317 asm volatile(
|
318 kumpf 1.10 "fetchadd4.rel %0=[%1],%2"
319 : "=r"(tmp)
320 : "r"(v), "i"(-1)
321 : "memory");
|
322 mike 1.9 }
323
324 PEGASUS_TEMPLATE_SPECIALIZATION
325 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
326 {
327 unsigned long tmp;
328 volatile int* v = &_rep.n;
329
330 asm volatile(
|
331 kumpf 1.10 "fetchadd4.rel %0=[%1],%2"
332 : "=r"(tmp)
333 : "r"(v), "i"(-1)
334 : "memory");
|
335 mike 1.9
336 return tmp == 1;
337 }
338
339 typedef AtomicIntTemplate<AtomicType> AtomicInt;
340
341 PEGASUS_NAMESPACE_END
342
343 #endif /* PEGASUS_PLATFORM_LINUX_IA64_GNU */
344
345 //==============================================================================
346 //
347 // PEGASUS_PLATFORM_LINUX_PPC_GNU
348 //
349 //==============================================================================
350
351 #if defined(PEGASUS_PLATFORM_LINUX_PPC_GNU)
352 # define PEGASUS_ATOMIC_INT_DEFINED
353
354 PEGASUS_NAMESPACE_BEGIN
355
356 mike 1.9 struct AtomicType
357 {
|
358 kumpf 1.10 volatile Uint32 n;
|
359 mike 1.9 };
360
361 PEGASUS_TEMPLATE_SPECIALIZATION
362 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
363 {
364 _rep.n = n;
365 }
366
367 PEGASUS_TEMPLATE_SPECIALIZATION
368 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
369 {
370 }
371
372 PEGASUS_TEMPLATE_SPECIALIZATION
373 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
374 {
375 return _rep.n;
376 }
377
378 PEGASUS_TEMPLATE_SPECIALIZATION
379 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
380 mike 1.9 {
|
381 venkat.puvvada 1.17.2.1 // sync is required for SMP machines.
382 asm volatile("sync" : : :);
|
383 mike 1.9 _rep.n = n;
384 }
385
386 PEGASUS_TEMPLATE_SPECIALIZATION
387 inline void AtomicIntTemplate<AtomicType>::inc()
388 {
389 int t;
390
391 asm volatile(
|
392 venkat.puvvada 1.17.2.1 "lwsync\n"
393 "1: lwarx %0,0,%1\n"
|
394 kumpf 1.10 "addic %0,%0,1\n"
|
395 venkat.puvvada 1.17.2.1 "stwcx. %0,0,%1\n"
396 "bne- 1b\n"
397 "isync"
398 : "=&r" (t)
399 : "r" (&_rep.n)
400 : "cc", "memory");
|
401 mike 1.9 }
402
403 PEGASUS_TEMPLATE_SPECIALIZATION
404 inline void AtomicIntTemplate<AtomicType>::dec()
405 {
406 int c;
407
408 asm volatile(
|
409 venkat.puvvada 1.17.2.1 "lwsync\n"
|
410 kumpf 1.10 "1: lwarx %0,0,%1\n"
411 "addic %0,%0,-1\n"
412 "stwcx. %0,0,%1\n"
|
413 venkat.puvvada 1.17.2.1 "bne- 1b\n"
414 "isync"
|
415 kumpf 1.10 : "=&r" (c)
416 : "r" (&_rep.n)
417 : "cc", "memory");
|
418 mike 1.9 }
419
420 PEGASUS_TEMPLATE_SPECIALIZATION
421 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
422 {
423 int c;
424
425 asm volatile(
|
426 venkat.puvvada 1.17.2.1 "lwsync\n"
|
427 kumpf 1.10 "1: lwarx %0,0,%1\n"
428 "addic %0,%0,-1\n"
429 "stwcx. %0,0,%1\n"
|
430 venkat.puvvada 1.17.2.1 "bne- 1b\n"
431 "isync"
|
432 kumpf 1.10 : "=&r" (c)
433 : "r" (&_rep.n)
434 : "cc", "memory");
|
435 mike 1.9
436 return c == 0;
437 }
438
439 typedef AtomicIntTemplate<AtomicType> AtomicInt;
440
441 PEGASUS_NAMESPACE_END
442
443 #endif /* PEGASUS_PLATFORM_LINUX_PPC_GNU */
444
445 //==============================================================================
446 //
|
447 a.dunfey 1.12 // PEGASUS_OS_TYPE_WINDOWS
|
448 mike 1.9 //
449 //==============================================================================
450
|
451 a.dunfey 1.12 #if defined(PEGASUS_OS_TYPE_WINDOWS)
|
452 mike 1.9 # define PEGASUS_ATOMIC_INT_DEFINED
453
454 #include <Pegasus/Common/Network.h>
455 #include <windows.h>
456
457 PEGASUS_NAMESPACE_BEGIN
458
459 typedef LONG AtomicType;
460
461 PEGASUS_TEMPLATE_SPECIALIZATION
462 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
463 {
464 _rep = LONG(n);
465 }
466
467 PEGASUS_TEMPLATE_SPECIALIZATION
468 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
469 {
470 }
471
472 PEGASUS_TEMPLATE_SPECIALIZATION
473 mike 1.9 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
474 {
475 return Uint32(_rep);
476 }
477
478 PEGASUS_TEMPLATE_SPECIALIZATION
479 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
480 {
481 _rep = LONG(n);
482 }
483
484 PEGASUS_TEMPLATE_SPECIALIZATION
485 inline void AtomicIntTemplate<AtomicType>::inc()
486 {
487 InterlockedIncrement(&_rep);
488 }
489
490 PEGASUS_TEMPLATE_SPECIALIZATION
491 inline void AtomicIntTemplate<AtomicType>::dec()
492 {
493 InterlockedDecrement(&_rep);
494 mike 1.9 }
495
496 PEGASUS_TEMPLATE_SPECIALIZATION
497 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
498 {
499 return InterlockedDecrement(&_rep) == 0;
500 }
501
502 typedef AtomicIntTemplate<AtomicType> AtomicInt;
503
504 PEGASUS_NAMESPACE_END
505
|
506 a.dunfey 1.12 #endif /* PEGASUS_OS_TYPE_WINDOWS */
|
507 mike 1.9
508 //==============================================================================
509 //
|
510 r.kieninger 1.14 // PEGASUS_OS_ZOS
|
511 mike 1.9 //
512 //==============================================================================
513
|
514 r.kieninger 1.14 #if defined(PEGASUS_OS_ZOS)
|
515 mike 1.9 # define PEGASUS_ATOMIC_INT_DEFINED
516
517 PEGASUS_NAMESPACE_BEGIN
518
519 struct AtomicType
520 {
521 cs_t n;
522 };
523
524 PEGASUS_TEMPLATE_SPECIALIZATION
525 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
526 {
527 _rep.n = (cs_t)n;
528 }
529
530 PEGASUS_TEMPLATE_SPECIALIZATION
531 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
532 {
533 }
534
535 PEGASUS_TEMPLATE_SPECIALIZATION
536 mike 1.9 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
537 {
538 return (Uint32)_rep.n;
539 }
540
541 PEGASUS_TEMPLATE_SPECIALIZATION
542 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
543 {
544 _rep.n = (cs_t)n;
545 }
546
547 PEGASUS_TEMPLATE_SPECIALIZATION
548 inline void AtomicIntTemplate<AtomicType>::inc()
549 {
550 Uint32 x = (Uint32)_rep.n;
551 Uint32 old = x;
552 x++;
553 while ( cs( (cs_t*)&old, &(_rep.n), (cs_t)x) )
554 {
555 x = (Uint32)_rep.n;
556 old = x;
557 mike 1.9 x++;
558 }
559 }
560
561 PEGASUS_TEMPLATE_SPECIALIZATION
562 inline void AtomicIntTemplate<AtomicType>::dec()
563 {
564 Uint32 x = (Uint32)_rep.n;
565 Uint32 old = x;
566 x--;
567 while ( cs( (cs_t*)&old, &(_rep.n), (cs_t) x) )
568 {
569 x = (Uint32) _rep.n;
570 old = x;
571 x--;
572 }
573 }
574
575 PEGASUS_TEMPLATE_SPECIALIZATION
576 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
577 {
578 mike 1.9 Uint32 x = (Uint32)_rep.n;
579 Uint32 old = x;
580 x--;
581 while ( cs( (cs_t*)&old, &(_rep.n), (cs_t) x) )
582 {
583 x = (Uint32) _rep.n;
584 old = x;
585 x--;
586 }
587 return x==0;
588 }
589
590 typedef AtomicIntTemplate<AtomicType> AtomicInt;
591
592 PEGASUS_NAMESPACE_END
593
|
594 r.kieninger 1.14 #endif /* PEGASUS_OS_ZOS */
|
595 mike 1.9
596 //==============================================================================
597 //
598 // PEGASUS_PLATFORM_HPUX_IA64_ACC
599 //
600 //==============================================================================
601
602 #if defined (PEGASUS_PLATFORM_HPUX_IA64_ACC)
603 # define PEGASUS_ATOMIC_INT_DEFINED
604
605 #include <machine/sys/inline.h>
606
607 PEGASUS_NAMESPACE_BEGIN
608
609 struct AtomicType
610 {
611 volatile Uint32 n;
612 };
613
614 PEGASUS_TEMPLATE_SPECIALIZATION
615 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
616 mike 1.9 {
617 _rep.n = n;
618 }
619
620 PEGASUS_TEMPLATE_SPECIALIZATION
621 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
622 {
623 // Nothing to do!
624 }
625
626 PEGASUS_TEMPLATE_SPECIALIZATION
627 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
628 {
629 return _rep.n;
630 }
631
632 PEGASUS_TEMPLATE_SPECIALIZATION
633 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
634 {
635 _rep.n = n;
636 }
637 mike 1.9
638 PEGASUS_TEMPLATE_SPECIALIZATION
639 inline void AtomicIntTemplate<AtomicType>::inc()
640 {
641 _Asm_fetchadd(
|
642 kumpf 1.10 (_Asm_fasz)_FASZ_W,
643 (_Asm_sem)_SEM_ACQ,
644 (volatile Uint32*)&_rep.n,
645 (int)1,
646 (_Asm_ldhint)_LDHINT_NONE);
|
647 mike 1.9 }
648
649 PEGASUS_TEMPLATE_SPECIALIZATION
650 inline void AtomicIntTemplate<AtomicType>::dec()
651 {
652 _Asm_fetchadd(
|
653 kumpf 1.10 (_Asm_fasz)_FASZ_W,
654 (_Asm_sem)_SEM_ACQ,
655 (volatile Uint32*)&_rep.n,
656 (int)-1,
657 (_Asm_ldhint)_LDHINT_NONE);
|
658 mike 1.9 }
659
660 PEGASUS_TEMPLATE_SPECIALIZATION
661 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
662 {
663 Uint32 x = _Asm_fetchadd(
|
664 kumpf 1.10 (_Asm_fasz)_FASZ_W,
665 (_Asm_sem)_SEM_ACQ,
666 (volatile Uint32*)&_rep.n,
667 (int)-1,
668 (_Asm_ldhint)_LDHINT_NONE);
|
669 mike 1.9
670 return x == 1;
671 }
672
673 typedef AtomicIntTemplate<AtomicType> AtomicInt;
674
675 PEGASUS_NAMESPACE_END
676
677 #endif /* PEGASUS_PLATFORM_HPUX_IA64_ACC */
678
679 //==============================================================================
680 //
681 // PEGASUS_PLATFORM_LINUX_XSCALE_GNU
682 //
683 //==============================================================================
684
685 #if defined (PEGASUS_PLATFORM_LINUX_XSCALE_GNU)
686 # define PEGASUS_ATOMIC_INT_DEFINED
687
688 PEGASUS_NAMESPACE_BEGIN
689
690 mike 1.9 inline void AtomicIntDisableIRQs(unsigned long& flags)
691 {
692 unsigned long temp;
693 unsigned long x;
694
695 asm volatile(
|
696 kumpf 1.10 "mrs %0, cpsr\n"
697 "orr %1, %0, #128\n"
698 "msr cpsr_c, %1\n"
699 : "=r" (x), "=r" (temp)
700 :
701 : "memory");
|
702 mike 1.9
703 flags = x;
704 }
705
706 inline void AtomicIntEnableIRQs(unsigned long x)
707 {
708 unsigned long temp;
709
710 asm volatile(
|
711 kumpf 1.10 "mrs %0, cpsr\n"
712 "orr %1, %0, #128\n"
713 "msr cpsr_c, %1\n"
714 : "=r" (x), "=r" (temp)
715 :
716 : "memory");
|
717 mike 1.9 }
718
719 struct AtomicType
720 {
721 volatile Uint32 n;
722 };
723
724 PEGASUS_TEMPLATE_SPECIALIZATION
725 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
726 {
727 _rep.n = n;
728 }
729
730 PEGASUS_TEMPLATE_SPECIALIZATION
731 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
732 {
733 }
734
735 PEGASUS_TEMPLATE_SPECIALIZATION
736 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
737 {
738 mike 1.9 return _rep.n;
739 }
740
741 PEGASUS_TEMPLATE_SPECIALIZATION
742 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
743 {
744 _rep.n = n;
745 }
746
747 PEGASUS_TEMPLATE_SPECIALIZATION
748 inline void AtomicIntTemplate<AtomicType>::inc()
749 {
750 unsigned long flags;
751 AtomicIntDisableIRQs(flags);
752 _rep.n++;
753 AtomicIntEnableIRQs(flags);
754 }
755
756 PEGASUS_TEMPLATE_SPECIALIZATION
757 inline void AtomicIntTemplate<AtomicType>::dec()
758 {
759 mike 1.9 unsigned long flags;
760 AtomicIntDisableIRQs(flags);
761 _rep.n--;
762 AtomicIntEnableIRQs(flags);
763 }
764
765 PEGASUS_TEMPLATE_SPECIALIZATION
766 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
767 {
768 Uint32 tmp;
769 unsigned long flags;
770 AtomicIntDisableIRQs(flags);
771 tmp = --_rep.n;
772 AtomicIntEnableIRQs(flags);
773 return tmp == 0;
774 }
775
776 typedef AtomicIntTemplate<AtomicType> AtomicInt;
777
778 PEGASUS_NAMESPACE_END
779
780 mike 1.9 #endif /* PEGASUS_PLATFORM_LINUX_XSCALE_GNU */
781
782 //==============================================================================
783 //
784 // PEGASUS_PLATFORM_VMS_ALPHA_DECCXX
785 // PEGASUS_PLATFORM_VMS_IA64_DECCXX
786 //
787 //==============================================================================
788
789 #if defined (PEGASUS_PLATFORM_VMS_ALPHA_DECCXX) || \
790 defined (PEGASUS_PLATFORM_VMS_IA64_DECCXX)
791 # define PEGASUS_ATOMIC_INT_DEFINED
792
793 # include <sys/machine/builtins.h>
|
794 mike 1.2
795 PEGASUS_NAMESPACE_BEGIN
796
|
797 mike 1.9 struct AtomicType
798 {
|
799 kumpf 1.10 volatile int n;
|
800 mike 1.9 };
801
802 PEGASUS_TEMPLATE_SPECIALIZATION
803 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
804 {
805 _rep.n = n;
806 }
807
808 PEGASUS_TEMPLATE_SPECIALIZATION
809 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
810 {
811 }
812
813 PEGASUS_TEMPLATE_SPECIALIZATION
814 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
815 {
816 return _rep.n;
817 }
818
819 PEGASUS_TEMPLATE_SPECIALIZATION
820 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
821 mike 1.9 {
822 _rep.n = n;
823 }
824
825 PEGASUS_TEMPLATE_SPECIALIZATION
826 inline void AtomicIntTemplate<AtomicType>::inc()
827 {
828 __ATOMIC_INCREMENT_LONG(&_rep.n);
829 }
830
831 PEGASUS_TEMPLATE_SPECIALIZATION
832 inline void AtomicIntTemplate<AtomicType>::dec()
833 {
834 __ATOMIC_DECREMENT_LONG(&_rep.n);
835 }
836
837 PEGASUS_TEMPLATE_SPECIALIZATION
838 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
839 {
840 return __ATOMIC_DECREMENT_LONG(&_rep.n) == 1;
841 }
842 mike 1.9
|
843 mike 1.2 typedef AtomicIntTemplate<AtomicType> AtomicInt;
844
845 PEGASUS_NAMESPACE_END
846
|
847 mike 1.9 #endif /* _Pegasus_Common_AtomicInt_VMS_h */
848
849 //==============================================================================
850 //
|
851 karl 1.13 // PEGASUS_OS_SOLARIS
852 //
853 //==============================================================================
854
855 #if defined(PEGASUS_OS_SOLARIS)
856 # define PEGASUS_ATOMIC_INT_DEFINED
857
858 #include <atomic.h>
859
860 PEGASUS_NAMESPACE_BEGIN
861
862 struct AtomicType
863 {
864 volatile uint32_t n;
865 };
866
867 PEGASUS_TEMPLATE_SPECIALIZATION
868 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
869 {
870 _rep.n = n;
871 }
872 karl 1.13
873 PEGASUS_TEMPLATE_SPECIALIZATION
874 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
875 {
876 }
877
878 PEGASUS_TEMPLATE_SPECIALIZATION
879 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
880 {
881 return _rep.n;
882 }
883
884 PEGASUS_TEMPLATE_SPECIALIZATION
885 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
886 {
887 _rep.n = n;
888 }
889
890 PEGASUS_TEMPLATE_SPECIALIZATION
891 inline void AtomicIntTemplate<AtomicType>::inc()
892 {
893 karl 1.13 atomic_inc_32(&_rep.n);
894 }
895
896 PEGASUS_TEMPLATE_SPECIALIZATION
897 inline void AtomicIntTemplate<AtomicType>::dec()
898 {
899 atomic_dec_32(&_rep.n);
900 }
901
902 PEGASUS_TEMPLATE_SPECIALIZATION
903 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
904 {
905 return atomic_dec_32_nv(&_rep.n) == 0;
906 }
907
908 typedef AtomicIntTemplate<AtomicType> AtomicInt;
909
910 PEGASUS_NAMESPACE_END
911
912 #endif
913
914 karl 1.13 //==============================================================================
915 //
|
916 cheng.sp 1.15 // PEGASUS_PLATFORM_AIX_RS_IBMCXX
917 //
918 //==============================================================================
919
920 #if defined (PEGASUS_PLATFORM_AIX_RS_IBMCXX)
921 # define PEGASUS_ATOMIC_INT_DEFINED
922
923 # include <sys/atomic_op.h>
924
925 PEGASUS_NAMESPACE_BEGIN
926
927 struct AtomicType
928 {
929 volatile Uint32 n;
930 };
931
932 PEGASUS_TEMPLATE_SPECIALIZATION
933 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
934 {
935 _rep.n = n;
936 }
937 cheng.sp 1.15
938 PEGASUS_TEMPLATE_SPECIALIZATION
939 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
940 {
941 }
942
943 PEGASUS_TEMPLATE_SPECIALIZATION
944 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
945 {
946 return _rep.n;
947 }
948
949 PEGASUS_TEMPLATE_SPECIALIZATION
950 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
951 {
952 _rep.n = n;
953 }
954
955 PEGASUS_TEMPLATE_SPECIALIZATION
956 inline void AtomicIntTemplate<AtomicType>::inc()
957 {
958 cheng.sp 1.15 fetch_and_add((atomic_p)&_rep.n, 1);
959 }
960
961 PEGASUS_TEMPLATE_SPECIALIZATION
962 inline void AtomicIntTemplate<AtomicType>::dec()
963 {
964 fetch_and_add((atomic_p)&_rep.n, -1);
965 }
966
967 PEGASUS_TEMPLATE_SPECIALIZATION
968 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
969 {
970 return fetch_and_add((atomic_p)&_rep.n, -1) == 1;
971 }
972
973 typedef AtomicIntTemplate<AtomicType> AtomicInt;
974
975 PEGASUS_NAMESPACE_END
976
977 #endif /* PEGASUS_PLATFORM_AIX_RS_IBMCXX */
978
979 cheng.sp 1.15
980 //==============================================================================
981 //
|
982 mike 1.9 // Generic Implementation
983 //
984 //==============================================================================
985
986 #if !defined(PEGASUS_ATOMIC_INT_DEFINED)
987 # define PEGASUS_ATOMIC_INT_DEFINED
988
989 # include <Pegasus/Common/SpinLock.h>
990
991 PEGASUS_NAMESPACE_BEGIN
992
993 // Represents the atomic type counter.
994 struct AtomicType
995 {
996 Uint32 n;
997 };
998
999 PEGASUS_TEMPLATE_SPECIALIZATION
1000 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
1001 {
1002 _rep.n = n;
1003 mike 1.9
1004 if (spinLockPoolInitialized == 0)
|
1005 kumpf 1.10 SpinLockCreatePool();
|
1006 mike 1.9 }
1007
1008 PEGASUS_TEMPLATE_SPECIALIZATION
1009 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
1010 {
1011 // Nothing to do.
1012 }
1013
1014 PEGASUS_TEMPLATE_SPECIALIZATION
1015 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
1016 {
1017 Uint32 tmp;
1018 size_t i = SpinLockIndex(&_rep);
1019 SpinLockLock(spinLockPool[i]);
1020 tmp = _rep.n;
1021 SpinLockUnlock(spinLockPool[i]);
1022 return tmp;
1023 }
1024
1025 PEGASUS_TEMPLATE_SPECIALIZATION
1026 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
1027 mike 1.9 {
1028 size_t i = SpinLockIndex(&_rep);
1029 SpinLockLock(spinLockPool[i]);
1030 _rep.n = n;
1031 SpinLockUnlock(spinLockPool[i]);
1032 }
1033
1034 PEGASUS_TEMPLATE_SPECIALIZATION
1035 inline void AtomicIntTemplate<AtomicType>::inc()
1036 {
1037 size_t i = SpinLockIndex(&_rep);
1038 SpinLockLock(spinLockPool[i]);
1039 _rep.n++;
1040 SpinLockUnlock(spinLockPool[i]);
1041 }
1042
1043 PEGASUS_TEMPLATE_SPECIALIZATION
1044 inline void AtomicIntTemplate<AtomicType>::dec()
1045 {
1046 size_t i = SpinLockIndex(&_rep);
1047 SpinLockLock(spinLockPool[i]);
1048 mike 1.9 _rep.n--;
1049 SpinLockUnlock(spinLockPool[i]);
1050 }
1051
1052 PEGASUS_TEMPLATE_SPECIALIZATION
1053 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
1054 {
1055 Uint32 tmp;
1056 size_t i = SpinLockIndex(&_rep);
1057 SpinLockLock(spinLockPool[i]);
1058 tmp = --_rep.n;
1059 SpinLockUnlock(spinLockPool[i]);
1060 return tmp == 0;
1061 }
1062
1063 typedef AtomicIntTemplate<AtomicType> AtomicInt;
1064
1065 PEGASUS_NAMESPACE_END
1066
1067 #endif /* !PEGASUS_ATOMIC_INT_DEFINED */
1068
|
1069 mike 1.2 #endif /* Pegasus_AtomicInt_h */
|