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:
|
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 //
|
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 volatile int n;
119 };
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 mike 1.9 }
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 {
141 _rep.n = n;
142 }
143
144 PEGASUS_TEMPLATE_SPECIALIZATION
145 inline void AtomicIntTemplate<AtomicType>::inc()
146 {
147 asm volatile(
148 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 PEGASUS_ATOMIC_LOCK "decl %0; sete %1"
169 :"=m" (_rep.n), "=qm" (c)
170 :"m" (_rep.n) : "memory");
171
172 mike 1.9 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
193 mike 1.9 PEGASUS_NAMESPACE_BEGIN
194
195 struct AtomicType
196 {
197 volatile int n;
198 };
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 mike 1.9 return _rep.n;
215 }
216
217 PEGASUS_TEMPLATE_SPECIALIZATION
218 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
219 {
220 _rep.n = n;
221 }
222
223 PEGASUS_TEMPLATE_SPECIALIZATION
224 inline void AtomicIntTemplate<AtomicType>::inc()
225 {
226 asm volatile(
227 PEGASUS_ATOMIC_LOCK "incl %0"
228 :"=m" (_rep.n)
229 :"m" (_rep.n));
230 }
231
232 PEGASUS_TEMPLATE_SPECIALIZATION
233 inline void AtomicIntTemplate<AtomicType>::dec()
234 {
235 mike 1.9 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 PEGASUS_ATOMIC_LOCK "decl %0; sete %1"
248 :"=m" (_rep.n), "=qm" (c)
249 :"m" (_rep.n) : "memory");
250
251 return c != 0;
252 }
253
254 typedef AtomicIntTemplate<AtomicType> AtomicInt;
255
256 mike 1.9 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 struct AtomicType
272 {
273 volatile int n;
274 };
275
276 PEGASUS_TEMPLATE_SPECIALIZATION
277 mike 1.9 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 }
293
294 PEGASUS_TEMPLATE_SPECIALIZATION
295 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
296 {
297 _rep.n = (int)n;
298 mike 1.9 }
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 "fetchadd4.rel %0=[%1],%2"
308 : "=r"(tmp)
309 : "r"(v), "i"(1)
310 : "memory");
311 }
312
313 PEGASUS_TEMPLATE_SPECIALIZATION
314 inline void AtomicIntTemplate<AtomicType>::dec()
315 {
316 unsigned long tmp;
317 volatile int* v = &_rep.n;
318
319 mike 1.9 asm volatile(
320 "fetchadd4.rel %0=[%1],%2"
321 : "=r"(tmp)
322 : "r"(v), "i"(-1)
323 : "memory");
324 }
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 "fetchadd4.rel %0=[%1],%2"
334 : "=r"(tmp)
335 : "r"(v), "i"(-1)
336 : "memory");
337
338 return tmp == 1;
339 }
340 mike 1.9
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 struct AtomicType
359 {
360 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 "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 }
400
401 PEGASUS_TEMPLATE_SPECIALIZATION
402 inline void AtomicIntTemplate<AtomicType>::dec()
403 mike 1.9 {
404 int c;
405
406 asm volatile(
407 "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 }
415
416 PEGASUS_TEMPLATE_SPECIALIZATION
417 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
418 {
419 int c;
420
421 asm volatile(
422 "1: lwarx %0,0,%1\n"
423 "addic %0,%0,-1\n"
424 mike 1.9 "stwcx. %0,0,%1\n"
425 "bne- 1b"
426 : "=&r" (c)
427 : "r" (&_rep.n)
428 : "cc", "memory");
429
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 // PEGASUS_PLATFORM_WIN32_IX86_MSVC
442 //
443 //==============================================================================
444
445 mike 1.9 #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC)
446 # 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 mike 1.9 PEGASUS_TEMPLATE_SPECIALIZATION
467 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 mike 1.9 InterlockedDecrement(&_rep);
488 }
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 #endif /* PEGASUS_PLATFORM_WIN32_IX86_MSVC */
501
502 //==============================================================================
503 //
504 // PEGASUS_PLATFORM_ZOS_ZSERIES_IBM
505 //
506 //==============================================================================
507
508 mike 1.9 #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 }
523
524 PEGASUS_TEMPLATE_SPECIALIZATION
525 inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
526 {
527 }
528
529 mike 1.9 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 {
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 mike 1.9 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 old = x;
565 x--;
566 }
567 }
568
569 PEGASUS_TEMPLATE_SPECIALIZATION
570 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
571 mike 1.9 {
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
586 PEGASUS_NAMESPACE_END
587
588 #endif /* PEGASUS_PLATFORM_ZOS_ZSERIES_IBM */
589
590 //==============================================================================
591 //
592 mike 1.9 // 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 };
607
608 PEGASUS_TEMPLATE_SPECIALIZATION
609 inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
610 {
611 _rep.n = n;
612 }
613 mike 1.9
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 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 mike 1.9 {
635 _Asm_fetchadd(
636 (_Asm_fasz)_FASZ_W,
637 (_Asm_sem)_SEM_ACQ,
638 (volatile Uint32*)&_rep.n,
639 (int)1,
640 (_Asm_ldhint)_LDHINT_NONE);
641 }
642
643 PEGASUS_TEMPLATE_SPECIALIZATION
644 inline void AtomicIntTemplate<AtomicType>::dec()
645 {
646 _Asm_fetchadd(
647 (_Asm_fasz)_FASZ_W,
648 (_Asm_sem)_SEM_ACQ,
649 (volatile Uint32*)&_rep.n,
650 (int)-1,
651 (_Asm_ldhint)_LDHINT_NONE);
652 }
653
654 PEGASUS_TEMPLATE_SPECIALIZATION
655 mike 1.9 inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
656 {
657 Uint32 x = _Asm_fetchadd(
658 (_Asm_fasz)_FASZ_W,
659 (_Asm_sem)_SEM_ACQ,
660 (volatile Uint32*)&_rep.n,
661 (int)-1,
662 (_Asm_ldhint)_LDHINT_NONE);
663
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 mike 1.9 //
677 //==============================================================================
678
679 #if defined (PEGASUS_PLATFORM_LINUX_XSCALE_GNU)
680 # define PEGASUS_ATOMIC_INT_DEFINED
681
682 PEGASUS_NAMESPACE_BEGIN
683
684 inline void AtomicIntDisableIRQs(unsigned long& flags)
685 {
686 unsigned long temp;
687 unsigned long x;
688
689 asm volatile(
690 "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
697 mike 1.9 flags = x;
698 }
699
700 inline void AtomicIntEnableIRQs(unsigned long x)
701 {
702 unsigned long temp;
703
704 asm volatile(
705 "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 }
712
713 struct AtomicType
714 {
715 volatile Uint32 n;
716 };
717
718 mike 1.9 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 return _rep.n;
733 }
734
735 PEGASUS_TEMPLATE_SPECIALIZATION
736 inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
737 {
738 _rep.n = n;
739 mike 1.9 }
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 unsigned long flags;
754 AtomicIntDisableIRQs(flags);
755 _rep.n--;
756 AtomicIntEnableIRQs(flags);
757 }
758
759 PEGASUS_TEMPLATE_SPECIALIZATION
760 mike 1.9 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 #endif /* PEGASUS_PLATFORM_LINUX_XSCALE_GNU */
775
776 //==============================================================================
777 //
778 // PEGASUS_PLATFORM_VMS_ALPHA_DECCXX
779 // PEGASUS_PLATFORM_VMS_IA64_DECCXX
780 //
781 mike 1.9 //==============================================================================
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>
|