lock.h revision 1.19
11.19Smatt/* $NetBSD: lock.h,v 1.19 2015/06/01 22:55:13 matt Exp $ */ 21.1Sthorpej 31.1Sthorpej/*- 41.10Sad * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc. 51.1Sthorpej * All rights reserved. 61.1Sthorpej * 71.1Sthorpej * This code is derived from software contributed to The NetBSD Foundation 81.10Sad * by Wayne Knowles and Andrew Doran. 91.1Sthorpej * 101.1Sthorpej * Redistribution and use in source and binary forms, with or without 111.1Sthorpej * modification, are permitted provided that the following conditions 121.1Sthorpej * are met: 131.1Sthorpej * 1. Redistributions of source code must retain the above copyright 141.1Sthorpej * notice, this list of conditions and the following disclaimer. 151.1Sthorpej * 2. Redistributions in binary form must reproduce the above copyright 161.1Sthorpej * notice, this list of conditions and the following disclaimer in the 171.1Sthorpej * documentation and/or other materials provided with the distribution. 181.1Sthorpej * 191.1Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.1Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.1Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.1Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.1Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.1Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.1Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.1Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.1Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.1Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.1Sthorpej * POSSIBILITY OF SUCH DAMAGE. 301.1Sthorpej */ 311.1Sthorpej 321.1Sthorpej/* 331.10Sad * Machine-dependent spin lock operations for MIPS processors. 341.3Sgmcgarry * 351.10Sad * Note: R2000/R3000 doesn't have any atomic update instructions; this 361.10Sad * will cause problems for user applications using this header. 371.1Sthorpej */ 381.1Sthorpej 391.1Sthorpej#ifndef _MIPS_LOCK_H_ 401.1Sthorpej#define _MIPS_LOCK_H_ 411.3Sgmcgarry 421.17Spooka#include <sys/param.h> 431.17Spooka 441.13Sskrllstatic __inline int 451.13Sskrll__SIMPLELOCK_LOCKED_P(__cpu_simple_lock_t *__ptr) 461.13Sskrll{ 471.18Smatt return *__ptr != __SIMPLELOCK_UNLOCKED; 481.13Sskrll} 491.13Sskrll 501.13Sskrllstatic __inline int 511.13Sskrll__SIMPLELOCK_UNLOCKED_P(__cpu_simple_lock_t *__ptr) 521.13Sskrll{ 531.13Sskrll return *__ptr == __SIMPLELOCK_UNLOCKED; 541.13Sskrll} 551.13Sskrll 561.13Sskrllstatic __inline void 571.13Sskrll__cpu_simple_lock_clear(__cpu_simple_lock_t *__ptr) 581.13Sskrll{ 591.13Sskrll *__ptr = __SIMPLELOCK_UNLOCKED; 601.13Sskrll} 611.13Sskrll 621.13Sskrllstatic __inline void 631.13Sskrll__cpu_simple_lock_set(__cpu_simple_lock_t *__ptr) 641.13Sskrll{ 651.13Sskrll *__ptr = __SIMPLELOCK_LOCKED; 661.13Sskrll} 671.13Sskrll 681.17Spooka#ifndef _HARDKERNEL 691.3Sgmcgarry 701.8Sperrystatic __inline int 711.3Sgmcgarry__cpu_simple_lock_try(__cpu_simple_lock_t *lp) 721.3Sgmcgarry{ 731.3Sgmcgarry unsigned long t0, v0; 741.3Sgmcgarry 751.7Sperry __asm volatile( 761.3Sgmcgarry "# -- BEGIN __cpu_simple_lock_try\n" 771.3Sgmcgarry " .set push \n" 781.3Sgmcgarry " .set mips2 \n" 791.3Sgmcgarry "1: ll %0, %4 \n" 801.3Sgmcgarry " bnez %0, 2f \n" 811.3Sgmcgarry " nop # BDslot \n" 821.3Sgmcgarry " li %0, %3 \n" 831.3Sgmcgarry " sc %0, %2 \n" 841.3Sgmcgarry " beqz %0, 2f \n" 851.3Sgmcgarry " nop # BDslot \n" 861.3Sgmcgarry " li %1, 1 \n" 871.3Sgmcgarry " sync \n" 881.3Sgmcgarry " j 3f \n" 891.3Sgmcgarry " nop \n" 901.3Sgmcgarry " nop \n" 911.3Sgmcgarry "2: li %1, 0 \n" 921.3Sgmcgarry "3: \n" 931.3Sgmcgarry " .set pop \n" 941.3Sgmcgarry "# -- END __cpu_simple_lock_try \n" 951.3Sgmcgarry : "=r" (t0), "=r" (v0), "+m" (*lp) 961.9Ssimonb : "i" (__SIMPLELOCK_LOCKED), "m" (*lp)); 971.3Sgmcgarry 981.3Sgmcgarry return (v0 != 0); 991.3Sgmcgarry} 1001.3Sgmcgarry 1011.10Sad#ifdef MIPS1 1021.10Sadstatic __inline void 1031.10Sadmb_read(void) 1041.10Sad{ 1051.10Sad __insn_barrier(); 1061.10Sad} 1071.10Sad 1081.10Sadstatic __inline void 1091.10Sadmb_write(void) 1101.10Sad{ 1111.10Sad __insn_barrier(); 1121.10Sad} 1131.10Sad 1141.10Sadstatic __inline void 1151.10Sadmb_memory(void) 1161.10Sad{ 1171.10Sad __insn_barrier(); 1181.10Sad} 1191.10Sad#else /* MIPS1*/ 1201.10Sadstatic __inline void 1211.10Sadmb_read(void) 1221.10Sad{ 1231.12Sad __asm volatile( 1241.12Sad " .set push\n" 1251.12Sad " .set mips2\n" 1261.12Sad " sync\n" 1271.12Sad " .set pop" 1281.12Sad ::: "memory" 1291.12Sad ); 1301.10Sad} 1311.10Sad 1321.10Sadstatic __inline void 1331.10Sadmb_write(void) 1341.10Sad{ 1351.12Sad mb_read(); 1361.10Sad} 1371.10Sad 1381.10Sadstatic __inline void 1391.10Sadmb_memory(void) 1401.10Sad{ 1411.12Sad mb_read(); 1421.10Sad} 1431.10Sad#endif /* MIPS1 */ 1441.10Sad 1451.17Spooka#else /* !_HARDKERNEL */ 1461.10Sad 1471.18Smattu_int _atomic_cas_uint(volatile u_int *, u_int, u_int); 1481.18Smattu_long _atomic_cas_ulong(volatile u_long *, u_long, u_long); 1491.18Smattvoid * _atomic_cas_ptr(volatile void *, void *, void *); 1501.10Sadvoid mb_read(void); 1511.10Sadvoid mb_write(void); 1521.10Sadvoid mb_memory(void); 1531.10Sad 1541.10Sadstatic __inline int 1551.10Sad__cpu_simple_lock_try(__cpu_simple_lock_t *lp) 1561.10Sad{ 1571.10Sad 1581.18Smatt return _atomic_cas_uint(lp, 1591.15Sad __SIMPLELOCK_UNLOCKED, __SIMPLELOCK_LOCKED) == 1601.15Sad __SIMPLELOCK_UNLOCKED; 1611.10Sad} 1621.10Sad 1631.17Spooka#endif /* _HARDKERNEL */ 1641.10Sad 1651.10Sadstatic __inline void 1661.10Sad__cpu_simple_lock_init(__cpu_simple_lock_t *lp) 1671.10Sad{ 1681.10Sad 1691.10Sad *lp = __SIMPLELOCK_UNLOCKED; 1701.10Sad mb_memory(); 1711.10Sad} 1721.10Sad 1731.10Sadstatic __inline void 1741.10Sad__cpu_simple_lock(__cpu_simple_lock_t *lp) 1751.10Sad{ 1761.10Sad 1771.18Smatt while (!__cpu_simple_lock_try(lp)) { 1781.10Sad while (*lp == __SIMPLELOCK_LOCKED) 1791.10Sad /* spin */; 1801.18Smatt } 1811.10Sad} 1821.10Sad 1831.8Sperrystatic __inline void 1841.3Sgmcgarry__cpu_simple_unlock(__cpu_simple_lock_t *lp) 1851.3Sgmcgarry{ 1861.3Sgmcgarry 1871.19Smatt#ifndef _MIPS_ARCH_OCTEONP 1881.10Sad mb_memory(); 1891.19Smatt#endif 1901.10Sad *lp = __SIMPLELOCK_UNLOCKED; 1911.19Smatt#ifdef _MIPS_ARCH_OCTEONP 1921.19Smatt mb_write(); 1931.19Smatt#endif 1941.3Sgmcgarry} 1951.10Sad 1961.1Sthorpej#endif /* _MIPS_LOCK_H_ */ 197