1*b30d1939SAndy Fiddaman /*********************************************************************** 2*b30d1939SAndy Fiddaman * * 3*b30d1939SAndy Fiddaman * This software is part of the ast package * 4*b30d1939SAndy Fiddaman * Copyright (c) 1985-2012 AT&T Intellectual Property * 5*b30d1939SAndy Fiddaman * and is licensed under the * 6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 * 7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property * 8*b30d1939SAndy Fiddaman * * 9*b30d1939SAndy Fiddaman * A copy of the License is available at * 10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html * 11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12*b30d1939SAndy Fiddaman * * 13*b30d1939SAndy Fiddaman * Information and Software Systems Research * 14*b30d1939SAndy Fiddaman * AT&T Research * 15*b30d1939SAndy Fiddaman * Florham Park NJ * 16*b30d1939SAndy Fiddaman * * 17*b30d1939SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> * 18*b30d1939SAndy Fiddaman * David Korn <dgk@research.att.com> * 19*b30d1939SAndy Fiddaman * Phong Vo <kpv@research.att.com> * 20*b30d1939SAndy Fiddaman * * 21*b30d1939SAndy Fiddaman ***********************************************************************/ 22*b30d1939SAndy Fiddaman #pragma prototyped 23*b30d1939SAndy Fiddaman 24*b30d1939SAndy Fiddaman #include "asohdr.h" 25*b30d1939SAndy Fiddaman #include "FEATURE/aso" 26*b30d1939SAndy Fiddaman 27*b30d1939SAndy Fiddaman #if defined(_UWIN) && defined(_BLD_ast) 28*b30d1939SAndy Fiddaman 29*b30d1939SAndy Fiddaman NoN(aso) 30*b30d1939SAndy Fiddaman 31*b30d1939SAndy Fiddaman #else 32*b30d1939SAndy Fiddaman 33*b30d1939SAndy Fiddaman /* 34*b30d1939SAndy Fiddaman * ast atomic scalar operations 35*b30d1939SAndy Fiddaman * AT&T Research 36*b30d1939SAndy Fiddaman * 37*b30d1939SAndy Fiddaman * cas { 8 16 32 [64] } subset snarfed from the work by 38*b30d1939SAndy Fiddaman * Adam Edgar and Kiem-Phong Vo 2010-10-10 39*b30d1939SAndy Fiddaman * 40*b30d1939SAndy Fiddaman * lock methods and emulations by 41*b30d1939SAndy Fiddaman * Glenn Fowler 2011-11-11 42*b30d1939SAndy Fiddaman * 43*b30d1939SAndy Fiddaman * hopefully stable by 2012-12-12 44*b30d1939SAndy Fiddaman */ 45*b30d1939SAndy Fiddaman 46*b30d1939SAndy Fiddaman #if !_PACKAGE_ast 47*b30d1939SAndy Fiddaman 48*b30d1939SAndy Fiddaman #if _UWIN 49*b30d1939SAndy Fiddaman 50*b30d1939SAndy Fiddaman extern ssize_t sfsprintf(char*, size_t, const char*, ...); 51*b30d1939SAndy Fiddaman 52*b30d1939SAndy Fiddaman #else 53*b30d1939SAndy Fiddaman 54*b30d1939SAndy Fiddaman #include <stdio.h> 55*b30d1939SAndy Fiddaman 56*b30d1939SAndy Fiddaman #define sfsprintf snprintf 57*b30d1939SAndy Fiddaman 58*b30d1939SAndy Fiddaman #endif 59*b30d1939SAndy Fiddaman 60*b30d1939SAndy Fiddaman #endif 61*b30d1939SAndy Fiddaman 62*b30d1939SAndy Fiddaman #if defined(_aso_casptr) && (defined(_aso_cas32) || defined(_aso_cas64)) 63*b30d1939SAndy Fiddaman #define ASO_METHOD (&_aso_meth_intrinsic) 64*b30d1939SAndy Fiddaman #define ASO_LOCKF 0 65*b30d1939SAndy Fiddaman #else 66*b30d1939SAndy Fiddaman #define ASO_METHOD (&_aso_meth_signal) 67*b30d1939SAndy Fiddaman #define ASO_LOCKF _aso_lock_signal 68*b30d1939SAndy Fiddaman #endif 69*b30d1939SAndy Fiddaman 70*b30d1939SAndy Fiddaman typedef union 71*b30d1939SAndy Fiddaman { 72*b30d1939SAndy Fiddaman uint8_t c[2]; 73*b30d1939SAndy Fiddaman uint16_t i; 74*b30d1939SAndy Fiddaman } U16_8_t; 75*b30d1939SAndy Fiddaman 76*b30d1939SAndy Fiddaman typedef union 77*b30d1939SAndy Fiddaman { 78*b30d1939SAndy Fiddaman uint8_t c[4]; 79*b30d1939SAndy Fiddaman uint32_t i; 80*b30d1939SAndy Fiddaman } U32_8_t; 81*b30d1939SAndy Fiddaman 82*b30d1939SAndy Fiddaman typedef union 83*b30d1939SAndy Fiddaman { 84*b30d1939SAndy Fiddaman uint16_t c[2]; 85*b30d1939SAndy Fiddaman uint32_t i; 86*b30d1939SAndy Fiddaman } U32_16_t; 87*b30d1939SAndy Fiddaman 88*b30d1939SAndy Fiddaman #ifdef _ast_int8_t 89*b30d1939SAndy Fiddaman 90*b30d1939SAndy Fiddaman typedef union 91*b30d1939SAndy Fiddaman { 92*b30d1939SAndy Fiddaman uint8_t c[8]; 93*b30d1939SAndy Fiddaman uint64_t i; 94*b30d1939SAndy Fiddaman } U64_8_t; 95*b30d1939SAndy Fiddaman 96*b30d1939SAndy Fiddaman typedef union 97*b30d1939SAndy Fiddaman { 98*b30d1939SAndy Fiddaman uint16_t c[4]; 99*b30d1939SAndy Fiddaman uint64_t i; 100*b30d1939SAndy Fiddaman } U64_16_t; 101*b30d1939SAndy Fiddaman 102*b30d1939SAndy Fiddaman typedef union 103*b30d1939SAndy Fiddaman { 104*b30d1939SAndy Fiddaman uint32_t c[2]; 105*b30d1939SAndy Fiddaman uint64_t i; 106*b30d1939SAndy Fiddaman } U64_32_t; 107*b30d1939SAndy Fiddaman 108*b30d1939SAndy Fiddaman #endif 109*b30d1939SAndy Fiddaman 110*b30d1939SAndy Fiddaman typedef struct State_s 111*b30d1939SAndy Fiddaman { 112*b30d1939SAndy Fiddaman Asometh_t* meth; 113*b30d1939SAndy Fiddaman Asolock_f lockf; 114*b30d1939SAndy Fiddaman Asoerror_f errorf; 115*b30d1939SAndy Fiddaman uintmax_t hung; 116*b30d1939SAndy Fiddaman unsigned int hung2; 117*b30d1939SAndy Fiddaman void* data; 118*b30d1939SAndy Fiddaman pid_t pid; 119*b30d1939SAndy Fiddaman } State_t; 120*b30d1939SAndy Fiddaman 121*b30d1939SAndy Fiddaman static unsigned int _aso_data_signal; 122*b30d1939SAndy Fiddaman 123*b30d1939SAndy Fiddaman static ssize_t 124*b30d1939SAndy Fiddaman _aso_lock_signal(void* data, ssize_t k, void volatile* p) 125*b30d1939SAndy Fiddaman { 126*b30d1939SAndy Fiddaman if (k >= 0) 127*b30d1939SAndy Fiddaman { 128*b30d1939SAndy Fiddaman _aso_data_signal--; 129*b30d1939SAndy Fiddaman return 0; 130*b30d1939SAndy Fiddaman } 131*b30d1939SAndy Fiddaman while (_aso_data_signal++) 132*b30d1939SAndy Fiddaman _aso_data_signal--; 133*b30d1939SAndy Fiddaman return 1; 134*b30d1939SAndy Fiddaman } 135*b30d1939SAndy Fiddaman 136*b30d1939SAndy Fiddaman static Asometh_t _aso_meth_signal = { "signal", ASO_SIGNAL, 0, _aso_lock_signal }; 137*b30d1939SAndy Fiddaman extern Asometh_t _aso_meth_semaphore; 138*b30d1939SAndy Fiddaman extern Asometh_t _aso_meth_fcntl; 139*b30d1939SAndy Fiddaman static Asometh_t _aso_meth_intrinsic = { "intrinsic", ASO_INTRINSIC|ASO_PROCESS|ASO_THREAD|ASO_SIGNAL, 0, 0 }; 140*b30d1939SAndy Fiddaman 141*b30d1939SAndy Fiddaman static Asometh_t* method[] = 142*b30d1939SAndy Fiddaman { 143*b30d1939SAndy Fiddaman &_aso_meth_signal, 144*b30d1939SAndy Fiddaman #if defined(_ast_int8_t) && defined(_aso_cas64) || !defined(_ast_int8_t) && defined(_aso_cas32) 145*b30d1939SAndy Fiddaman &_aso_meth_intrinsic, 146*b30d1939SAndy Fiddaman #endif 147*b30d1939SAndy Fiddaman #if _aso_semaphore 148*b30d1939SAndy Fiddaman &_aso_meth_semaphore, 149*b30d1939SAndy Fiddaman #endif 150*b30d1939SAndy Fiddaman #if _aso_fcntl 151*b30d1939SAndy Fiddaman &_aso_meth_fcntl, 152*b30d1939SAndy Fiddaman #endif 153*b30d1939SAndy Fiddaman }; 154*b30d1939SAndy Fiddaman 155*b30d1939SAndy Fiddaman static State_t state = 156*b30d1939SAndy Fiddaman { 157*b30d1939SAndy Fiddaman ASO_METHOD, ASO_LOCKF 158*b30d1939SAndy Fiddaman }; 159*b30d1939SAndy Fiddaman 160*b30d1939SAndy Fiddaman static int 161*b30d1939SAndy Fiddaman asoerror(int type, const char* format, const char* a, const char* b, long n) 162*b30d1939SAndy Fiddaman { 163*b30d1939SAndy Fiddaman char buf[128]; 164*b30d1939SAndy Fiddaman 165*b30d1939SAndy Fiddaman if (b) 166*b30d1939SAndy Fiddaman sfsprintf(buf, sizeof(buf), format, a, b, n); 167*b30d1939SAndy Fiddaman else if (a) 168*b30d1939SAndy Fiddaman sfsprintf(buf, sizeof(buf), format, a, n); 169*b30d1939SAndy Fiddaman else 170*b30d1939SAndy Fiddaman sfsprintf(buf, sizeof(buf), format, n); 171*b30d1939SAndy Fiddaman return state.errorf(type, buf); 172*b30d1939SAndy Fiddaman } 173*b30d1939SAndy Fiddaman 174*b30d1939SAndy Fiddaman /* 175*b30d1939SAndy Fiddaman * if type!=0 return lock method for type with name details 176*b30d1939SAndy Fiddaman * else if name!=0 return lock method matching <name>[,<details>] 177*b30d1939SAndy Fiddaman * else return the current lock method 178*b30d1939SAndy Fiddaman * 0 returned on error 179*b30d1939SAndy Fiddaman * 180*b30d1939SAndy Fiddaman * the user visible asometh() calls this function 181*b30d1939SAndy Fiddaman * it allows, e.g., for -ltaso to provide an asometh() intercept 182*b30d1939SAndy Fiddaman * that prepends its ASO_THREAD methods ahead of the _asometh() methods 183*b30d1939SAndy Fiddaman */ 184*b30d1939SAndy Fiddaman 185*b30d1939SAndy Fiddaman Asometh_t* 186*b30d1939SAndy Fiddaman _asometh(int type, void* data) 187*b30d1939SAndy Fiddaman { 188*b30d1939SAndy Fiddaman size_t n; 189*b30d1939SAndy Fiddaman int i; 190*b30d1939SAndy Fiddaman char* e; 191*b30d1939SAndy Fiddaman Asometh_t* meth; 192*b30d1939SAndy Fiddaman char* name; 193*b30d1939SAndy Fiddaman 194*b30d1939SAndy Fiddaman if (type == ASO_NEXT) 195*b30d1939SAndy Fiddaman { 196*b30d1939SAndy Fiddaman if (!(meth = (Asometh_t*)data)) 197*b30d1939SAndy Fiddaman return method[0]; 198*b30d1939SAndy Fiddaman for (i = 0; i < elementsof(method) - 1; i++) 199*b30d1939SAndy Fiddaman if (meth == method[i]) 200*b30d1939SAndy Fiddaman return method[i+1]; 201*b30d1939SAndy Fiddaman return 0; 202*b30d1939SAndy Fiddaman } 203*b30d1939SAndy Fiddaman if (type) 204*b30d1939SAndy Fiddaman { 205*b30d1939SAndy Fiddaman for (i = 0; i < elementsof(method); i++) 206*b30d1939SAndy Fiddaman if (method[i]->type & type) 207*b30d1939SAndy Fiddaman { 208*b30d1939SAndy Fiddaman method[i]->details = (char*)data; 209*b30d1939SAndy Fiddaman return method[i]; 210*b30d1939SAndy Fiddaman } 211*b30d1939SAndy Fiddaman return 0; 212*b30d1939SAndy Fiddaman } 213*b30d1939SAndy Fiddaman if (!(name = (char*)data)) 214*b30d1939SAndy Fiddaman return state.meth; 215*b30d1939SAndy Fiddaman n = (e = strchr(name, ',')) ? (e - name) : strlen(name); 216*b30d1939SAndy Fiddaman for (i = 0; i < elementsof(method); i++) 217*b30d1939SAndy Fiddaman if (strncmp(name, method[i]->name, n) == 0) 218*b30d1939SAndy Fiddaman { 219*b30d1939SAndy Fiddaman if (e) 220*b30d1939SAndy Fiddaman method[i]->details = e + 1; 221*b30d1939SAndy Fiddaman return method[i]; 222*b30d1939SAndy Fiddaman } 223*b30d1939SAndy Fiddaman return 0; 224*b30d1939SAndy Fiddaman } 225*b30d1939SAndy Fiddaman 226*b30d1939SAndy Fiddaman /* 227*b30d1939SAndy Fiddaman * clean up lock method on exit 228*b30d1939SAndy Fiddaman */ 229*b30d1939SAndy Fiddaman 230*b30d1939SAndy Fiddaman static void 231*b30d1939SAndy Fiddaman asoexit(void) 232*b30d1939SAndy Fiddaman { 233*b30d1939SAndy Fiddaman if (state.meth && state.meth->initf && state.data && state.pid == getpid()) 234*b30d1939SAndy Fiddaman { 235*b30d1939SAndy Fiddaman state.lockf = ASO_METHOD->lockf; 236*b30d1939SAndy Fiddaman state.meth->initf(state.data, 0); 237*b30d1939SAndy Fiddaman state.data = 0; 238*b30d1939SAndy Fiddaman } 239*b30d1939SAndy Fiddaman } 240*b30d1939SAndy Fiddaman 241*b30d1939SAndy Fiddaman /* 242*b30d1939SAndy Fiddaman * initialize lock method 243*b30d1939SAndy Fiddaman */ 244*b30d1939SAndy Fiddaman 245*b30d1939SAndy Fiddaman int 246*b30d1939SAndy Fiddaman asoinit(const char* details, Asometh_t* meth, Asodisc_t* disc) 247*b30d1939SAndy Fiddaman { 248*b30d1939SAndy Fiddaman void* data; 249*b30d1939SAndy Fiddaman 250*b30d1939SAndy Fiddaman if (disc) 251*b30d1939SAndy Fiddaman { 252*b30d1939SAndy Fiddaman state.errorf = disc->errorf; 253*b30d1939SAndy Fiddaman state.hung2 = disc->hung; 254*b30d1939SAndy Fiddaman state.hung = 1; 255*b30d1939SAndy Fiddaman state.hung <<= state.hung2; 256*b30d1939SAndy Fiddaman state.hung--; 257*b30d1939SAndy Fiddaman } 258*b30d1939SAndy Fiddaman if (!meth) 259*b30d1939SAndy Fiddaman return state.pid != 0; 260*b30d1939SAndy Fiddaman if (!meth->lockf && !(meth->type & ASO_INTRINSIC)) 261*b30d1939SAndy Fiddaman { 262*b30d1939SAndy Fiddaman if (state.errorf) 263*b30d1939SAndy Fiddaman asoerror(ASO_EMETHOD, "%s method has no lock function", meth->name, 0, 0); 264*b30d1939SAndy Fiddaman return -1; 265*b30d1939SAndy Fiddaman } 266*b30d1939SAndy Fiddaman state.lockf = ASO_METHOD->lockf; 267*b30d1939SAndy Fiddaman if (state.meth && state.meth->initf && state.data) 268*b30d1939SAndy Fiddaman { 269*b30d1939SAndy Fiddaman state.meth->initf(state.data, 0); 270*b30d1939SAndy Fiddaman state.data = 0; 271*b30d1939SAndy Fiddaman } 272*b30d1939SAndy Fiddaman if (!meth->initf) 273*b30d1939SAndy Fiddaman data = 0; 274*b30d1939SAndy Fiddaman else if (!(data = meth->initf(0, details ? details : meth->details))) 275*b30d1939SAndy Fiddaman { 276*b30d1939SAndy Fiddaman state.meth = ASO_METHOD; 277*b30d1939SAndy Fiddaman if (state.errorf) 278*b30d1939SAndy Fiddaman asoerror(ASO_EMETHOD, "%s method initialization failed -- reverting to the %s method", meth->name, state.meth->name, 0); 279*b30d1939SAndy Fiddaman return -1; 280*b30d1939SAndy Fiddaman } 281*b30d1939SAndy Fiddaman state.meth = meth; 282*b30d1939SAndy Fiddaman state.data = data; 283*b30d1939SAndy Fiddaman state.lockf = meth->lockf; 284*b30d1939SAndy Fiddaman if (!state.pid) 285*b30d1939SAndy Fiddaman { 286*b30d1939SAndy Fiddaman state.pid = getpid(); 287*b30d1939SAndy Fiddaman atexit(asoexit); 288*b30d1939SAndy Fiddaman } 289*b30d1939SAndy Fiddaman return 0; 290*b30d1939SAndy Fiddaman } 291*b30d1939SAndy Fiddaman 292*b30d1939SAndy Fiddaman /* 293*b30d1939SAndy Fiddaman * loop check for hung spin locks 294*b30d1939SAndy Fiddaman * and periodic relinquishing of the processor 295*b30d1939SAndy Fiddaman */ 296*b30d1939SAndy Fiddaman 297*b30d1939SAndy Fiddaman int 298*b30d1939SAndy Fiddaman asoloop(uintmax_t rep) 299*b30d1939SAndy Fiddaman { 300*b30d1939SAndy Fiddaman if (state.hung && !(rep & state.hung) && state.errorf) 301*b30d1939SAndy Fiddaman return asoerror(ASO_EHUNG, "spin lock possibly hung after 2^%u attempts", 0, 0, state.hung2); 302*b30d1939SAndy Fiddaman return (rep & ASO_RELAX) ? 0 : asorelax(1); 303*b30d1939SAndy Fiddaman } 304*b30d1939SAndy Fiddaman 305*b30d1939SAndy Fiddaman /* 306*b30d1939SAndy Fiddaman * error checking state.lockf() call 307*b30d1939SAndy Fiddaman */ 308*b30d1939SAndy Fiddaman 309*b30d1939SAndy Fiddaman static ssize_t 310*b30d1939SAndy Fiddaman lock(void* data, ssize_t k, void volatile* p) 311*b30d1939SAndy Fiddaman { 312*b30d1939SAndy Fiddaman ssize_t r; 313*b30d1939SAndy Fiddaman 314*b30d1939SAndy Fiddaman if ((r = state.lockf(data, k, p)) < 0 && state.errorf) 315*b30d1939SAndy Fiddaman asoerror(ASO_EMETHOD, "%s method lock failed", state.meth->name, 0, 0); 316*b30d1939SAndy Fiddaman return r; 317*b30d1939SAndy Fiddaman } 318*b30d1939SAndy Fiddaman 319*b30d1939SAndy Fiddaman /* 320*b30d1939SAndy Fiddaman * sync and return "current" value 321*b30d1939SAndy Fiddaman */ 322*b30d1939SAndy Fiddaman 323*b30d1939SAndy Fiddaman uint8_t 324*b30d1939SAndy Fiddaman asoget8(uint8_t volatile* p) 325*b30d1939SAndy Fiddaman { 326*b30d1939SAndy Fiddaman int o; 327*b30d1939SAndy Fiddaman 328*b30d1939SAndy Fiddaman do 329*b30d1939SAndy Fiddaman { 330*b30d1939SAndy Fiddaman o = *p; 331*b30d1939SAndy Fiddaman } while (asocas8(p, o, o) != o); 332*b30d1939SAndy Fiddaman return o; 333*b30d1939SAndy Fiddaman } 334*b30d1939SAndy Fiddaman 335*b30d1939SAndy Fiddaman uint16_t 336*b30d1939SAndy Fiddaman asoget16(uint16_t volatile* p) 337*b30d1939SAndy Fiddaman { 338*b30d1939SAndy Fiddaman int o; 339*b30d1939SAndy Fiddaman 340*b30d1939SAndy Fiddaman do 341*b30d1939SAndy Fiddaman { 342*b30d1939SAndy Fiddaman o = *p; 343*b30d1939SAndy Fiddaman } while (asocas16(p, o, o) != o); 344*b30d1939SAndy Fiddaman return o; 345*b30d1939SAndy Fiddaman } 346*b30d1939SAndy Fiddaman 347*b30d1939SAndy Fiddaman uint32_t 348*b30d1939SAndy Fiddaman asoget32(uint32_t volatile* p) 349*b30d1939SAndy Fiddaman { 350*b30d1939SAndy Fiddaman uint32_t o; 351*b30d1939SAndy Fiddaman 352*b30d1939SAndy Fiddaman do 353*b30d1939SAndy Fiddaman { 354*b30d1939SAndy Fiddaman o = *p; 355*b30d1939SAndy Fiddaman } while (asocas32(p, o, o) != o); 356*b30d1939SAndy Fiddaman return o; 357*b30d1939SAndy Fiddaman } 358*b30d1939SAndy Fiddaman 359*b30d1939SAndy Fiddaman #ifdef _ast_int8_t 360*b30d1939SAndy Fiddaman 361*b30d1939SAndy Fiddaman uint64_t 362*b30d1939SAndy Fiddaman asoget64(uint64_t volatile* p) 363*b30d1939SAndy Fiddaman { 364*b30d1939SAndy Fiddaman uint64_t o; 365*b30d1939SAndy Fiddaman 366*b30d1939SAndy Fiddaman do 367*b30d1939SAndy Fiddaman { 368*b30d1939SAndy Fiddaman o = *p; 369*b30d1939SAndy Fiddaman } while (asocas64(p, o, o) != o); 370*b30d1939SAndy Fiddaman return o; 371*b30d1939SAndy Fiddaman } 372*b30d1939SAndy Fiddaman 373*b30d1939SAndy Fiddaman #endif 374*b30d1939SAndy Fiddaman 375*b30d1939SAndy Fiddaman void* 376*b30d1939SAndy Fiddaman asogetptr(void volatile* p) 377*b30d1939SAndy Fiddaman { 378*b30d1939SAndy Fiddaman void* o; 379*b30d1939SAndy Fiddaman 380*b30d1939SAndy Fiddaman do 381*b30d1939SAndy Fiddaman { 382*b30d1939SAndy Fiddaman o = *(void* volatile*)p; 383*b30d1939SAndy Fiddaman } while (asocasptr(p, o, o) != o); 384*b30d1939SAndy Fiddaman return o; 385*b30d1939SAndy Fiddaman } 386*b30d1939SAndy Fiddaman 387*b30d1939SAndy Fiddaman /* 388*b30d1939SAndy Fiddaman * increment and return old value 389*b30d1939SAndy Fiddaman */ 390*b30d1939SAndy Fiddaman 391*b30d1939SAndy Fiddaman uint8_t 392*b30d1939SAndy Fiddaman asoinc8(uint8_t volatile* p) 393*b30d1939SAndy Fiddaman { 394*b30d1939SAndy Fiddaman ssize_t k; 395*b30d1939SAndy Fiddaman int o; 396*b30d1939SAndy Fiddaman 397*b30d1939SAndy Fiddaman #if defined(_aso_inc8) 398*b30d1939SAndy Fiddaman if (!state.lockf) 399*b30d1939SAndy Fiddaman return _aso_inc8(p); 400*b30d1939SAndy Fiddaman #else 401*b30d1939SAndy Fiddaman if (!state.lockf) 402*b30d1939SAndy Fiddaman { 403*b30d1939SAndy Fiddaman do 404*b30d1939SAndy Fiddaman { 405*b30d1939SAndy Fiddaman o = *p; 406*b30d1939SAndy Fiddaman } while (asocas8(p, o, o + 1) != o); 407*b30d1939SAndy Fiddaman return o; 408*b30d1939SAndy Fiddaman } 409*b30d1939SAndy Fiddaman #endif 410*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 411*b30d1939SAndy Fiddaman o = (*p)++; 412*b30d1939SAndy Fiddaman lock(state.data, k, p); 413*b30d1939SAndy Fiddaman return o; 414*b30d1939SAndy Fiddaman } 415*b30d1939SAndy Fiddaman 416*b30d1939SAndy Fiddaman uint16_t 417*b30d1939SAndy Fiddaman asoinc16(uint16_t volatile* p) 418*b30d1939SAndy Fiddaman { 419*b30d1939SAndy Fiddaman ssize_t k; 420*b30d1939SAndy Fiddaman int o; 421*b30d1939SAndy Fiddaman 422*b30d1939SAndy Fiddaman #if defined(_aso_inc16) 423*b30d1939SAndy Fiddaman if (!state.lockf) 424*b30d1939SAndy Fiddaman return _aso_inc16(p); 425*b30d1939SAndy Fiddaman #else 426*b30d1939SAndy Fiddaman if (!state.lockf) 427*b30d1939SAndy Fiddaman { 428*b30d1939SAndy Fiddaman do 429*b30d1939SAndy Fiddaman { 430*b30d1939SAndy Fiddaman o = *p; 431*b30d1939SAndy Fiddaman } while (asocas16(p, o, o + 1) != o); 432*b30d1939SAndy Fiddaman return o; 433*b30d1939SAndy Fiddaman } 434*b30d1939SAndy Fiddaman #endif 435*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 436*b30d1939SAndy Fiddaman o = (*p)++; 437*b30d1939SAndy Fiddaman lock(state.data, k, p); 438*b30d1939SAndy Fiddaman return o; 439*b30d1939SAndy Fiddaman } 440*b30d1939SAndy Fiddaman 441*b30d1939SAndy Fiddaman uint32_t 442*b30d1939SAndy Fiddaman asoinc32(uint32_t volatile* p) 443*b30d1939SAndy Fiddaman { 444*b30d1939SAndy Fiddaman ssize_t k; 445*b30d1939SAndy Fiddaman int o; 446*b30d1939SAndy Fiddaman 447*b30d1939SAndy Fiddaman #if defined(_aso_inc32) 448*b30d1939SAndy Fiddaman if (!state.lockf) 449*b30d1939SAndy Fiddaman return _aso_inc32(p); 450*b30d1939SAndy Fiddaman #else 451*b30d1939SAndy Fiddaman if (!state.lockf) 452*b30d1939SAndy Fiddaman { 453*b30d1939SAndy Fiddaman do 454*b30d1939SAndy Fiddaman { 455*b30d1939SAndy Fiddaman o = *p; 456*b30d1939SAndy Fiddaman } while (asocas32(p, o, o + 1) != o); 457*b30d1939SAndy Fiddaman return o; 458*b30d1939SAndy Fiddaman } 459*b30d1939SAndy Fiddaman #endif 460*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 461*b30d1939SAndy Fiddaman o = (*p)++; 462*b30d1939SAndy Fiddaman lock(state.data, k, p); 463*b30d1939SAndy Fiddaman return o; 464*b30d1939SAndy Fiddaman } 465*b30d1939SAndy Fiddaman 466*b30d1939SAndy Fiddaman #ifdef _ast_int8_t 467*b30d1939SAndy Fiddaman 468*b30d1939SAndy Fiddaman uint64_t 469*b30d1939SAndy Fiddaman asoinc64(uint64_t volatile* p) 470*b30d1939SAndy Fiddaman { 471*b30d1939SAndy Fiddaman ssize_t k; 472*b30d1939SAndy Fiddaman uint64_t o; 473*b30d1939SAndy Fiddaman 474*b30d1939SAndy Fiddaman #if defined(_aso_inc64) 475*b30d1939SAndy Fiddaman if (!state.lockf) 476*b30d1939SAndy Fiddaman return _aso_inc64(p); 477*b30d1939SAndy Fiddaman #else 478*b30d1939SAndy Fiddaman if (!state.lockf) 479*b30d1939SAndy Fiddaman { 480*b30d1939SAndy Fiddaman do 481*b30d1939SAndy Fiddaman { 482*b30d1939SAndy Fiddaman o = *p; 483*b30d1939SAndy Fiddaman } while (asocas64(p, o, o + 1) != o); 484*b30d1939SAndy Fiddaman return o; 485*b30d1939SAndy Fiddaman } 486*b30d1939SAndy Fiddaman #endif 487*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 488*b30d1939SAndy Fiddaman o = (*p)++; 489*b30d1939SAndy Fiddaman lock(state.data, k, p); 490*b30d1939SAndy Fiddaman return o; 491*b30d1939SAndy Fiddaman } 492*b30d1939SAndy Fiddaman 493*b30d1939SAndy Fiddaman #endif 494*b30d1939SAndy Fiddaman 495*b30d1939SAndy Fiddaman /* 496*b30d1939SAndy Fiddaman * decrement and return old value 497*b30d1939SAndy Fiddaman */ 498*b30d1939SAndy Fiddaman 499*b30d1939SAndy Fiddaman uint8_t 500*b30d1939SAndy Fiddaman asodec8(uint8_t volatile* p) 501*b30d1939SAndy Fiddaman { 502*b30d1939SAndy Fiddaman ssize_t k; 503*b30d1939SAndy Fiddaman int o; 504*b30d1939SAndy Fiddaman 505*b30d1939SAndy Fiddaman #if defined(_aso_dec8) 506*b30d1939SAndy Fiddaman if (!state.lockf) 507*b30d1939SAndy Fiddaman return _aso_dec8(p); 508*b30d1939SAndy Fiddaman #else 509*b30d1939SAndy Fiddaman if (!state.lockf) 510*b30d1939SAndy Fiddaman { 511*b30d1939SAndy Fiddaman do 512*b30d1939SAndy Fiddaman { 513*b30d1939SAndy Fiddaman o = *p; 514*b30d1939SAndy Fiddaman } while (asocas8(p, o, o - 1) != o); 515*b30d1939SAndy Fiddaman return o; 516*b30d1939SAndy Fiddaman } 517*b30d1939SAndy Fiddaman #endif 518*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 519*b30d1939SAndy Fiddaman o = (*p)--; 520*b30d1939SAndy Fiddaman lock(state.data, k, p); 521*b30d1939SAndy Fiddaman return o; 522*b30d1939SAndy Fiddaman } 523*b30d1939SAndy Fiddaman 524*b30d1939SAndy Fiddaman uint16_t 525*b30d1939SAndy Fiddaman asodec16(uint16_t volatile* p) 526*b30d1939SAndy Fiddaman { 527*b30d1939SAndy Fiddaman ssize_t k; 528*b30d1939SAndy Fiddaman int o; 529*b30d1939SAndy Fiddaman 530*b30d1939SAndy Fiddaman #if defined(_aso_dec16) 531*b30d1939SAndy Fiddaman if (!state.lockf) 532*b30d1939SAndy Fiddaman return _aso_dec16(p); 533*b30d1939SAndy Fiddaman #else 534*b30d1939SAndy Fiddaman if (!state.lockf) 535*b30d1939SAndy Fiddaman { 536*b30d1939SAndy Fiddaman do 537*b30d1939SAndy Fiddaman { 538*b30d1939SAndy Fiddaman o = *p; 539*b30d1939SAndy Fiddaman } while (asocas16(p, o, o - 1) != o); 540*b30d1939SAndy Fiddaman return o; 541*b30d1939SAndy Fiddaman } 542*b30d1939SAndy Fiddaman #endif 543*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 544*b30d1939SAndy Fiddaman o = (*p)--; 545*b30d1939SAndy Fiddaman lock(state.data, k, p); 546*b30d1939SAndy Fiddaman return o; 547*b30d1939SAndy Fiddaman } 548*b30d1939SAndy Fiddaman 549*b30d1939SAndy Fiddaman uint32_t 550*b30d1939SAndy Fiddaman asodec32(uint32_t volatile* p) 551*b30d1939SAndy Fiddaman { 552*b30d1939SAndy Fiddaman ssize_t k; 553*b30d1939SAndy Fiddaman int o; 554*b30d1939SAndy Fiddaman 555*b30d1939SAndy Fiddaman #if defined(_aso_dec32) 556*b30d1939SAndy Fiddaman if (!state.lockf) 557*b30d1939SAndy Fiddaman return _aso_dec32(p); 558*b30d1939SAndy Fiddaman #else 559*b30d1939SAndy Fiddaman if (!state.lockf) 560*b30d1939SAndy Fiddaman { 561*b30d1939SAndy Fiddaman do 562*b30d1939SAndy Fiddaman { 563*b30d1939SAndy Fiddaman o = *p; 564*b30d1939SAndy Fiddaman } while (asocas32(p, o, o - 1) != o); 565*b30d1939SAndy Fiddaman return o; 566*b30d1939SAndy Fiddaman } 567*b30d1939SAndy Fiddaman #endif 568*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 569*b30d1939SAndy Fiddaman o = (*p)--; 570*b30d1939SAndy Fiddaman lock(state.data, k, p); 571*b30d1939SAndy Fiddaman return o; 572*b30d1939SAndy Fiddaman } 573*b30d1939SAndy Fiddaman 574*b30d1939SAndy Fiddaman #ifdef _ast_int8_t 575*b30d1939SAndy Fiddaman 576*b30d1939SAndy Fiddaman uint64_t 577*b30d1939SAndy Fiddaman asodec64(uint64_t volatile* p) 578*b30d1939SAndy Fiddaman { 579*b30d1939SAndy Fiddaman ssize_t k; 580*b30d1939SAndy Fiddaman uint64_t o; 581*b30d1939SAndy Fiddaman 582*b30d1939SAndy Fiddaman #if defined(_aso_dec64) 583*b30d1939SAndy Fiddaman if (!state.lockf) 584*b30d1939SAndy Fiddaman return _aso_dec64(p); 585*b30d1939SAndy Fiddaman #else 586*b30d1939SAndy Fiddaman if (!state.lockf) 587*b30d1939SAndy Fiddaman { 588*b30d1939SAndy Fiddaman do 589*b30d1939SAndy Fiddaman { 590*b30d1939SAndy Fiddaman o = *p; 591*b30d1939SAndy Fiddaman } while (asocas64(p, o, o - 1) != o); 592*b30d1939SAndy Fiddaman return o; 593*b30d1939SAndy Fiddaman } 594*b30d1939SAndy Fiddaman #endif 595*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 596*b30d1939SAndy Fiddaman o = (*p)--; 597*b30d1939SAndy Fiddaman lock(state.data, k, p); 598*b30d1939SAndy Fiddaman return o; 599*b30d1939SAndy Fiddaman } 600*b30d1939SAndy Fiddaman 601*b30d1939SAndy Fiddaman #endif 602*b30d1939SAndy Fiddaman 603*b30d1939SAndy Fiddaman /* 604*b30d1939SAndy Fiddaman * { 8 16 32 [64] } compare with old, swap with new if same, and return old value 605*b30d1939SAndy Fiddaman */ 606*b30d1939SAndy Fiddaman 607*b30d1939SAndy Fiddaman uint8_t 608*b30d1939SAndy Fiddaman asocas8(uint8_t volatile* p, int o, int n) 609*b30d1939SAndy Fiddaman { 610*b30d1939SAndy Fiddaman ssize_t k; 611*b30d1939SAndy Fiddaman 612*b30d1939SAndy Fiddaman #if defined(_aso_cas8) 613*b30d1939SAndy Fiddaman if (!state.lockf) 614*b30d1939SAndy Fiddaman return _aso_cas8(p, o, n); 615*b30d1939SAndy Fiddaman #elif defined(_aso_cas16) 616*b30d1939SAndy Fiddaman if (!state.lockf) 617*b30d1939SAndy Fiddaman { 618*b30d1939SAndy Fiddaman U16_8_t u; 619*b30d1939SAndy Fiddaman U16_8_t v; 620*b30d1939SAndy Fiddaman U16_8_t* a; 621*b30d1939SAndy Fiddaman int s; 622*b30d1939SAndy Fiddaman int i; 623*b30d1939SAndy Fiddaman 624*b30d1939SAndy Fiddaman s = (int)(integralof(p) & (sizeof(u.i) - 1)); 625*b30d1939SAndy Fiddaman a = (U16_8_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1))); 626*b30d1939SAndy Fiddaman for (;;) 627*b30d1939SAndy Fiddaman { 628*b30d1939SAndy Fiddaman u.i = a->i; 629*b30d1939SAndy Fiddaman u.c[s] = o; 630*b30d1939SAndy Fiddaman v.i = u.i; 631*b30d1939SAndy Fiddaman v.c[s] = n; 632*b30d1939SAndy Fiddaman if (_aso_cas16(&a->i, u.i, v.i) == u.i) 633*b30d1939SAndy Fiddaman break; 634*b30d1939SAndy Fiddaman for (i = 0;; i++) 635*b30d1939SAndy Fiddaman if (i >= elementsof(u.c)) 636*b30d1939SAndy Fiddaman return a->c[s]; 637*b30d1939SAndy Fiddaman else if (i != s && u.c[i] != a->c[i]) 638*b30d1939SAndy Fiddaman break; 639*b30d1939SAndy Fiddaman } 640*b30d1939SAndy Fiddaman return o; 641*b30d1939SAndy Fiddaman } 642*b30d1939SAndy Fiddaman #elif defined(_aso_cas32) 643*b30d1939SAndy Fiddaman if (!state.lockf) 644*b30d1939SAndy Fiddaman { 645*b30d1939SAndy Fiddaman U32_8_t u; 646*b30d1939SAndy Fiddaman U32_8_t v; 647*b30d1939SAndy Fiddaman U32_8_t* a; 648*b30d1939SAndy Fiddaman int s; 649*b30d1939SAndy Fiddaman int i; 650*b30d1939SAndy Fiddaman 651*b30d1939SAndy Fiddaman s = (int)(integralof(p) & (sizeof(u.i) - 1)); 652*b30d1939SAndy Fiddaman a = (U32_8_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1))); 653*b30d1939SAndy Fiddaman for (;;) 654*b30d1939SAndy Fiddaman { 655*b30d1939SAndy Fiddaman u.i = a->i; 656*b30d1939SAndy Fiddaman u.c[s] = o; 657*b30d1939SAndy Fiddaman v.i = u.i; 658*b30d1939SAndy Fiddaman v.c[s] = n; 659*b30d1939SAndy Fiddaman if (_aso_cas32(&a->i, u.i, v.i) == u.i) 660*b30d1939SAndy Fiddaman break; 661*b30d1939SAndy Fiddaman for (i = 0;; i++) 662*b30d1939SAndy Fiddaman if (i >= elementsof(u.c)) 663*b30d1939SAndy Fiddaman return a->c[s]; 664*b30d1939SAndy Fiddaman else if (i != s && u.c[i] != a->c[i]) 665*b30d1939SAndy Fiddaman break; 666*b30d1939SAndy Fiddaman } 667*b30d1939SAndy Fiddaman return o; 668*b30d1939SAndy Fiddaman } 669*b30d1939SAndy Fiddaman #elif defined(_aso_cas64) 670*b30d1939SAndy Fiddaman if (!state.lockf) 671*b30d1939SAndy Fiddaman { 672*b30d1939SAndy Fiddaman U64_8_t u; 673*b30d1939SAndy Fiddaman U64_8_t v; 674*b30d1939SAndy Fiddaman U64_8_t* a; 675*b30d1939SAndy Fiddaman int s; 676*b30d1939SAndy Fiddaman int i; 677*b30d1939SAndy Fiddaman 678*b30d1939SAndy Fiddaman s = (int)(integralof(p) & (sizeof(u.i) - 1)); 679*b30d1939SAndy Fiddaman a = (U64_8_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1))); 680*b30d1939SAndy Fiddaman for (;;) 681*b30d1939SAndy Fiddaman { 682*b30d1939SAndy Fiddaman u.i = a->i; 683*b30d1939SAndy Fiddaman u.c[s] = o; 684*b30d1939SAndy Fiddaman v.i = u.i; 685*b30d1939SAndy Fiddaman v.c[s] = n; 686*b30d1939SAndy Fiddaman if (_aso_cas64(&a->i, u.i, v.i) == u.i) 687*b30d1939SAndy Fiddaman break; 688*b30d1939SAndy Fiddaman for (i = 0;; i++) 689*b30d1939SAndy Fiddaman if (i >= elementsof(u.c)) 690*b30d1939SAndy Fiddaman return a->c[s]; 691*b30d1939SAndy Fiddaman else if (i != s && u.c[i] != a->c[i]) 692*b30d1939SAndy Fiddaman break; 693*b30d1939SAndy Fiddaman } 694*b30d1939SAndy Fiddaman return o; 695*b30d1939SAndy Fiddaman } 696*b30d1939SAndy Fiddaman #endif 697*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 698*b30d1939SAndy Fiddaman if (*p == o) 699*b30d1939SAndy Fiddaman *p = n; 700*b30d1939SAndy Fiddaman else 701*b30d1939SAndy Fiddaman o = *p; 702*b30d1939SAndy Fiddaman lock(state.data, k, p); 703*b30d1939SAndy Fiddaman return o; 704*b30d1939SAndy Fiddaman } 705*b30d1939SAndy Fiddaman 706*b30d1939SAndy Fiddaman uint16_t 707*b30d1939SAndy Fiddaman asocas16(uint16_t volatile* p, uint16_t o, uint16_t n) 708*b30d1939SAndy Fiddaman { 709*b30d1939SAndy Fiddaman ssize_t k; 710*b30d1939SAndy Fiddaman 711*b30d1939SAndy Fiddaman #if defined(_aso_cas16) 712*b30d1939SAndy Fiddaman if (!state.lockf) 713*b30d1939SAndy Fiddaman return _aso_cas16(p, o, n); 714*b30d1939SAndy Fiddaman #elif defined(_aso_cas32) 715*b30d1939SAndy Fiddaman if (!state.lockf) 716*b30d1939SAndy Fiddaman { 717*b30d1939SAndy Fiddaman U32_16_t u; 718*b30d1939SAndy Fiddaman U32_16_t v; 719*b30d1939SAndy Fiddaman U32_16_t* a; 720*b30d1939SAndy Fiddaman int s; 721*b30d1939SAndy Fiddaman int i; 722*b30d1939SAndy Fiddaman 723*b30d1939SAndy Fiddaman s = (int)(integralof(p) & (sizeof(u.i) - 1)) / 2; 724*b30d1939SAndy Fiddaman a = (U32_16_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1))); 725*b30d1939SAndy Fiddaman for (;;) 726*b30d1939SAndy Fiddaman { 727*b30d1939SAndy Fiddaman u.i = a->i; 728*b30d1939SAndy Fiddaman u.c[s] = o; 729*b30d1939SAndy Fiddaman v.i = u.i; 730*b30d1939SAndy Fiddaman v.c[s] = n; 731*b30d1939SAndy Fiddaman if (_aso_cas32(&a->i, u.i, v.i) == u.i) 732*b30d1939SAndy Fiddaman break; 733*b30d1939SAndy Fiddaman for (i = 0;; i++) 734*b30d1939SAndy Fiddaman if (i >= elementsof(u.c)) 735*b30d1939SAndy Fiddaman return a->c[s]; 736*b30d1939SAndy Fiddaman else if (i != s && u.c[i] != a->c[i]) 737*b30d1939SAndy Fiddaman break; 738*b30d1939SAndy Fiddaman } 739*b30d1939SAndy Fiddaman return o; 740*b30d1939SAndy Fiddaman } 741*b30d1939SAndy Fiddaman #elif defined(_aso_cas64) 742*b30d1939SAndy Fiddaman if (!state.lockf) 743*b30d1939SAndy Fiddaman { 744*b30d1939SAndy Fiddaman U64_16_t u; 745*b30d1939SAndy Fiddaman U64_16_t v; 746*b30d1939SAndy Fiddaman U64_16_t* a; 747*b30d1939SAndy Fiddaman int s; 748*b30d1939SAndy Fiddaman int i; 749*b30d1939SAndy Fiddaman 750*b30d1939SAndy Fiddaman s = (int)(integralof(p) & (sizeof(u.i) - 1)) / 2; 751*b30d1939SAndy Fiddaman a = (U64_16_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1))); 752*b30d1939SAndy Fiddaman for (;;) 753*b30d1939SAndy Fiddaman { 754*b30d1939SAndy Fiddaman u.i = a->i; 755*b30d1939SAndy Fiddaman u.c[s] = o; 756*b30d1939SAndy Fiddaman v.i = u.i; 757*b30d1939SAndy Fiddaman v.c[s] = n; 758*b30d1939SAndy Fiddaman if (_aso_cas64(&a->i, u.i, v.i) == u.i) 759*b30d1939SAndy Fiddaman break; 760*b30d1939SAndy Fiddaman for (i = 0;; i++) 761*b30d1939SAndy Fiddaman if (i >= elementsof(u.c)) 762*b30d1939SAndy Fiddaman return a->c[s]; 763*b30d1939SAndy Fiddaman else if (i != s && u.c[i] != a->c[i]) 764*b30d1939SAndy Fiddaman break; 765*b30d1939SAndy Fiddaman } 766*b30d1939SAndy Fiddaman return o; 767*b30d1939SAndy Fiddaman } 768*b30d1939SAndy Fiddaman #endif 769*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 770*b30d1939SAndy Fiddaman if (*p == o) 771*b30d1939SAndy Fiddaman *p = n; 772*b30d1939SAndy Fiddaman else 773*b30d1939SAndy Fiddaman o = *p; 774*b30d1939SAndy Fiddaman lock(state.data, k, p); 775*b30d1939SAndy Fiddaman return o; 776*b30d1939SAndy Fiddaman } 777*b30d1939SAndy Fiddaman 778*b30d1939SAndy Fiddaman uint32_t 779*b30d1939SAndy Fiddaman asocas32(uint32_t volatile* p, uint32_t o, uint32_t n) 780*b30d1939SAndy Fiddaman { 781*b30d1939SAndy Fiddaman ssize_t k; 782*b30d1939SAndy Fiddaman 783*b30d1939SAndy Fiddaman #if defined(_aso_cas32) 784*b30d1939SAndy Fiddaman if (!state.lockf) 785*b30d1939SAndy Fiddaman return _aso_cas32(p, o, n); 786*b30d1939SAndy Fiddaman #elif defined(_aso_cas64) 787*b30d1939SAndy Fiddaman if (!state.lockf) 788*b30d1939SAndy Fiddaman { 789*b30d1939SAndy Fiddaman U64_32_t u; 790*b30d1939SAndy Fiddaman U64_32_t v; 791*b30d1939SAndy Fiddaman U64_32_t* a; 792*b30d1939SAndy Fiddaman int s; 793*b30d1939SAndy Fiddaman int i; 794*b30d1939SAndy Fiddaman 795*b30d1939SAndy Fiddaman s = (int)(integralof(p) & (sizeof(u.i) - 1)) / 4; 796*b30d1939SAndy Fiddaman a = (U64_32_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1))); 797*b30d1939SAndy Fiddaman for (;;) 798*b30d1939SAndy Fiddaman { 799*b30d1939SAndy Fiddaman u.i = a->i; 800*b30d1939SAndy Fiddaman u.c[s] = o; 801*b30d1939SAndy Fiddaman v.i = u.i; 802*b30d1939SAndy Fiddaman v.c[s] = n; 803*b30d1939SAndy Fiddaman if (_aso_cas64(&a->i, u.i, v.i) == u.i) 804*b30d1939SAndy Fiddaman break; 805*b30d1939SAndy Fiddaman for (i = 0;; i++) 806*b30d1939SAndy Fiddaman if (i >= elementsof(u.c)) 807*b30d1939SAndy Fiddaman return a->c[s]; 808*b30d1939SAndy Fiddaman else if (i != s && u.c[i] != a->c[i]) 809*b30d1939SAndy Fiddaman break; 810*b30d1939SAndy Fiddaman } 811*b30d1939SAndy Fiddaman return o; 812*b30d1939SAndy Fiddaman } 813*b30d1939SAndy Fiddaman #endif 814*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 815*b30d1939SAndy Fiddaman if (*p == o) 816*b30d1939SAndy Fiddaman *p = n; 817*b30d1939SAndy Fiddaman else 818*b30d1939SAndy Fiddaman o = *p; 819*b30d1939SAndy Fiddaman lock(state.data, k, p); 820*b30d1939SAndy Fiddaman return o; 821*b30d1939SAndy Fiddaman } 822*b30d1939SAndy Fiddaman 823*b30d1939SAndy Fiddaman #ifdef _ast_int8_t 824*b30d1939SAndy Fiddaman 825*b30d1939SAndy Fiddaman uint64_t 826*b30d1939SAndy Fiddaman asocas64(uint64_t volatile* p, uint64_t o, uint64_t n) 827*b30d1939SAndy Fiddaman { 828*b30d1939SAndy Fiddaman ssize_t k; 829*b30d1939SAndy Fiddaman 830*b30d1939SAndy Fiddaman #if defined(_aso_cas64) 831*b30d1939SAndy Fiddaman if (!state.lockf) 832*b30d1939SAndy Fiddaman return _aso_cas64(p, o, n); 833*b30d1939SAndy Fiddaman #endif 834*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 835*b30d1939SAndy Fiddaman if (*p == o) 836*b30d1939SAndy Fiddaman *p = n; 837*b30d1939SAndy Fiddaman else 838*b30d1939SAndy Fiddaman o = *p; 839*b30d1939SAndy Fiddaman lock(state.data, k, p); 840*b30d1939SAndy Fiddaman return o; 841*b30d1939SAndy Fiddaman } 842*b30d1939SAndy Fiddaman 843*b30d1939SAndy Fiddaman #endif 844*b30d1939SAndy Fiddaman 845*b30d1939SAndy Fiddaman /* 846*b30d1939SAndy Fiddaman * compare with old, swap with new if same, and return old value 847*b30d1939SAndy Fiddaman */ 848*b30d1939SAndy Fiddaman 849*b30d1939SAndy Fiddaman void* 850*b30d1939SAndy Fiddaman asocasptr(void volatile* p, void* o, void* n) 851*b30d1939SAndy Fiddaman { 852*b30d1939SAndy Fiddaman ssize_t k; 853*b30d1939SAndy Fiddaman 854*b30d1939SAndy Fiddaman #if defined(_aso_casptr) 855*b30d1939SAndy Fiddaman if (!state.lockf) 856*b30d1939SAndy Fiddaman return _aso_casptr((void**)p, o, n); 857*b30d1939SAndy Fiddaman #endif 858*b30d1939SAndy Fiddaman k = lock(state.data, 0, p); 859*b30d1939SAndy Fiddaman if (*(void* volatile*)p == o) 860*b30d1939SAndy Fiddaman *(void* volatile*)p = n; 861*b30d1939SAndy Fiddaman else 862*b30d1939SAndy Fiddaman o = *(void* volatile*)p; 863*b30d1939SAndy Fiddaman lock(state.data, k, p); 864*b30d1939SAndy Fiddaman return o; 865*b30d1939SAndy Fiddaman } 866*b30d1939SAndy Fiddaman 867*b30d1939SAndy Fiddaman #endif 868