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