11cb0ef41Sopenharmony_ci/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl> 21cb0ef41Sopenharmony_ci * 31cb0ef41Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 41cb0ef41Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 51cb0ef41Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 61cb0ef41Sopenharmony_ci * 71cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 81cb0ef41Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 91cb0ef41Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 101cb0ef41Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 111cb0ef41Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 121cb0ef41Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 131cb0ef41Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 141cb0ef41Sopenharmony_ci */ 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci#ifndef UV_ATOMIC_OPS_H_ 171cb0ef41Sopenharmony_ci#define UV_ATOMIC_OPS_H_ 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci#include "internal.h" /* UV_UNUSED */ 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) 221cb0ef41Sopenharmony_ci#include <atomic.h> 231cb0ef41Sopenharmony_ci#endif 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciUV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)); 261cb0ef41Sopenharmony_ciUV_UNUSED(static void cpu_relax(void)); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci/* Prefer hand-rolled assembly over the gcc builtins because the latter also 291cb0ef41Sopenharmony_ci * issue full memory barriers. 301cb0ef41Sopenharmony_ci */ 311cb0ef41Sopenharmony_ciUV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { 321cb0ef41Sopenharmony_ci#if defined(__i386__) || defined(__x86_64__) 331cb0ef41Sopenharmony_ci int out; 341cb0ef41Sopenharmony_ci __asm__ __volatile__ ("lock; cmpxchg %2, %1;" 351cb0ef41Sopenharmony_ci : "=a" (out), "+m" (*(volatile int*) ptr) 361cb0ef41Sopenharmony_ci : "r" (newval), "0" (oldval) 371cb0ef41Sopenharmony_ci : "memory"); 381cb0ef41Sopenharmony_ci return out; 391cb0ef41Sopenharmony_ci#elif defined(__MVS__) 401cb0ef41Sopenharmony_ci /* Use hand-rolled assembly because codegen from builtin __plo_CSST results in 411cb0ef41Sopenharmony_ci * a runtime bug. 421cb0ef41Sopenharmony_ci */ 431cb0ef41Sopenharmony_ci __asm(" cs %0,%2,%1 \n " : "+r"(oldval), "+m"(*ptr) : "r"(newval) :); 441cb0ef41Sopenharmony_ci return oldval; 451cb0ef41Sopenharmony_ci#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) 461cb0ef41Sopenharmony_ci return atomic_cas_uint((uint_t *)ptr, (uint_t)oldval, (uint_t)newval); 471cb0ef41Sopenharmony_ci#else 481cb0ef41Sopenharmony_ci return __sync_val_compare_and_swap(ptr, oldval, newval); 491cb0ef41Sopenharmony_ci#endif 501cb0ef41Sopenharmony_ci} 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ciUV_UNUSED(static void cpu_relax(void)) { 531cb0ef41Sopenharmony_ci#if defined(__i386__) || defined(__x86_64__) 541cb0ef41Sopenharmony_ci __asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */ 551cb0ef41Sopenharmony_ci#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__) 561cb0ef41Sopenharmony_ci __asm__ __volatile__ ("yield" ::: "memory"); 571cb0ef41Sopenharmony_ci#elif (defined(__ppc__) || defined(__ppc64__)) && defined(__APPLE__) 581cb0ef41Sopenharmony_ci __asm volatile ("" : : : "memory"); 591cb0ef41Sopenharmony_ci#elif !defined(__APPLE__) && (defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__)) 601cb0ef41Sopenharmony_ci __asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory"); 611cb0ef41Sopenharmony_ci#endif 621cb0ef41Sopenharmony_ci} 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci#endif /* UV_ATOMIC_OPS_H_ */ 65