mutex.h revision 1.2
11.2Sad/* $NetBSD: mutex.h,v 1.2 2007/02/09 21:55:12 ad Exp $ */ 21.2Sad 31.2Sad/*- 41.2Sad * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc. 51.2Sad * All rights reserved. 61.2Sad * 71.2Sad * This code is derived from software contributed to The NetBSD Foundation 81.2Sad * by Jason R. Thorpe and Andrew Doran. 91.2Sad * 101.2Sad * Redistribution and use in source and binary forms, with or without 111.2Sad * modification, are permitted provided that the following conditions 121.2Sad * are met: 131.2Sad * 1. Redistributions of source code must retain the above copyright 141.2Sad * notice, this list of conditions and the following disclaimer. 151.2Sad * 2. Redistributions in binary form must reproduce the above copyright 161.2Sad * notice, this list of conditions and the following disclaimer in the 171.2Sad * documentation and/or other materials provided with the distribution. 181.2Sad * 3. All advertising materials mentioning features or use of this software 191.2Sad * must display the following acknowledgement: 201.2Sad * This product includes software developed by the NetBSD 211.2Sad * Foundation, Inc. and its contributors. 221.2Sad * 4. Neither the name of The NetBSD Foundation nor the names of its 231.2Sad * contributors may be used to endorse or promote products derived 241.2Sad * from this software without specific prior written permission. 251.2Sad * 261.2Sad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 271.2Sad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 281.2Sad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 291.2Sad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 301.2Sad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 311.2Sad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 321.2Sad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 331.2Sad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 341.2Sad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 351.2Sad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 361.2Sad * POSSIBILITY OF SUCH DAMAGE. 371.2Sad */ 381.2Sad 391.2Sad#ifndef _SH3_MUTEX_H_ 401.2Sad#define _SH3_MUTEX_H_ 411.2Sad 421.2Sad/* 431.2Sad * The SH3 mutex implementation is troublesome, because SH3 lacks 441.2Sad * a pointer sized compare-and-set operation. SMP for spin mutexes 451.2Sad * is easy - we don't need to know who owns the lock. For adaptive 461.2Sad * mutexes, we need an owner field and additional interlock 471.2Sad * 481.2Sad * See arch/sparc/include/mutex.h for a more detailed description. 491.2Sad */ 501.2Sad 511.2Sad#ifndef __MUTEX_PRIVATE 521.2Sad 531.2Sadstruct kmutex { 541.2Sad uintptr_t mtx_pad1; 551.2Sad uint32_t mtx_pad2; 561.2Sad}; 571.2Sad 581.2Sad#else /* __MUTEX_PRIVATE */ 591.2Sad 601.2Sadstruct kmutex { 611.2Sad union { 621.2Sad /* Adaptive mutex */ 631.2Sad volatile uintptr_t mtxu_owner; /* 0-3 */ 641.2Sad __cpu_simple_lock_t mtxu_interlock; /* 0 */ 651.2Sad 661.2Sad /* Spin mutex. */ 671.2Sad struct { 681.2Sad uint8_t mtxs_dummy; /* 0 */ 691.2Sad uint8_t mtxs_unused1; /* 1 */ 701.2Sad ipl_cookie_t mtxs_ipl; /* 2 */ 711.2Sad uint8_t mtxs_unused2; /* 3 */ 721.2Sad } s; 731.2Sad } u; 741.2Sad __cpu_simple_lock_t mtx_lock; /* 4 */ 751.2Sad uint8_t mtx_idtype[3]; /* 5-7 */ 761.2Sad}; 771.2Sad 781.2Sad#define __HAVE_MUTEX_STUBS 1 791.2Sad 801.2Sad#define mtx_owner u.mtxu_owner 811.2Sad#define mtx_interlock u.mtxu_interlock 821.2Sad#define mtx_dummy u.s.mtxs_dummy 831.2Sad#define mtx_ipl u.s.mtxs_ipl 841.2Sad 851.2Sadstatic inline uintptr_t 861.2SadMUTEX_OWNER(uintptr_t owner) 871.2Sad{ 881.2Sad return owner << 6; 891.2Sad} 901.2Sad 911.2Sadstatic inline int 921.2SadMUTEX_OWNED(uintptr_t owner) 931.2Sad{ 941.2Sad return owner != 0; 951.2Sad} 961.2Sad 971.2Sadstatic inline int 981.2SadMUTEX_SET_WAITERS(kmutex_t *mtx, uintptr_t owner) 991.2Sad{ 1001.2Sad (void)__cpu_simple_lock_try(&mtx->mtx_lock); 1011.2Sad return mtx->mtx_owner != 0; 1021.2Sad} 1031.2Sad 1041.2Sadstatic inline int 1051.2SadMUTEX_HAS_WAITERS(volatile kmutex_t *mtx) 1061.2Sad{ 1071.2Sad if (mtx->mtx_owner == 0) 1081.2Sad return 0; 1091.2Sad return mtx->mtx_lock == __SIMPLELOCK_LOCKED; 1101.2Sad} 1111.2Sad 1121.2Sadstatic inline void 1131.2SadMUTEX_INITIALIZE_SPIN(kmutex_t *mtx, u_int id, int ipl) 1141.2Sad{ 1151.2Sad mtx->mtx_idtype[0] = (uint8_t)id; 1161.2Sad mtx->mtx_idtype[1] = (uint8_t)(id >> 8); 1171.2Sad mtx->mtx_idtype[2] = (uint8_t)((id >> 16) | 0x80); 1181.2Sad mtx->mtx_ipl = makeiplcookie(ipl); 1191.2Sad mtx->mtx_interlock = __SIMPLELOCK_LOCKED; 1201.2Sad __cpu_simple_lock_init(&mtx->mtx_lock); 1211.2Sad} 1221.2Sad 1231.2Sadstatic inline void 1241.2SadMUTEX_INITIALIZE_ADAPTIVE(kmutex_t *mtx, u_int id) 1251.2Sad{ 1261.2Sad mtx->mtx_idtype[0] = (uint8_t)id; 1271.2Sad mtx->mtx_idtype[1] = (uint8_t)(id >> 8); 1281.2Sad mtx->mtx_idtype[2] = (uint8_t)(id >> 16); 1291.2Sad __cpu_simple_lock_init(&mtx->mtx_lock); 1301.2Sad} 1311.2Sad 1321.2Sadstatic inline void 1331.2SadMUTEX_DESTROY(kmutex_t *mtx) 1341.2Sad{ 1351.2Sad mtx->mtx_owner = (uintptr_t)-1L; 1361.2Sad mtx->mtx_idtype[0] = 0xff; 1371.2Sad mtx->mtx_idtype[1] = 0xff; 1381.2Sad mtx->mtx_idtype[2] = 0xff; 1391.2Sad} 1401.2Sad 1411.2Sadstatic inline u_int 1421.2SadMUTEX_GETID(kmutex_t *mtx) 1431.2Sad{ 1441.2Sad return (u_int)mtx->mtx_idtype[0] | 1451.2Sad ((u_int)mtx->mtx_idtype[1] << 8) | 1461.2Sad (((u_int)mtx->mtx_idtype[2] & 0x7f) << 16); 1471.2Sad} 1481.2Sad 1491.2Sadstatic inline int 1501.2SadMUTEX_SPIN_P(volatile kmutex_t *mtx) 1511.2Sad{ 1521.2Sad return mtx->mtx_idtype[2] & 0x80; 1531.2Sad} 1541.2Sad 1551.2Sadstatic inline int 1561.2SadMUTEX_ADAPTIVE_P(volatile kmutex_t *mtx) 1571.2Sad{ 1581.2Sad return (mtx->mtx_idtype[2] & 0x80) == 0; 1591.2Sad} 1601.2Sad 1611.2Sadstatic inline int 1621.2SadMUTEX_ACQUIRE(kmutex_t *mtx, uintptr_t curthread) 1631.2Sad{ 1641.2Sad if (!__cpu_simple_lock_try(&mtx->mtx_interlock)) 1651.2Sad return 0; 1661.2Sad mtx->mtx_owner = (curthread >> 6) | 0xfa000000; 1671.2Sad return 1; 1681.2Sad} 1691.2Sad 1701.2Sadstatic inline void 1711.2SadMUTEX_RELEASE(kmutex_t *mtx) 1721.2Sad{ 1731.2Sad mtx->mtx_owner = 0; 1741.2Sad __cpu_simple_unlock(&mtx->mtx_lock); 1751.2Sad} 1761.2Sad 1771.2Sad#endif /* __MUTEX_PRIVATE */ 1781.2Sad 1791.2Sad#endif /* _SH3_MUTEX_H_ */ 180