The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/include/atomic.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2008 Marcel Moolenaar
    5  * Copyright (c) 2001 Benno Rice
    6  * Copyright (c) 2001 David E. O'Brien
    7  * Copyright (c) 1998 Doug Rabson
    8  * All rights reserved.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  * $FreeBSD$
   32  */
   33 
   34 #ifndef _MACHINE_ATOMIC_H_
   35 #define _MACHINE_ATOMIC_H_
   36 
   37 #include <sys/atomic_common.h>
   38 
   39 #ifndef __powerpc64__
   40 #include <sys/_atomic64e.h>
   41 #endif
   42 
   43 /*
   44  * The __ATOMIC_REL/ACQ() macros provide memory barriers only in conjunction
   45  * with the atomic lXarx/stXcx. sequences below. They are not exposed outside
   46  * of this file. See also Appendix B.2 of Book II of the architecture manual.
   47  *
   48  * Note that not all Book-E processors accept the light-weight sync variant.
   49  * In particular, early models of E500 cores are known to wedge. Bank on all
   50  * 64-bit capable CPUs to accept lwsync properly and pressimize 32-bit CPUs
   51  * to use the heavier-weight sync.
   52  */
   53 
   54 #ifdef __powerpc64__
   55 #define mb()            __asm __volatile("sync" : : : "memory")
   56 #define rmb()           __asm __volatile("lwsync" : : : "memory")
   57 #define wmb()           __asm __volatile("lwsync" : : : "memory")
   58 #define __ATOMIC_REL()  __asm __volatile("lwsync" : : : "memory")
   59 #define __ATOMIC_ACQ()  __asm __volatile("isync" : : : "memory")
   60 #else
   61 #define mb()            __asm __volatile("sync" : : : "memory")
   62 #define rmb()           __asm __volatile("sync" : : : "memory")
   63 #define wmb()           __asm __volatile("sync" : : : "memory")
   64 #define __ATOMIC_REL()  __asm __volatile("sync" : : : "memory")
   65 #define __ATOMIC_ACQ()  __asm __volatile("isync" : : : "memory")
   66 #endif
   67 
   68 static __inline void
   69 powerpc_lwsync(void)
   70 {
   71 
   72 #ifdef __powerpc64__
   73         __asm __volatile("lwsync" : : : "memory");
   74 #else
   75         __asm __volatile("sync" : : : "memory");
   76 #endif
   77 }
   78 
   79 /*
   80  * atomic_add(p, v)
   81  * { *p += v; }
   82  */
   83 
   84 #define __atomic_add_int(p, v, t)                               \
   85     __asm __volatile(                                           \
   86         "1:     lwarx   %0, 0, %2\n"                            \
   87         "       add     %0, %3, %0\n"                           \
   88         "       stwcx.  %0, 0, %2\n"                            \
   89         "       bne-    1b\n"                                   \
   90         : "=&r" (t), "=m" (*p)                                  \
   91         : "r" (p), "r" (v), "m" (*p)                            \
   92         : "cr0", "memory")                                      \
   93     /* __atomic_add_int */
   94 
   95 #ifdef __powerpc64__
   96 #define __atomic_add_long(p, v, t)                              \
   97     __asm __volatile(                                           \
   98         "1:     ldarx   %0, 0, %2\n"                            \
   99         "       add     %0, %3, %0\n"                           \
  100         "       stdcx.  %0, 0, %2\n"                            \
  101         "       bne-    1b\n"                                   \
  102         : "=&r" (t), "=m" (*p)                                  \
  103         : "r" (p), "r" (v), "m" (*p)                            \
  104         : "cr0", "memory")                                      \
  105     /* __atomic_add_long */
  106 #else
  107 #define __atomic_add_long(p, v, t)                              \
  108     __asm __volatile(                                           \
  109         "1:     lwarx   %0, 0, %2\n"                            \
  110         "       add     %0, %3, %0\n"                           \
  111         "       stwcx.  %0, 0, %2\n"                            \
  112         "       bne-    1b\n"                                   \
  113         : "=&r" (t), "=m" (*p)                                  \
  114         : "r" (p), "r" (v), "m" (*p)                            \
  115         : "cr0", "memory")                                      \
  116     /* __atomic_add_long */
  117 #endif
  118 
  119 #define _ATOMIC_ADD(type)                                       \
  120     static __inline void                                        \
  121     atomic_add_##type(volatile u_##type *p, u_##type v) {       \
  122         u_##type t;                                             \
  123         __atomic_add_##type(p, v, t);                           \
  124     }                                                           \
  125                                                                 \
  126     static __inline void                                        \
  127     atomic_add_acq_##type(volatile u_##type *p, u_##type v) {   \
  128         u_##type t;                                             \
  129         __atomic_add_##type(p, v, t);                           \
  130         __ATOMIC_ACQ();                                         \
  131     }                                                           \
  132                                                                 \
  133     static __inline void                                        \
  134     atomic_add_rel_##type(volatile u_##type *p, u_##type v) {   \
  135         u_##type t;                                             \
  136         __ATOMIC_REL();                                         \
  137         __atomic_add_##type(p, v, t);                           \
  138     }                                                           \
  139     /* _ATOMIC_ADD */
  140 
  141 _ATOMIC_ADD(int)
  142 _ATOMIC_ADD(long)
  143 
  144 #define atomic_add_32           atomic_add_int
  145 #define atomic_add_acq_32       atomic_add_acq_int
  146 #define atomic_add_rel_32       atomic_add_rel_int
  147 
  148 #ifdef __powerpc64__
  149 #define atomic_add_64           atomic_add_long
  150 #define atomic_add_acq_64       atomic_add_acq_long
  151 #define atomic_add_rel_64       atomic_add_rel_long
  152 
  153 #define atomic_add_ptr          atomic_add_long
  154 #define atomic_add_acq_ptr      atomic_add_acq_long
  155 #define atomic_add_rel_ptr      atomic_add_rel_long
  156 #else
  157 #define atomic_add_ptr          atomic_add_int
  158 #define atomic_add_acq_ptr      atomic_add_acq_int
  159 #define atomic_add_rel_ptr      atomic_add_rel_int
  160 #endif
  161 #undef _ATOMIC_ADD
  162 #undef __atomic_add_long
  163 #undef __atomic_add_int
  164 
  165 /*
  166  * atomic_clear(p, v)
  167  * { *p &= ~v; }
  168  */
  169 
  170 #define __atomic_clear_int(p, v, t)                             \
  171     __asm __volatile(                                           \
  172         "1:     lwarx   %0, 0, %2\n"                            \
  173         "       andc    %0, %0, %3\n"                           \
  174         "       stwcx.  %0, 0, %2\n"                            \
  175         "       bne-    1b\n"                                   \
  176         : "=&r" (t), "=m" (*p)                                  \
  177         : "r" (p), "r" (v), "m" (*p)                            \
  178         : "cr0", "memory")                                      \
  179     /* __atomic_clear_int */
  180 
  181 #ifdef __powerpc64__
  182 #define __atomic_clear_long(p, v, t)                            \
  183     __asm __volatile(                                           \
  184         "1:     ldarx   %0, 0, %2\n"                            \
  185         "       andc    %0, %0, %3\n"                           \
  186         "       stdcx.  %0, 0, %2\n"                            \
  187         "       bne-    1b\n"                                   \
  188         : "=&r" (t), "=m" (*p)                                  \
  189         : "r" (p), "r" (v), "m" (*p)                            \
  190         : "cr0", "memory")                                      \
  191     /* __atomic_clear_long */
  192 #else
  193 #define __atomic_clear_long(p, v, t)                            \
  194     __asm __volatile(                                           \
  195         "1:     lwarx   %0, 0, %2\n"                            \
  196         "       andc    %0, %0, %3\n"                           \
  197         "       stwcx.  %0, 0, %2\n"                            \
  198         "       bne-    1b\n"                                   \
  199         : "=&r" (t), "=m" (*p)                                  \
  200         : "r" (p), "r" (v), "m" (*p)                            \
  201         : "cr0", "memory")                                      \
  202     /* __atomic_clear_long */
  203 #endif
  204 
  205 #define _ATOMIC_CLEAR(type)                                     \
  206     static __inline void                                        \
  207     atomic_clear_##type(volatile u_##type *p, u_##type v) {     \
  208         u_##type t;                                             \
  209         __atomic_clear_##type(p, v, t);                         \
  210     }                                                           \
  211                                                                 \
  212     static __inline void                                        \
  213     atomic_clear_acq_##type(volatile u_##type *p, u_##type v) { \
  214         u_##type t;                                             \
  215         __atomic_clear_##type(p, v, t);                         \
  216         __ATOMIC_ACQ();                                         \
  217     }                                                           \
  218                                                                 \
  219     static __inline void                                        \
  220     atomic_clear_rel_##type(volatile u_##type *p, u_##type v) { \
  221         u_##type t;                                             \
  222         __ATOMIC_REL();                                         \
  223         __atomic_clear_##type(p, v, t);                         \
  224     }                                                           \
  225     /* _ATOMIC_CLEAR */
  226 
  227 _ATOMIC_CLEAR(int)
  228 _ATOMIC_CLEAR(long)
  229 
  230 #define atomic_clear_32         atomic_clear_int
  231 #define atomic_clear_acq_32     atomic_clear_acq_int
  232 #define atomic_clear_rel_32     atomic_clear_rel_int
  233 
  234 #ifdef __powerpc64__
  235 #define atomic_clear_64         atomic_clear_long
  236 #define atomic_clear_acq_64     atomic_clear_acq_long
  237 #define atomic_clear_rel_64     atomic_clear_rel_long
  238 
  239 #define atomic_clear_ptr        atomic_clear_long
  240 #define atomic_clear_acq_ptr    atomic_clear_acq_long
  241 #define atomic_clear_rel_ptr    atomic_clear_rel_long
  242 #else
  243 #define atomic_clear_ptr        atomic_clear_int
  244 #define atomic_clear_acq_ptr    atomic_clear_acq_int
  245 #define atomic_clear_rel_ptr    atomic_clear_rel_int
  246 #endif
  247 #undef _ATOMIC_CLEAR
  248 #undef __atomic_clear_long
  249 #undef __atomic_clear_int
  250 
  251 /*
  252  * atomic_cmpset(p, o, n)
  253  */
  254 /* TODO -- see below */
  255 
  256 /*
  257  * atomic_load_acq(p)
  258  */
  259 /* TODO -- see below */
  260 
  261 /*
  262  * atomic_readandclear(p)
  263  */
  264 /* TODO -- see below */
  265 
  266 /*
  267  * atomic_set(p, v)
  268  * { *p |= v; }
  269  */
  270 
  271 #define __atomic_set_int(p, v, t)                               \
  272     __asm __volatile(                                           \
  273         "1:     lwarx   %0, 0, %2\n"                            \
  274         "       or      %0, %3, %0\n"                           \
  275         "       stwcx.  %0, 0, %2\n"                            \
  276         "       bne-    1b\n"                                   \
  277         : "=&r" (t), "=m" (*p)                                  \
  278         : "r" (p), "r" (v), "m" (*p)                            \
  279         : "cr0", "memory")                                      \
  280     /* __atomic_set_int */
  281 
  282 #ifdef __powerpc64__
  283 #define __atomic_set_long(p, v, t)                              \
  284     __asm __volatile(                                           \
  285         "1:     ldarx   %0, 0, %2\n"                            \
  286         "       or      %0, %3, %0\n"                           \
  287         "       stdcx.  %0, 0, %2\n"                            \
  288         "       bne-    1b\n"                                   \
  289         : "=&r" (t), "=m" (*p)                                  \
  290         : "r" (p), "r" (v), "m" (*p)                            \
  291         : "cr0", "memory")                                      \
  292     /* __atomic_set_long */
  293 #else
  294 #define __atomic_set_long(p, v, t)                              \
  295     __asm __volatile(                                           \
  296         "1:     lwarx   %0, 0, %2\n"                            \
  297         "       or      %0, %3, %0\n"                           \
  298         "       stwcx.  %0, 0, %2\n"                            \
  299         "       bne-    1b\n"                                   \
  300         : "=&r" (t), "=m" (*p)                                  \
  301         : "r" (p), "r" (v), "m" (*p)                            \
  302         : "cr0", "memory")                                      \
  303     /* __atomic_set_long */
  304 #endif
  305 
  306 #define _ATOMIC_SET(type)                                       \
  307     static __inline void                                        \
  308     atomic_set_##type(volatile u_##type *p, u_##type v) {       \
  309         u_##type t;                                             \
  310         __atomic_set_##type(p, v, t);                           \
  311     }                                                           \
  312                                                                 \
  313     static __inline void                                        \
  314     atomic_set_acq_##type(volatile u_##type *p, u_##type v) {   \
  315         u_##type t;                                             \
  316         __atomic_set_##type(p, v, t);                           \
  317         __ATOMIC_ACQ();                                         \
  318     }                                                           \
  319                                                                 \
  320     static __inline void                                        \
  321     atomic_set_rel_##type(volatile u_##type *p, u_##type v) {   \
  322         u_##type t;                                             \
  323         __ATOMIC_REL();                                         \
  324         __atomic_set_##type(p, v, t);                           \
  325     }                                                           \
  326     /* _ATOMIC_SET */
  327 
  328 _ATOMIC_SET(int)
  329 _ATOMIC_SET(long)
  330 
  331 #define atomic_set_32           atomic_set_int
  332 #define atomic_set_acq_32       atomic_set_acq_int
  333 #define atomic_set_rel_32       atomic_set_rel_int
  334 
  335 #ifdef __powerpc64__
  336 #define atomic_set_64           atomic_set_long
  337 #define atomic_set_acq_64       atomic_set_acq_long
  338 #define atomic_set_rel_64       atomic_set_rel_long
  339 
  340 #define atomic_set_ptr          atomic_set_long
  341 #define atomic_set_acq_ptr      atomic_set_acq_long
  342 #define atomic_set_rel_ptr      atomic_set_rel_long
  343 #else
  344 #define atomic_set_ptr          atomic_set_int
  345 #define atomic_set_acq_ptr      atomic_set_acq_int
  346 #define atomic_set_rel_ptr      atomic_set_rel_int
  347 #endif
  348 #undef _ATOMIC_SET
  349 #undef __atomic_set_long
  350 #undef __atomic_set_int
  351 
  352 /*
  353  * atomic_subtract(p, v)
  354  * { *p -= v; }
  355  */
  356 
  357 #define __atomic_subtract_int(p, v, t)                          \
  358     __asm __volatile(                                           \
  359         "1:     lwarx   %0, 0, %2\n"                            \
  360         "       subf    %0, %3, %0\n"                           \
  361         "       stwcx.  %0, 0, %2\n"                            \
  362         "       bne-    1b\n"                                   \
  363         : "=&r" (t), "=m" (*p)                                  \
  364         : "r" (p), "r" (v), "m" (*p)                            \
  365         : "cr0", "memory")                                      \
  366     /* __atomic_subtract_int */
  367 
  368 #ifdef __powerpc64__
  369 #define __atomic_subtract_long(p, v, t)                         \
  370     __asm __volatile(                                           \
  371         "1:     ldarx   %0, 0, %2\n"                            \
  372         "       subf    %0, %3, %0\n"                           \
  373         "       stdcx.  %0, 0, %2\n"                            \
  374         "       bne-    1b\n"                                   \
  375         : "=&r" (t), "=m" (*p)                                  \
  376         : "r" (p), "r" (v), "m" (*p)                            \
  377         : "cr0", "memory")                                      \
  378     /* __atomic_subtract_long */
  379 #else
  380 #define __atomic_subtract_long(p, v, t)                         \
  381     __asm __volatile(                                           \
  382         "1:     lwarx   %0, 0, %2\n"                            \
  383         "       subf    %0, %3, %0\n"                           \
  384         "       stwcx.  %0, 0, %2\n"                            \
  385         "       bne-    1b\n"                                   \
  386         : "=&r" (t), "=m" (*p)                                  \
  387         : "r" (p), "r" (v), "m" (*p)                            \
  388         : "cr0", "memory")                                      \
  389     /* __atomic_subtract_long */
  390 #endif
  391 
  392 #define _ATOMIC_SUBTRACT(type)                                          \
  393     static __inline void                                                \
  394     atomic_subtract_##type(volatile u_##type *p, u_##type v) {          \
  395         u_##type t;                                                     \
  396         __atomic_subtract_##type(p, v, t);                              \
  397     }                                                                   \
  398                                                                         \
  399     static __inline void                                                \
  400     atomic_subtract_acq_##type(volatile u_##type *p, u_##type v) {      \
  401         u_##type t;                                                     \
  402         __atomic_subtract_##type(p, v, t);                              \
  403         __ATOMIC_ACQ();                                                 \
  404     }                                                                   \
  405                                                                         \
  406     static __inline void                                                \
  407     atomic_subtract_rel_##type(volatile u_##type *p, u_##type v) {      \
  408         u_##type t;                                                     \
  409         __ATOMIC_REL();                                                 \
  410         __atomic_subtract_##type(p, v, t);                              \
  411     }                                                                   \
  412     /* _ATOMIC_SUBTRACT */
  413 
  414 _ATOMIC_SUBTRACT(int)
  415 _ATOMIC_SUBTRACT(long)
  416 
  417 #define atomic_subtract_32      atomic_subtract_int
  418 #define atomic_subtract_acq_32  atomic_subtract_acq_int
  419 #define atomic_subtract_rel_32  atomic_subtract_rel_int
  420 
  421 #ifdef __powerpc64__
  422 #define atomic_subtract_64      atomic_subtract_long
  423 #define atomic_subtract_acq_64  atomic_subract_acq_long
  424 #define atomic_subtract_rel_64  atomic_subtract_rel_long
  425 
  426 #define atomic_subtract_ptr     atomic_subtract_long
  427 #define atomic_subtract_acq_ptr atomic_subtract_acq_long
  428 #define atomic_subtract_rel_ptr atomic_subtract_rel_long
  429 #else
  430 #define atomic_subtract_ptr     atomic_subtract_int
  431 #define atomic_subtract_acq_ptr atomic_subtract_acq_int
  432 #define atomic_subtract_rel_ptr atomic_subtract_rel_int
  433 #endif
  434 #undef _ATOMIC_SUBTRACT
  435 #undef __atomic_subtract_long
  436 #undef __atomic_subtract_int
  437 
  438 /*
  439  * atomic_store_rel(p, v)
  440  */
  441 /* TODO -- see below */
  442 
  443 /*
  444  * Old/original implementations that still need revisiting.
  445  */
  446 
  447 static __inline u_int
  448 atomic_readandclear_int(volatile u_int *addr)
  449 {
  450         u_int result,temp;
  451 
  452         __asm __volatile (
  453                 "\tsync\n"                      /* drain writes */
  454                 "1:\tlwarx %0, 0, %3\n\t"       /* load old value */
  455                 "li %1, 0\n\t"                  /* load new value */
  456                 "stwcx. %1, 0, %3\n\t"          /* attempt to store */
  457                 "bne- 1b\n\t"                   /* spin if failed */
  458                 : "=&r"(result), "=&r"(temp), "=m" (*addr)
  459                 : "r" (addr), "m" (*addr)
  460                 : "cr0", "memory");
  461 
  462         return (result);
  463 }
  464 
  465 #ifdef __powerpc64__
  466 static __inline u_long
  467 atomic_readandclear_long(volatile u_long *addr)
  468 {
  469         u_long result,temp;
  470 
  471         __asm __volatile (
  472                 "\tsync\n"                      /* drain writes */
  473                 "1:\tldarx %0, 0, %3\n\t"       /* load old value */
  474                 "li %1, 0\n\t"                  /* load new value */
  475                 "stdcx. %1, 0, %3\n\t"          /* attempt to store */
  476                 "bne- 1b\n\t"                   /* spin if failed */
  477                 : "=&r"(result), "=&r"(temp), "=m" (*addr)
  478                 : "r" (addr), "m" (*addr)
  479                 : "cr0", "memory");
  480 
  481         return (result);
  482 }
  483 #endif
  484 
  485 #define atomic_readandclear_32          atomic_readandclear_int
  486 
  487 #ifdef __powerpc64__
  488 #define atomic_readandclear_64          atomic_readandclear_long
  489 
  490 #define atomic_readandclear_ptr         atomic_readandclear_long
  491 #else
  492 static __inline u_long
  493 atomic_readandclear_long(volatile u_long *addr)
  494 {
  495 
  496         return ((u_long)atomic_readandclear_int((volatile u_int *)addr));
  497 }
  498 
  499 #define atomic_readandclear_ptr         atomic_readandclear_int
  500 #endif
  501 
  502 /*
  503  * We assume that a = b will do atomic loads and stores.
  504  */
  505 #define ATOMIC_STORE_LOAD(TYPE)                                 \
  506 static __inline u_##TYPE                                        \
  507 atomic_load_acq_##TYPE(volatile u_##TYPE *p)                    \
  508 {                                                               \
  509         u_##TYPE v;                                             \
  510                                                                 \
  511         v = *p;                                                 \
  512         powerpc_lwsync();                                       \
  513         return (v);                                             \
  514 }                                                               \
  515                                                                 \
  516 static __inline void                                            \
  517 atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)       \
  518 {                                                               \
  519                                                                 \
  520         powerpc_lwsync();                                       \
  521         *p = v;                                                 \
  522 }
  523 
  524 ATOMIC_STORE_LOAD(int)
  525 
  526 #define atomic_load_acq_32      atomic_load_acq_int
  527 #define atomic_store_rel_32     atomic_store_rel_int
  528 
  529 #ifdef __powerpc64__
  530 ATOMIC_STORE_LOAD(long)
  531 
  532 #define atomic_load_acq_64      atomic_load_acq_long
  533 #define atomic_store_rel_64     atomic_store_rel_long
  534 
  535 #define atomic_load_acq_ptr     atomic_load_acq_long
  536 #define atomic_store_rel_ptr    atomic_store_rel_long
  537 #else
  538 static __inline u_long
  539 atomic_load_acq_long(volatile u_long *addr)
  540 {
  541 
  542         return ((u_long)atomic_load_acq_int((volatile u_int *)addr));
  543 }
  544 
  545 static __inline void
  546 atomic_store_rel_long(volatile u_long *addr, u_long val)
  547 {
  548 
  549         atomic_store_rel_int((volatile u_int *)addr, (u_int)val);
  550 }
  551 
  552 #define atomic_load_acq_ptr     atomic_load_acq_int
  553 #define atomic_store_rel_ptr    atomic_store_rel_int
  554 #endif
  555 #undef ATOMIC_STORE_LOAD
  556 
  557 /*
  558  * Atomically compare the value stored at *p with cmpval and if the
  559  * two values are equal, update the value of *p with newval. Returns
  560  * zero if the compare failed, nonzero otherwise.
  561  */
  562 #ifdef ISA_206_ATOMICS
  563 static __inline int
  564 atomic_cmpset_char(volatile u_char *p, u_char cmpval, u_char newval)
  565 {
  566         int     ret;
  567 
  568         __asm __volatile (
  569                 "1:\tlbarx %0, 0, %2\n\t"       /* load old value */
  570                 "cmplw %3, %0\n\t"              /* compare */
  571                 "bne- 2f\n\t"                   /* exit if not equal */
  572                 "stbcx. %4, 0, %2\n\t"          /* attempt to store */
  573                 "bne- 1b\n\t"                   /* spin if failed */
  574                 "li %0, 1\n\t"                  /* success - retval = 1 */
  575                 "b 3f\n\t"                      /* we've succeeded */
  576                 "2:\n\t"
  577                 "stbcx. %0, 0, %2\n\t"          /* clear reservation (74xx) */
  578                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  579                 "3:\n\t"
  580                 : "=&r" (ret), "=m" (*p)
  581                 : "r" (p), "r" (cmpval), "r" (newval), "m" (*p)
  582                 : "cr0", "memory");
  583 
  584         return (ret);
  585 }
  586 
  587 static __inline int
  588 atomic_cmpset_short(volatile u_short *p, u_short cmpval, u_short newval)
  589 {
  590         int     ret;
  591 
  592         __asm __volatile (
  593                 "1:\tlharx %0, 0, %2\n\t"       /* load old value */
  594                 "cmplw %3, %0\n\t"              /* compare */
  595                 "bne- 2f\n\t"                   /* exit if not equal */
  596                 "sthcx. %4, 0, %2\n\t"          /* attempt to store */
  597                 "bne- 1b\n\t"                   /* spin if failed */
  598                 "li %0, 1\n\t"                  /* success - retval = 1 */
  599                 "b 3f\n\t"                      /* we've succeeded */
  600                 "2:\n\t"
  601                 "sthcx. %0, 0, %2\n\t"          /* clear reservation (74xx) */
  602                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  603                 "3:\n\t"
  604                 : "=&r" (ret), "=m" (*p)
  605                 : "r" (p), "r" (cmpval), "r" (newval), "m" (*p)
  606                 : "cr0", "memory");
  607 
  608         return (ret);
  609 }
  610 #else
  611 static __inline int
  612 atomic_cmpset_masked(uint32_t *p, uint32_t cmpval, uint32_t newval,
  613     uint32_t mask)
  614 {
  615         int             ret;
  616         uint32_t        tmp;
  617 
  618         __asm __volatile (
  619                 "1:\tlwarx %2, 0, %3\n\t"       /* load old value */
  620                 "and %0, %2, %7\n\t"
  621                 "cmplw %4, %0\n\t"              /* compare */
  622                 "bne- 2f\n\t"                   /* exit if not equal */
  623                 "andc %2, %2, %7\n\t"
  624                 "or %2, %2, %5\n\t"
  625                 "stwcx. %2, 0, %3\n\t"          /* attempt to store */
  626                 "bne- 1b\n\t"                   /* spin if failed */
  627                 "li %0, 1\n\t"                  /* success - retval = 1 */
  628                 "b 3f\n\t"                      /* we've succeeded */
  629                 "2:\n\t"
  630                 "stwcx. %2, 0, %3\n\t"          /* clear reservation (74xx) */
  631                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  632                 "3:\n\t"
  633                 : "=&r" (ret), "=m" (*p), "+&r" (tmp)
  634                 : "r" (p), "r" (cmpval), "r" (newval), "m" (*p),
  635                   "r" (mask)
  636                 : "cr0", "memory");
  637 
  638         return (ret);
  639 }
  640 
  641 #define _atomic_cmpset_masked_word(a,o,v,m) atomic_cmpset_masked(a, o, v, m)
  642 #endif
  643 
  644 static __inline int
  645 atomic_cmpset_int(volatile u_int* p, u_int cmpval, u_int newval)
  646 {
  647         int     ret;
  648 
  649         __asm __volatile (
  650                 "1:\tlwarx %0, 0, %2\n\t"       /* load old value */
  651                 "cmplw %3, %0\n\t"              /* compare */
  652                 "bne- 2f\n\t"                   /* exit if not equal */
  653                 "stwcx. %4, 0, %2\n\t"          /* attempt to store */
  654                 "bne- 1b\n\t"                   /* spin if failed */
  655                 "li %0, 1\n\t"                  /* success - retval = 1 */
  656                 "b 3f\n\t"                      /* we've succeeded */
  657                 "2:\n\t"
  658                 "stwcx. %0, 0, %2\n\t"          /* clear reservation (74xx) */
  659                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  660                 "3:\n\t"
  661                 : "=&r" (ret), "=m" (*p)
  662                 : "r" (p), "r" (cmpval), "r" (newval), "m" (*p)
  663                 : "cr0", "memory");
  664 
  665         return (ret);
  666 }
  667 static __inline int
  668 atomic_cmpset_long(volatile u_long* p, u_long cmpval, u_long newval)
  669 {
  670         int ret;
  671 
  672         __asm __volatile (
  673             #ifdef __powerpc64__
  674                 "1:\tldarx %0, 0, %2\n\t"       /* load old value */
  675                 "cmpld %3, %0\n\t"              /* compare */
  676                 "bne- 2f\n\t"                   /* exit if not equal */
  677                 "stdcx. %4, 0, %2\n\t"          /* attempt to store */
  678             #else
  679                 "1:\tlwarx %0, 0, %2\n\t"       /* load old value */
  680                 "cmplw %3, %0\n\t"              /* compare */
  681                 "bne- 2f\n\t"                   /* exit if not equal */
  682                 "stwcx. %4, 0, %2\n\t"          /* attempt to store */
  683             #endif
  684                 "bne- 1b\n\t"                   /* spin if failed */
  685                 "li %0, 1\n\t"                  /* success - retval = 1 */
  686                 "b 3f\n\t"                      /* we've succeeded */
  687                 "2:\n\t"
  688             #ifdef __powerpc64__
  689                 "stdcx. %0, 0, %2\n\t"          /* clear reservation (74xx) */
  690             #else
  691                 "stwcx. %0, 0, %2\n\t"          /* clear reservation (74xx) */
  692             #endif
  693                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  694                 "3:\n\t"
  695                 : "=&r" (ret), "=m" (*p)
  696                 : "r" (p), "r" (cmpval), "r" (newval), "m" (*p)
  697                 : "cr0", "memory");
  698 
  699         return (ret);
  700 }
  701 
  702 #define ATOMIC_CMPSET_ACQ_REL(type) \
  703     static __inline int \
  704     atomic_cmpset_acq_##type(volatile u_##type *p, \
  705             u_##type cmpval, u_##type newval)\
  706     {\
  707         u_##type retval; \
  708         retval = atomic_cmpset_##type(p, cmpval, newval);\
  709         __ATOMIC_ACQ();\
  710         return (retval);\
  711     }\
  712     static __inline int \
  713     atomic_cmpset_rel_##type(volatile u_##type *p, \
  714             u_##type cmpval, u_##type newval)\
  715     {\
  716         __ATOMIC_REL();\
  717         return (atomic_cmpset_##type(p, cmpval, newval));\
  718     }\
  719     struct hack
  720 
  721 ATOMIC_CMPSET_ACQ_REL(int);
  722 ATOMIC_CMPSET_ACQ_REL(long);
  723 
  724 #ifdef ISA_206_ATOMICS
  725 #define atomic_cmpset_8         atomic_cmpset_char
  726 #endif
  727 #define atomic_cmpset_acq_8     atomic_cmpset_acq_char
  728 #define atomic_cmpset_rel_8     atomic_cmpset_rel_char
  729 
  730 #ifdef ISA_206_ATOMICS
  731 #define atomic_cmpset_16        atomic_cmpset_short
  732 #endif
  733 #define atomic_cmpset_acq_16    atomic_cmpset_acq_short
  734 #define atomic_cmpset_rel_16    atomic_cmpset_rel_short
  735 
  736 #define atomic_cmpset_32        atomic_cmpset_int
  737 #define atomic_cmpset_acq_32    atomic_cmpset_acq_int
  738 #define atomic_cmpset_rel_32    atomic_cmpset_rel_int
  739 
  740 #ifdef __powerpc64__
  741 #define atomic_cmpset_64        atomic_cmpset_long
  742 #define atomic_cmpset_acq_64    atomic_cmpset_acq_long
  743 #define atomic_cmpset_rel_64    atomic_cmpset_rel_long
  744 
  745 #define atomic_cmpset_ptr       atomic_cmpset_long
  746 #define atomic_cmpset_acq_ptr   atomic_cmpset_acq_long
  747 #define atomic_cmpset_rel_ptr   atomic_cmpset_rel_long
  748 #else
  749 #define atomic_cmpset_ptr       atomic_cmpset_int
  750 #define atomic_cmpset_acq_ptr   atomic_cmpset_acq_int
  751 #define atomic_cmpset_rel_ptr   atomic_cmpset_rel_int
  752 #endif
  753 
  754 /*
  755  * Atomically compare the value stored at *p with *cmpval and if the
  756  * two values are equal, update the value of *p with newval. Returns
  757  * zero if the compare failed and sets *cmpval to the read value from *p,
  758  * nonzero otherwise.
  759  */
  760 #ifdef ISA_206_ATOMICS
  761 static __inline int
  762 atomic_fcmpset_char(volatile u_char *p, u_char *cmpval, u_char newval)
  763 {
  764         int     ret;
  765 
  766         __asm __volatile (
  767                 "lbarx %0, 0, %3\n\t"           /* load old value */
  768                 "cmplw %4, %0\n\t"              /* compare */
  769                 "bne- 1f\n\t"                   /* exit if not equal */
  770                 "stbcx. %5, 0, %3\n\t"          /* attempt to store */
  771                 "bne- 1f\n\t"                   /* exit if failed */
  772                 "li %0, 1\n\t"                  /* success - retval = 1 */
  773                 "b 2f\n\t"                      /* we've succeeded */
  774                 "1:\n\t"
  775                 "stbcx. %0, 0, %3\n\t"          /* clear reservation (74xx) */
  776                 "stbx %0, 0, %7\n\t"
  777                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  778                 "2:\n\t"
  779                 : "=&r" (ret), "=m" (*p), "=m" (*cmpval)
  780                 : "r" (p), "r" (*cmpval), "r" (newval), "m" (*p), "r"(cmpval)
  781                 : "cr0", "memory");
  782 
  783         return (ret);
  784 }
  785 
  786 static __inline int
  787 atomic_fcmpset_short(volatile u_short *p, u_short *cmpval, u_short newval)
  788 {
  789         int     ret;
  790 
  791         __asm __volatile (
  792                 "lharx %0, 0, %3\n\t"           /* load old value */
  793                 "cmplw %4, %0\n\t"              /* compare */
  794                 "bne- 1f\n\t"                   /* exit if not equal */
  795                 "sthcx. %5, 0, %3\n\t"          /* attempt to store */
  796                 "bne- 1f\n\t"                   /* exit if failed */
  797                 "li %0, 1\n\t"                  /* success - retval = 1 */
  798                 "b 2f\n\t"                      /* we've succeeded */
  799                 "1:\n\t"
  800                 "sthcx. %0, 0, %3\n\t"          /* clear reservation (74xx) */
  801                 "sthx %0, 0, %7\n\t"
  802                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  803                 "2:\n\t"
  804                 : "=&r" (ret), "=m" (*p), "=m" (*cmpval)
  805                 : "r" (p), "r" (*cmpval), "r" (newval), "m" (*p), "r"(cmpval)
  806                 : "cr0", "memory");
  807 
  808         return (ret);
  809 }
  810 #endif  /* ISA_206_ATOMICS */
  811 
  812 static __inline int
  813 atomic_fcmpset_int(volatile u_int *p, u_int *cmpval, u_int newval)
  814 {
  815         int     ret;
  816 
  817         __asm __volatile (
  818                 "lwarx %0, 0, %3\n\t"           /* load old value */
  819                 "cmplw %4, %0\n\t"              /* compare */
  820                 "bne- 1f\n\t"                   /* exit if not equal */
  821                 "stwcx. %5, 0, %3\n\t"          /* attempt to store */
  822                 "bne- 1f\n\t"                   /* exit if failed */
  823                 "li %0, 1\n\t"                  /* success - retval = 1 */
  824                 "b 2f\n\t"                      /* we've succeeded */
  825                 "1:\n\t"
  826                 "stwcx. %0, 0, %3\n\t"          /* clear reservation (74xx) */
  827                 "stwx %0, 0, %7\n\t"
  828                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  829                 "2:\n\t"
  830                 : "=&r" (ret), "=m" (*p), "=m" (*cmpval)
  831                 : "r" (p), "r" (*cmpval), "r" (newval), "m" (*p), "r"(cmpval)
  832                 : "cr0", "memory");
  833 
  834         return (ret);
  835 }
  836 static __inline int
  837 atomic_fcmpset_long(volatile u_long *p, u_long *cmpval, u_long newval)
  838 {
  839         int ret;
  840 
  841         __asm __volatile (
  842             #ifdef __powerpc64__
  843                 "ldarx %0, 0, %3\n\t"           /* load old value */
  844                 "cmpld %4, %0\n\t"              /* compare */
  845                 "bne- 1f\n\t"                   /* exit if not equal */
  846                 "stdcx. %5, 0, %3\n\t"          /* attempt to store */
  847             #else
  848                 "lwarx %0, 0, %3\n\t"           /* load old value */
  849                 "cmplw %4, %0\n\t"              /* compare */
  850                 "bne- 1f\n\t"                   /* exit if not equal */
  851                 "stwcx. %5, 0, %3\n\t"          /* attempt to store */
  852             #endif
  853                 "bne- 1f\n\t"                   /* exit if failed */
  854                 "li %0, 1\n\t"                  /* success - retval = 1 */
  855                 "b 2f\n\t"                      /* we've succeeded */
  856                 "1:\n\t"
  857             #ifdef __powerpc64__
  858                 "stdcx. %0, 0, %3\n\t"          /* clear reservation (74xx) */
  859                 "stdx %0, 0, %7\n\t"
  860             #else
  861                 "stwcx. %0, 0, %3\n\t"          /* clear reservation (74xx) */
  862                 "stwx %0, 0, %7\n\t"
  863             #endif
  864                 "li %0, 0\n\t"                  /* failure - retval = 0 */
  865                 "2:\n\t"
  866                 : "=&r" (ret), "=m" (*p), "=m" (*cmpval)
  867                 : "r" (p), "r" (*cmpval), "r" (newval), "m" (*p), "r"(cmpval)
  868                 : "cr0", "memory");
  869 
  870         return (ret);
  871 }
  872 
  873 #define ATOMIC_FCMPSET_ACQ_REL(type) \
  874     static __inline int \
  875     atomic_fcmpset_acq_##type(volatile u_##type *p, \
  876             u_##type *cmpval, u_##type newval)\
  877     {\
  878         u_##type retval; \
  879         retval = atomic_fcmpset_##type(p, cmpval, newval);\
  880         __ATOMIC_ACQ();\
  881         return (retval);\
  882     }\
  883     static __inline int \
  884     atomic_fcmpset_rel_##type(volatile u_##type *p, \
  885             u_##type *cmpval, u_##type newval)\
  886     {\
  887         __ATOMIC_REL();\
  888         return (atomic_fcmpset_##type(p, cmpval, newval));\
  889     }\
  890     struct hack
  891 
  892 ATOMIC_FCMPSET_ACQ_REL(int);
  893 ATOMIC_FCMPSET_ACQ_REL(long);
  894 
  895 #ifdef ISA_206_ATOMICS
  896 #define atomic_fcmpset_8        atomic_fcmpset_char
  897 #endif
  898 #define atomic_fcmpset_acq_8    atomic_fcmpset_acq_char
  899 #define atomic_fcmpset_rel_8    atomic_fcmpset_rel_char
  900 
  901 #ifdef ISA_206_ATOMICS
  902 #define atomic_fcmpset_16       atomic_fcmpset_short
  903 #endif
  904 #define atomic_fcmpset_acq_16   atomic_fcmpset_acq_short
  905 #define atomic_fcmpset_rel_16   atomic_fcmpset_rel_short
  906 
  907 #define atomic_fcmpset_32       atomic_fcmpset_int
  908 #define atomic_fcmpset_acq_32   atomic_fcmpset_acq_int
  909 #define atomic_fcmpset_rel_32   atomic_fcmpset_rel_int
  910 
  911 #ifdef __powerpc64__
  912 #define atomic_fcmpset_64       atomic_fcmpset_long
  913 #define atomic_fcmpset_acq_64   atomic_fcmpset_acq_long
  914 #define atomic_fcmpset_rel_64   atomic_fcmpset_rel_long
  915 
  916 #define atomic_fcmpset_ptr      atomic_fcmpset_long
  917 #define atomic_fcmpset_acq_ptr  atomic_fcmpset_acq_long
  918 #define atomic_fcmpset_rel_ptr  atomic_fcmpset_rel_long
  919 #else
  920 #define atomic_fcmpset_ptr      atomic_fcmpset_int
  921 #define atomic_fcmpset_acq_ptr  atomic_fcmpset_acq_int
  922 #define atomic_fcmpset_rel_ptr  atomic_fcmpset_rel_int
  923 #endif
  924 
  925 static __inline u_int
  926 atomic_fetchadd_int(volatile u_int *p, u_int v)
  927 {
  928         u_int value;
  929 
  930         do {
  931                 value = *p;
  932         } while (!atomic_cmpset_int(p, value, value + v));
  933         return (value);
  934 }
  935 
  936 static __inline u_long
  937 atomic_fetchadd_long(volatile u_long *p, u_long v)
  938 {
  939         u_long value;
  940 
  941         do {
  942                 value = *p;
  943         } while (!atomic_cmpset_long(p, value, value + v));
  944         return (value);
  945 }
  946 
  947 static __inline u_int
  948 atomic_swap_32(volatile u_int *p, u_int v)
  949 {
  950         u_int prev;
  951 
  952         __asm __volatile(
  953         "1:     lwarx   %0,0,%2\n"
  954         "       stwcx.  %3,0,%2\n"
  955         "       bne-    1b\n"
  956         : "=&r" (prev), "+m" (*(volatile u_int *)p)
  957         : "r" (p), "r" (v)
  958         : "cr0", "memory");
  959 
  960         return (prev);
  961 }
  962 
  963 #ifdef __powerpc64__
  964 static __inline u_long
  965 atomic_swap_64(volatile u_long *p, u_long v)
  966 {
  967         u_long prev;
  968 
  969         __asm __volatile(
  970         "1:     ldarx   %0,0,%2\n"
  971         "       stdcx.  %3,0,%2\n"
  972         "       bne-    1b\n"
  973         : "=&r" (prev), "+m" (*(volatile u_long *)p)
  974         : "r" (p), "r" (v)
  975         : "cr0", "memory");
  976 
  977         return (prev);
  978 }
  979 #endif
  980 
  981 #define atomic_fetchadd_32      atomic_fetchadd_int
  982 #define atomic_swap_int         atomic_swap_32
  983 
  984 #ifdef __powerpc64__
  985 #define atomic_fetchadd_64      atomic_fetchadd_long
  986 #define atomic_swap_long        atomic_swap_64
  987 #define atomic_swap_ptr         atomic_swap_64
  988 #else
  989 #define atomic_swap_long(p,v)   atomic_swap_32((volatile u_int *)(p), v)
  990 #define atomic_swap_ptr(p,v)    atomic_swap_32((volatile u_int *)(p), v)
  991 #endif
  992 
  993 static __inline int
  994 atomic_testandset_int(volatile u_int *p, u_int v)
  995 {
  996         u_int m = (1u << (v & 0x1f));
  997         u_int res;
  998         u_int tmp;
  999 
 1000         __asm __volatile(
 1001         "1:     lwarx   %0,0,%3\n"
 1002         "       and     %1,%0,%4\n"
 1003         "       or      %0,%0,%4\n"
 1004         "       stwcx.  %0,0,%3\n"
 1005         "       bne-    1b\n"
 1006         : "=&r"(tmp), "=&r"(res), "+m"(*p)
 1007         : "r"(p), "r"(m)
 1008         : "cr0", "memory");
 1009 
 1010         return (res != 0);
 1011 }
 1012 
 1013 static __inline int
 1014 atomic_testandclear_int(volatile u_int *p, u_int v)
 1015 {
 1016         u_int m = (1u << (v & 0x1f));
 1017         u_int res;
 1018         u_int tmp;
 1019 
 1020         __asm __volatile(
 1021         "1:     lwarx   %0,0,%3\n"
 1022         "       and     %1,%0,%4\n"
 1023         "       andc    %0,%0,%4\n"
 1024         "       stwcx.  %0,0,%3\n"
 1025         "       bne-    1b\n"
 1026         : "=&r"(tmp), "=&r"(res), "+m"(*p)
 1027         : "r"(p), "r"(m)
 1028         : "cr0", "memory");
 1029 
 1030         return (res != 0);
 1031 }
 1032 
 1033 #ifdef __powerpc64__
 1034 static __inline int
 1035 atomic_testandset_long(volatile u_long *p, u_int v)
 1036 {
 1037         u_long m = (1ul << (v & 0x3f));
 1038         u_long res;
 1039         u_long tmp;
 1040 
 1041         __asm __volatile(
 1042         "1:     ldarx   %0,0,%3\n"
 1043         "       and     %1,%0,%4\n"
 1044         "       or      %0,%0,%4\n"
 1045         "       stdcx.  %0,0,%3\n"
 1046         "       bne-    1b\n"
 1047         : "=&r"(tmp), "=&r"(res), "+m"(*(volatile u_long *)p)
 1048         : "r"(p), "r"(m)
 1049         : "cr0", "memory");
 1050 
 1051         return (res != 0);
 1052 }
 1053 
 1054 static __inline int
 1055 atomic_testandclear_long(volatile u_long *p, u_int v)
 1056 {
 1057         u_long m = (1ul << (v & 0x3f));
 1058         u_long res;
 1059         u_long tmp;
 1060 
 1061         __asm __volatile(
 1062         "1:     ldarx   %0,0,%3\n"
 1063         "       and     %1,%0,%4\n"
 1064         "       andc    %0,%0,%4\n"
 1065         "       stdcx.  %0,0,%3\n"
 1066         "       bne-    1b\n"
 1067         : "=&r"(tmp), "=&r"(res), "+m"(*p)
 1068         : "r"(p), "r"(m)
 1069         : "cr0", "memory");
 1070 
 1071         return (res != 0);
 1072 }
 1073 #else
 1074 static __inline int
 1075 atomic_testandset_long(volatile u_long *p, u_int v)
 1076 {
 1077         return (atomic_testandset_int((volatile u_int *)p, v));
 1078 }
 1079 
 1080 static __inline int
 1081 atomic_testandclear_long(volatile u_long *p, u_int v)
 1082 {
 1083         return (atomic_testandclear_int((volatile u_int *)p, v));
 1084 }
 1085 #endif
 1086 
 1087 #define atomic_testandclear_32  atomic_testandclear_int
 1088 #define atomic_testandset_32    atomic_testandset_int
 1089 
 1090 static __inline int
 1091 atomic_testandset_acq_long(volatile u_long *p, u_int v)
 1092 {
 1093         u_int a = atomic_testandset_long(p, v);
 1094         __ATOMIC_ACQ();
 1095         return (a);
 1096 }
 1097 
 1098 #define atomic_testandclear_int         atomic_testandclear_int
 1099 #define atomic_testandset_int           atomic_testandset_int
 1100 #define atomic_testandclear_long        atomic_testandclear_long
 1101 #define atomic_testandset_long          atomic_testandset_long
 1102 #define atomic_testandset_acq_long      atomic_testandset_acq_long
 1103 
 1104 static __inline void
 1105 atomic_thread_fence_acq(void)
 1106 {
 1107 
 1108         powerpc_lwsync();
 1109 }
 1110 
 1111 static __inline void
 1112 atomic_thread_fence_rel(void)
 1113 {
 1114 
 1115         powerpc_lwsync();
 1116 }
 1117 
 1118 static __inline void
 1119 atomic_thread_fence_acq_rel(void)
 1120 {
 1121 
 1122         powerpc_lwsync();
 1123 }
 1124 
 1125 static __inline void
 1126 atomic_thread_fence_seq_cst(void)
 1127 {
 1128 
 1129         __asm __volatile("sync" : : : "memory");
 1130 }
 1131 
 1132 #ifndef ISA_206_ATOMICS
 1133 #include <sys/_atomic_subword.h>
 1134 #define atomic_cmpset_char      atomic_cmpset_8
 1135 #define atomic_cmpset_short     atomic_cmpset_16
 1136 #define atomic_fcmpset_char     atomic_fcmpset_8
 1137 #define atomic_fcmpset_short    atomic_fcmpset_16
 1138 #endif
 1139 
 1140 /* These need sys/_atomic_subword.h on non-ISA-2.06-atomic platforms. */
 1141 ATOMIC_CMPSET_ACQ_REL(char);
 1142 ATOMIC_CMPSET_ACQ_REL(short);
 1143 
 1144 ATOMIC_FCMPSET_ACQ_REL(char);
 1145 ATOMIC_FCMPSET_ACQ_REL(short);
 1146 
 1147 #undef __ATOMIC_REL
 1148 #undef __ATOMIC_ACQ
 1149 
 1150 #endif /* ! _MACHINE_ATOMIC_H_ */

Cache object: 4211043ab4aa677446f0f0c6f2c521ba


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.