[BACK]Return to kern_mutex_obj.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Annotation of src/sys/kern/kern_mutex_obj.c, Revision 1.10

1.10    ! riastrad    1: /*     $NetBSD: kern_mutex_obj.c,v 1.9 2022/04/09 23:38:33 riastradh Exp $     */
1.1       pooka       2:
                      3: /*-
1.7       ad          4:  * Copyright (c) 2008, 2019 The NetBSD Foundation, Inc.
1.1       pooka       5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
1.2       ad          8:  * by Andrew Doran.
1.1       pooka       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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: #include <sys/cdefs.h>
1.10    ! riastrad   33: __KERNEL_RCSID(0, "$NetBSD: kern_mutex_obj.c,v 1.9 2022/04/09 23:38:33 riastradh Exp $");
1.1       pooka      34:
                     35: #include <sys/param.h>
                     36: #include <sys/atomic.h>
                     37: #include <sys/mutex.h>
                     38: #include <sys/pool.h>
                     39:
                     40: /* Mutex cache */
                     41: #define        MUTEX_OBJ_MAGIC 0x5aa3c85d
                     42: struct kmutexobj {
                     43:        kmutex_t        mo_lock;
                     44:        u_int           mo_magic;
                     45:        u_int           mo_refcnt;
                     46: };
                     47:
                     48: static int     mutex_obj_ctor(void *, void *, int);
                     49:
1.3       rmind      50: static pool_cache_t    mutex_obj_cache         __read_mostly;
1.1       pooka      51:
                     52: /*
                     53:  * mutex_obj_init:
                     54:  *
                     55:  *     Initialize the mutex object store.
                     56:  */
                     57: void
                     58: mutex_obj_init(void)
                     59: {
                     60:
                     61:        mutex_obj_cache = pool_cache_init(sizeof(struct kmutexobj),
                     62:            coherency_unit, 0, 0, "mutex", NULL, IPL_NONE, mutex_obj_ctor,
                     63:            NULL, NULL);
                     64: }
                     65:
                     66: /*
                     67:  * mutex_obj_ctor:
                     68:  *
                     69:  *     Initialize a new lock for the cache.
                     70:  */
                     71: static int
                     72: mutex_obj_ctor(void *arg, void *obj, int flags)
                     73: {
                     74:        struct kmutexobj * mo = obj;
                     75:
                     76:        mo->mo_magic = MUTEX_OBJ_MAGIC;
                     77:
                     78:        return 0;
                     79: }
                     80:
                     81: /*
                     82:  * mutex_obj_alloc:
                     83:  *
1.7       ad         84:  *     Allocate a single lock object, waiting for memory if needed.
1.1       pooka      85:  */
                     86: kmutex_t *
                     87: mutex_obj_alloc(kmutex_type_t type, int ipl)
                     88: {
                     89:        struct kmutexobj *mo;
                     90:
                     91:        mo = pool_cache_get(mutex_obj_cache, PR_WAITOK);
1.6       ozaki-r    92:        _mutex_init(&mo->mo_lock, type, ipl,
                     93:            (uintptr_t)__builtin_return_address(0));
1.1       pooka      94:        mo->mo_refcnt = 1;
                     95:
                     96:        return (kmutex_t *)mo;
                     97: }
                     98:
                     99: /*
1.7       ad        100:  * mutex_obj_alloc:
                    101:  *
                    102:  *     Allocate a single lock object, failing if no memory available.
                    103:  */
                    104: kmutex_t *
                    105: mutex_obj_tryalloc(kmutex_type_t type, int ipl)
                    106: {
                    107:        struct kmutexobj *mo;
                    108:
                    109:        mo = pool_cache_get(mutex_obj_cache, PR_NOWAIT);
                    110:        if (__predict_true(mo != NULL)) {
                    111:                _mutex_init(&mo->mo_lock, type, ipl,
                    112:                    (uintptr_t)__builtin_return_address(0));
                    113:                mo->mo_refcnt = 1;
                    114:        }
                    115:
                    116:        return (kmutex_t *)mo;
                    117: }
                    118:
                    119: /*
1.1       pooka     120:  * mutex_obj_hold:
                    121:  *
                    122:  *     Add a single reference to a lock object.  A reference to the object
                    123:  *     must already be held, and must be held across this call.
                    124:  */
                    125: void
                    126: mutex_obj_hold(kmutex_t *lock)
                    127: {
                    128:        struct kmutexobj *mo = (struct kmutexobj *)lock;
                    129:
1.4       matt      130:        KASSERTMSG(mo->mo_magic == MUTEX_OBJ_MAGIC,
1.5       jym       131:            "%s: lock %p: mo->mo_magic (%#x) != MUTEX_OBJ_MAGIC (%#x)",
                    132:             __func__, mo, mo->mo_magic, MUTEX_OBJ_MAGIC);
1.4       matt      133:        KASSERTMSG(mo->mo_refcnt > 0,
1.5       jym       134:            "%s: lock %p: mo->mo_refcnt (%#x) == 0",
                    135:             __func__, mo, mo->mo_refcnt);
1.1       pooka     136:
                    137:        atomic_inc_uint(&mo->mo_refcnt);
                    138: }
                    139:
                    140: /*
                    141:  * mutex_obj_free:
                    142:  *
                    143:  *     Drop a reference from a lock object.  If the last reference is being
                    144:  *     dropped, free the object and return true.  Otherwise, return false.
                    145:  */
                    146: bool
                    147: mutex_obj_free(kmutex_t *lock)
                    148: {
                    149:        struct kmutexobj *mo = (struct kmutexobj *)lock;
                    150:
1.4       matt      151:        KASSERTMSG(mo->mo_magic == MUTEX_OBJ_MAGIC,
1.5       jym       152:            "%s: lock %p: mo->mo_magic (%#x) != MUTEX_OBJ_MAGIC (%#x)",
                    153:             __func__, mo, mo->mo_magic, MUTEX_OBJ_MAGIC);
1.4       matt      154:        KASSERTMSG(mo->mo_refcnt > 0,
1.5       jym       155:            "%s: lock %p: mo->mo_refcnt (%#x) == 0",
                    156:             __func__, mo, mo->mo_refcnt);
1.1       pooka     157:
1.8       riastrad  158: #ifndef __HAVE_ATOMIC_AS_MEMBAR
1.9       riastrad  159:        membar_release();
1.8       riastrad  160: #endif
1.1       pooka     161:        if (atomic_dec_uint_nv(&mo->mo_refcnt) > 0) {
                    162:                return false;
                    163:        }
1.8       riastrad  164: #ifndef __HAVE_ATOMIC_AS_MEMBAR
1.9       riastrad  165:        membar_acquire();
1.8       riastrad  166: #endif
1.1       pooka     167:        mutex_destroy(&mo->mo_lock);
                    168:        pool_cache_put(mutex_obj_cache, mo);
                    169:        return true;
                    170: }
1.7       ad        171:
                    172: /*
                    173:  * mutex_obj_refcnt:
                    174:  *
                    175:  *     Return the reference count on a lock object.
                    176:  */
                    177: u_int
                    178: mutex_obj_refcnt(kmutex_t *lock)
                    179: {
                    180:        struct kmutexobj *mo = (struct kmutexobj *)lock;
                    181:
                    182:        return mo->mo_refcnt;
                    183: }

CVSweb <webmaster@jp.NetBSD.org>