pt-machine.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * sysdeps/microblaze/pt-machine.h -- microblaze-specific pthread definitions
  3. *
  4. * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
  5. * Copyright (C) 2002 NEC Electronics Corporation
  6. * Copyright (C) 2002 Miles Bader <miles@gnu.org>
  7. *
  8. * This file is subject to the terms and conditions of the GNU Lesser
  9. * General Public License. See the file COPYING.LIB in the main
  10. * directory of this archive for more details.
  11. *
  12. * Written by Miles Bader <miles@gnu.org>
  13. */
  14. #ifndef _PT_MACHINE_H
  15. #define _PT_MACHINE_H 1
  16. #include <features.h>
  17. #ifndef PT_EI
  18. # define PT_EI extern inline
  19. #endif
  20. extern long int testandset (int *spinlock);
  21. extern int __compare_and_swap (long *ptr, long old, long new);
  22. /* Get some notion of the current stack. Need not be exactly the top
  23. of the stack, just something somewhere in the current frame. */
  24. #define CURRENT_STACK_FRAME __stack_pointer
  25. register char *__stack_pointer __asm__ ("r1");
  26. #define HAS_COMPARE_AND_SWAP
  27. #define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
  28. #define IMPLEMENT_TAS_WITH_CAS
  29. /* Atomically: If *PTR == OLD, set *PTR to NEW and return true,
  30. otherwise do nothing and return false. */
  31. PT_EI int __compare_and_swap (long *ptr, long old, long new)
  32. {
  33. unsigned long psw;
  34. /* disable interrupts */
  35. /* This is ugly ugly ugly! */
  36. __asm__ __volatile__ ("mfs %0, rmsr;"
  37. "andi r3, %0, ~2;"
  38. "mts rmsr, r3;"
  39. : "=&r" (psw)
  40. :
  41. : "r3");
  42. if (likely (*ptr == old))
  43. {
  44. *ptr = new;
  45. __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */
  46. return 1;
  47. }
  48. else
  49. {
  50. __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */
  51. return 0;
  52. }
  53. }
  54. /* like above's __compare_and_swap() but it first syncs the memory
  55. (This is also the difference between both functions in e.g.
  56. ../powerpc/pt-machine.h)
  57. Doing this additional sync fixes a hang of __pthread_alt_unlock()
  58. (Falk Brettschneider <fbrettschneider@baumeroptronic.de>) */
  59. PT_EI int
  60. __compare_and_swap_with_release_semantics (long *p,
  61. long oldval, long newval)
  62. {
  63. __asm__ __volatile__ ("" : : : "memory"); /*MEMORY_BARRIER ();*/
  64. return __compare_and_swap (p, oldval, newval);
  65. }
  66. #ifndef IMPLEMENT_TAS_WITH_CAS
  67. /* Spinlock implementation; required. */
  68. PT_EI long int testandset (int *spinlock)
  69. {
  70. unsigned psw;
  71. /* disable interrupts */
  72. __asm__ __volatile__ ("mfs %0, rmsr;"
  73. "andi r3, %0, ~2;"
  74. "mts rmsr, r3;"
  75. : "=&r" (psw)
  76. :
  77. : "r3");
  78. if (*spinlock)
  79. {
  80. /* Enable ints */
  81. __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw));
  82. return 1;
  83. } else {
  84. *spinlock=1;
  85. /* Enable ints */
  86. __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw));
  87. return 0;
  88. }
  89. }
  90. #endif
  91. #endif /* pt-machine.h */