1 martin 1.16 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // 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 //
10 // 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 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // 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 karl 1.6 //
|
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 _rep.n = n;
382 }
383
384 PEGASUS_TEMPLATE_SPECIALIZATION
385 inline void AtomicIntTemplate<AtomicType>::inc()
386 {
387 int t;
388
389 asm volatile(
|
390 kumpf 1.10 "1: lwarx %0,0,%2\n"
391 "addic %0,%0,1\n"
392 "stwcx. %0,0,%2\n"
393 "bne- 1b"
394 : "=&r" (t), "=m" (_rep.n)
395 : "r" (&_rep.n), "m" (_rep.n)
396 : "cc");
|
397 mike 1.9 }
398
399 PEGASUS_TEMPLATE_SPECIALIZATION
400 inline void AtomicIntTemplate<AtomicType>::dec()
401 {
402 int c;
403
404 asm volatile(
|
405 kumpf 1.10 "1: lwarx %0,0,%1\n"
406 "addic %0,%0,-1\n"
407 "stwcx. %0,0,%1\n"
408 "bne- 1b"
409 : "=&r" (c)
410 : "r" (&_rep.n)
411 : "cc", "memory");
|
412 mike 1.9 }
413
414 PEGASUS_TEMPLATE_SPECIALIZATION
415 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
416 {
417 int c;
418
419 asm volatile(
|
420 kumpf 1.10 "1: lwarx %0,0,%1\n"
421 "addic %0,%0,-1\n"
422 "stwcx. %0,0,%1\n"
423 "bne- 1b"
424 : "=&r" (c)
425 : "r" (&_rep.n)
426 : "cc", "memory");
|
427 mike 1.9
428 return c == 0;
429 }
430
431 typedef AtomicIntTemplate<AtomicType> AtomicInt;
432
433 PEGASUS_NAMESPACE_END
434
435 #endif /* PEGASUS_PLATFORM_LINUX_PPC_GNU */
436
437 //==============================================================================
438 //
|
439 a.dunfey 1.12 // PEGASUS_OS_TYPE_WINDOWS
|
440 mike 1.9 //
441 //==============================================================================
442
|
443 a.dunfey 1.12 #if defined(PEGASUS_OS_TYPE_WINDOWS)
|
444 mike 1.9 # define PEGASUS_ATOMIC_INT_DEFINED
445
446 #include <Pegasus/Common/Network.h>
447 #include <windows.h>
448
449 PEGASUS_NAMESPACE_BEGIN
450
451 typedef LONG AtomicType;
452
453 PEGASUS_TEMPLATE_SPECIALIZATION
454 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
455 {
456 _rep = LONG(n);
457 }
458
459 PEGASUS_TEMPLATE_SPECIALIZATION
460 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
461 {
462 }
463
464 PEGASUS_TEMPLATE_SPECIALIZATION
465 mike 1.9 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
466 {
467 return Uint32(_rep);
468 }
469
470 PEGASUS_TEMPLATE_SPECIALIZATION
471 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
472 {
473 _rep = LONG(n);
474 }
475
476 PEGASUS_TEMPLATE_SPECIALIZATION
477 inline void AtomicIntTemplate<AtomicType>::inc()
478 {
479 InterlockedIncrement(&_rep);
480 }
481
482 PEGASUS_TEMPLATE_SPECIALIZATION
483 inline void AtomicIntTemplate<AtomicType>::dec()
484 {
485 InterlockedDecrement(&_rep);
486 mike 1.9 }
487
488 PEGASUS_TEMPLATE_SPECIALIZATION
489 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
490 {
491 return InterlockedDecrement(&_rep) == 0;
492 }
493
494 typedef AtomicIntTemplate<AtomicType> AtomicInt;
495
496 PEGASUS_NAMESPACE_END
497
|
498 a.dunfey 1.12 #endif /* PEGASUS_OS_TYPE_WINDOWS */
|
499 mike 1.9
500 //==============================================================================
501 //
|
502 r.kieninger 1.14 // PEGASUS_OS_ZOS
|
503 mike 1.9 //
504 //==============================================================================
505
|
506 r.kieninger 1.14 #if defined(PEGASUS_OS_ZOS)
|
507 mike 1.9 # define PEGASUS_ATOMIC_INT_DEFINED
508
509 PEGASUS_NAMESPACE_BEGIN
510
511 struct AtomicType
512 {
513 cs_t n;
514 };
515
516 PEGASUS_TEMPLATE_SPECIALIZATION
517 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
518 {
519 _rep.n = (cs_t)n;
520 }
521
522 PEGASUS_TEMPLATE_SPECIALIZATION
523 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
524 {
525 }
526
527 PEGASUS_TEMPLATE_SPECIALIZATION
528 mike 1.9 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
529 {
530 return (Uint32)_rep.n;
531 }
532
533 PEGASUS_TEMPLATE_SPECIALIZATION
534 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
535 {
536 _rep.n = (cs_t)n;
537 }
538
539 PEGASUS_TEMPLATE_SPECIALIZATION
540 inline void AtomicIntTemplate<AtomicType>::inc()
541 {
542 Uint32 x = (Uint32)_rep.n;
543 Uint32 old = x;
544 x++;
545 while ( cs( (cs_t*)&old, &(_rep.n), (cs_t)x) )
546 {
547 x = (Uint32)_rep.n;
548 old = x;
549 mike 1.9 x++;
550 }
551 }
552
553 PEGASUS_TEMPLATE_SPECIALIZATION
554 inline void AtomicIntTemplate<AtomicType>::dec()
555 {
556 Uint32 x = (Uint32)_rep.n;
557 Uint32 old = x;
558 x--;
559 while ( cs( (cs_t*)&old, &(_rep.n), (cs_t) x) )
560 {
561 x = (Uint32) _rep.n;
562 old = x;
563 x--;
564 }
565 }
566
567 PEGASUS_TEMPLATE_SPECIALIZATION
568 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
569 {
570 mike 1.9 Uint32 x = (Uint32)_rep.n;
571 Uint32 old = x;
572 x--;
573 while ( cs( (cs_t*)&old, &(_rep.n), (cs_t) x) )
574 {
575 x = (Uint32) _rep.n;
576 old = x;
577 x--;
578 }
579 return x==0;
580 }
581
582 typedef AtomicIntTemplate<AtomicType> AtomicInt;
583
584 PEGASUS_NAMESPACE_END
585
|
586 r.kieninger 1.14 #endif /* PEGASUS_OS_ZOS */
|
587 mike 1.9
588 //==============================================================================
589 //
590 // PEGASUS_PLATFORM_HPUX_IA64_ACC
591 //
592 //==============================================================================
593
594 #if defined (PEGASUS_PLATFORM_HPUX_IA64_ACC)
595 # define PEGASUS_ATOMIC_INT_DEFINED
596
597 #include <machine/sys/inline.h>
598
599 PEGASUS_NAMESPACE_BEGIN
600
601 struct AtomicType
602 {
603 volatile Uint32 n;
604 };
605
606 PEGASUS_TEMPLATE_SPECIALIZATION
607 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
608 mike 1.9 {
609 _rep.n = n;
610 }
611
612 PEGASUS_TEMPLATE_SPECIALIZATION
613 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
614 {
615 // Nothing to do!
616 }
617
618 PEGASUS_TEMPLATE_SPECIALIZATION
619 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
620 {
621 return _rep.n;
622 }
623
624 PEGASUS_TEMPLATE_SPECIALIZATION
625 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
626 {
627 _rep.n = n;
628 }
629 mike 1.9
630 PEGASUS_TEMPLATE_SPECIALIZATION
631 inline void AtomicIntTemplate<AtomicType>::inc()
632 {
633 _Asm_fetchadd(
|
634 kumpf 1.10 (_Asm_fasz)_FASZ_W,
635 (_Asm_sem)_SEM_ACQ,
636 (volatile Uint32*)&_rep.n,
637 (int)1,
638 (_Asm_ldhint)_LDHINT_NONE);
|
639 mike 1.9 }
640
641 PEGASUS_TEMPLATE_SPECIALIZATION
642 inline void AtomicIntTemplate<AtomicType>::dec()
643 {
644 _Asm_fetchadd(
|
645 kumpf 1.10 (_Asm_fasz)_FASZ_W,
646 (_Asm_sem)_SEM_ACQ,
647 (volatile Uint32*)&_rep.n,
648 (int)-1,
649 (_Asm_ldhint)_LDHINT_NONE);
|
650 mike 1.9 }
651
652 PEGASUS_TEMPLATE_SPECIALIZATION
653 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
654 {
655 Uint32 x = _Asm_fetchadd(
|
656 kumpf 1.10 (_Asm_fasz)_FASZ_W,
657 (_Asm_sem)_SEM_ACQ,
658 (volatile Uint32*)&_rep.n,
659 (int)-1,
660 (_Asm_ldhint)_LDHINT_NONE);
|
661 mike 1.9
662 return x == 1;
663 }
664
665 typedef AtomicIntTemplate<AtomicType> AtomicInt;
666
667 PEGASUS_NAMESPACE_END
668
669 #endif /* PEGASUS_PLATFORM_HPUX_IA64_ACC */
670
671 //==============================================================================
672 //
673 // PEGASUS_PLATFORM_LINUX_XSCALE_GNU
674 //
675 //==============================================================================
676
677 #if defined (PEGASUS_PLATFORM_LINUX_XSCALE_GNU)
678 # define PEGASUS_ATOMIC_INT_DEFINED
679
680 PEGASUS_NAMESPACE_BEGIN
681
682 mike 1.9 inline void AtomicIntDisableIRQs(unsigned long& flags)
683 {
684 unsigned long temp;
685 unsigned long x;
686
687 asm volatile(
|
688 kumpf 1.10 "mrs %0, cpsr\n"
689 "orr %1, %0, #128\n"
690 "msr cpsr_c, %1\n"
691 : "=r" (x), "=r" (temp)
692 :
693 : "memory");
|
694 mike 1.9
695 flags = x;
696 }
697
698 inline void AtomicIntEnableIRQs(unsigned long x)
699 {
700 unsigned long temp;
701
702 asm volatile(
|
703 kumpf 1.10 "mrs %0, cpsr\n"
704 "orr %1, %0, #128\n"
705 "msr cpsr_c, %1\n"
706 : "=r" (x), "=r" (temp)
707 :
708 : "memory");
|
709 mike 1.9 }
710
711 struct AtomicType
712 {
713 volatile Uint32 n;
714 };
715
716 PEGASUS_TEMPLATE_SPECIALIZATION
717 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
718 {
719 _rep.n = n;
720 }
721
722 PEGASUS_TEMPLATE_SPECIALIZATION
723 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
724 {
725 }
726
727 PEGASUS_TEMPLATE_SPECIALIZATION
728 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
729 {
730 mike 1.9 return _rep.n;
731 }
732
733 PEGASUS_TEMPLATE_SPECIALIZATION
734 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
735 {
736 _rep.n = n;
737 }
738
739 PEGASUS_TEMPLATE_SPECIALIZATION
740 inline void AtomicIntTemplate<AtomicType>::inc()
741 {
742 unsigned long flags;
743 AtomicIntDisableIRQs(flags);
744 _rep.n++;
745 AtomicIntEnableIRQs(flags);
746 }
747
748 PEGASUS_TEMPLATE_SPECIALIZATION
749 inline void AtomicIntTemplate<AtomicType>::dec()
750 {
751 mike 1.9 unsigned long flags;
752 AtomicIntDisableIRQs(flags);
753 _rep.n--;
754 AtomicIntEnableIRQs(flags);
755 }
756
757 PEGASUS_TEMPLATE_SPECIALIZATION
758 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
759 {
760 Uint32 tmp;
761 unsigned long flags;
762 AtomicIntDisableIRQs(flags);
763 tmp = --_rep.n;
764 AtomicIntEnableIRQs(flags);
765 return tmp == 0;
766 }
767
768 typedef AtomicIntTemplate<AtomicType> AtomicInt;
769
770 PEGASUS_NAMESPACE_END
771
772 mike 1.9 #endif /* PEGASUS_PLATFORM_LINUX_XSCALE_GNU */
773
774 //==============================================================================
775 //
776 // PEGASUS_PLATFORM_VMS_ALPHA_DECCXX
777 // PEGASUS_PLATFORM_VMS_IA64_DECCXX
778 //
779 //==============================================================================
780
781 #if defined (PEGASUS_PLATFORM_VMS_ALPHA_DECCXX) || \
782 defined (PEGASUS_PLATFORM_VMS_IA64_DECCXX)
783 # define PEGASUS_ATOMIC_INT_DEFINED
784
785 # include <sys/machine/builtins.h>
|
786 mike 1.2
787 PEGASUS_NAMESPACE_BEGIN
788
|
789 mike 1.9 struct AtomicType
790 {
|
791 kumpf 1.10 volatile int n;
|
792 mike 1.9 };
793
794 PEGASUS_TEMPLATE_SPECIALIZATION
795 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
796 {
797 _rep.n = n;
798 }
799
800 PEGASUS_TEMPLATE_SPECIALIZATION
801 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
802 {
803 }
804
805 PEGASUS_TEMPLATE_SPECIALIZATION
806 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
807 {
808 return _rep.n;
809 }
810
811 PEGASUS_TEMPLATE_SPECIALIZATION
812 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
813 mike 1.9 {
814 _rep.n = n;
815 }
816
817 PEGASUS_TEMPLATE_SPECIALIZATION
818 inline void AtomicIntTemplate<AtomicType>::inc()
819 {
820 __ATOMIC_INCREMENT_LONG(&_rep.n);
821 }
822
823 PEGASUS_TEMPLATE_SPECIALIZATION
824 inline void AtomicIntTemplate<AtomicType>::dec()
825 {
826 __ATOMIC_DECREMENT_LONG(&_rep.n);
827 }
828
829 PEGASUS_TEMPLATE_SPECIALIZATION
830 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
831 {
832 return __ATOMIC_DECREMENT_LONG(&_rep.n) == 1;
833 }
834 mike 1.9
|
835 mike 1.2 typedef AtomicIntTemplate<AtomicType> AtomicInt;
836
837 PEGASUS_NAMESPACE_END
838
|
839 mike 1.9 #endif /* _Pegasus_Common_AtomicInt_VMS_h */
840
841 //==============================================================================
842 //
|
843 karl 1.13 // PEGASUS_OS_SOLARIS
844 //
845 //==============================================================================
846
847 #if defined(PEGASUS_OS_SOLARIS)
848 # define PEGASUS_ATOMIC_INT_DEFINED
849
850 #include <atomic.h>
851
852 PEGASUS_NAMESPACE_BEGIN
853
854 struct AtomicType
855 {
856 volatile uint32_t n;
857 };
858
859 PEGASUS_TEMPLATE_SPECIALIZATION
860 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
861 {
862 _rep.n = n;
863 }
864 karl 1.13
865 PEGASUS_TEMPLATE_SPECIALIZATION
866 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
867 {
868 }
869
870 PEGASUS_TEMPLATE_SPECIALIZATION
871 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
872 {
873 return _rep.n;
874 }
875
876 PEGASUS_TEMPLATE_SPECIALIZATION
877 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
878 {
879 _rep.n = n;
880 }
881
882 PEGASUS_TEMPLATE_SPECIALIZATION
883 inline void AtomicIntTemplate<AtomicType>::inc()
884 {
885 karl 1.13 atomic_inc_32(&_rep.n);
886 }
887
888 PEGASUS_TEMPLATE_SPECIALIZATION
889 inline void AtomicIntTemplate<AtomicType>::dec()
890 {
891 atomic_dec_32(&_rep.n);
892 }
893
894 PEGASUS_TEMPLATE_SPECIALIZATION
895 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
896 {
897 return atomic_dec_32_nv(&_rep.n) == 0;
898 }
899
900 typedef AtomicIntTemplate<AtomicType> AtomicInt;
901
902 PEGASUS_NAMESPACE_END
903
904 #endif
905
906 karl 1.13 //==============================================================================
907 //
|
908 cheng.sp 1.15 // PEGASUS_PLATFORM_AIX_RS_IBMCXX
909 //
910 //==============================================================================
911
912 #if defined (PEGASUS_PLATFORM_AIX_RS_IBMCXX)
913 # define PEGASUS_ATOMIC_INT_DEFINED
914
915 # include <sys/atomic_op.h>
916
917 PEGASUS_NAMESPACE_BEGIN
918
919 struct AtomicType
920 {
921 volatile Uint32 n;
922 };
923
924 PEGASUS_TEMPLATE_SPECIALIZATION
925 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
926 {
927 _rep.n = n;
928 }
929 cheng.sp 1.15
930 PEGASUS_TEMPLATE_SPECIALIZATION
931 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
932 {
933 }
934
935 PEGASUS_TEMPLATE_SPECIALIZATION
936 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
937 {
938 return _rep.n;
939 }
940
941 PEGASUS_TEMPLATE_SPECIALIZATION
942 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
943 {
944 _rep.n = n;
945 }
946
947 PEGASUS_TEMPLATE_SPECIALIZATION
948 inline void AtomicIntTemplate<AtomicType>::inc()
949 {
950 cheng.sp 1.15 fetch_and_add((atomic_p)&_rep.n, 1);
951 }
952
953 PEGASUS_TEMPLATE_SPECIALIZATION
954 inline void AtomicIntTemplate<AtomicType>::dec()
955 {
956 fetch_and_add((atomic_p)&_rep.n, -1);
957 }
958
959 PEGASUS_TEMPLATE_SPECIALIZATION
960 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
961 {
962 return fetch_and_add((atomic_p)&_rep.n, -1) == 1;
963 }
964
965 typedef AtomicIntTemplate<AtomicType> AtomicInt;
966
967 PEGASUS_NAMESPACE_END
968
969 #endif /* PEGASUS_PLATFORM_AIX_RS_IBMCXX */
970
971 cheng.sp 1.15
972 //==============================================================================
973 //
|
974 mike 1.9 // Generic Implementation
975 //
976 //==============================================================================
977
978 #if !defined(PEGASUS_ATOMIC_INT_DEFINED)
979 # define PEGASUS_ATOMIC_INT_DEFINED
980
981 # include <Pegasus/Common/SpinLock.h>
982
983 PEGASUS_NAMESPACE_BEGIN
984
985 // Represents the atomic type counter.
986 struct AtomicType
987 {
988 Uint32 n;
989 };
990
991 PEGASUS_TEMPLATE_SPECIALIZATION
992 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
993 {
994 _rep.n = n;
995 mike 1.9
996 if (spinLockPoolInitialized == 0)
|
997 kumpf 1.10 SpinLockCreatePool();
|
998 mike 1.9 }
999
1000 PEGASUS_TEMPLATE_SPECIALIZATION
1001 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
1002 {
1003 // Nothing to do.
1004 }
1005
1006 PEGASUS_TEMPLATE_SPECIALIZATION
1007 inline Uint32 AtomicIntTemplate<AtomicType>::get() const
1008 {
1009 Uint32 tmp;
1010 size_t i = SpinLockIndex(&_rep);
1011 SpinLockLock(spinLockPool[i]);
1012 tmp = _rep.n;
1013 SpinLockUnlock(spinLockPool[i]);
1014 return tmp;
1015 }
1016
1017 PEGASUS_TEMPLATE_SPECIALIZATION
1018 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
1019 mike 1.9 {
1020 size_t i = SpinLockIndex(&_rep);
1021 SpinLockLock(spinLockPool[i]);
1022 _rep.n = n;
1023 SpinLockUnlock(spinLockPool[i]);
1024 }
1025
1026 PEGASUS_TEMPLATE_SPECIALIZATION
1027 inline void AtomicIntTemplate<AtomicType>::inc()
1028 {
1029 size_t i = SpinLockIndex(&_rep);
1030 SpinLockLock(spinLockPool[i]);
1031 _rep.n++;
1032 SpinLockUnlock(spinLockPool[i]);
1033 }
1034
1035 PEGASUS_TEMPLATE_SPECIALIZATION
1036 inline void AtomicIntTemplate<AtomicType>::dec()
1037 {
1038 size_t i = SpinLockIndex(&_rep);
1039 SpinLockLock(spinLockPool[i]);
1040 mike 1.9 _rep.n--;
1041 SpinLockUnlock(spinLockPool[i]);
1042 }
1043
1044 PEGASUS_TEMPLATE_SPECIALIZATION
1045 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
1046 {
1047 Uint32 tmp;
1048 size_t i = SpinLockIndex(&_rep);
1049 SpinLockLock(spinLockPool[i]);
1050 tmp = --_rep.n;
1051 SpinLockUnlock(spinLockPool[i]);
1052 return tmp == 0;
1053 }
1054
1055 typedef AtomicIntTemplate<AtomicType> AtomicInt;
1056
1057 PEGASUS_NAMESPACE_END
1058
1059 #endif /* !PEGASUS_ATOMIC_INT_DEFINED */
1060
|
1061 mike 1.2 #endif /* Pegasus_AtomicInt_h */
|