183a81bcbSJohn Baldwin /*- 283a81bcbSJohn Baldwin * Copyright (c) 2006 John Baldwin <jhb@FreeBSD.org> 383a81bcbSJohn Baldwin * All rights reserved. 483a81bcbSJohn Baldwin * 583a81bcbSJohn Baldwin * Redistribution and use in source and binary forms, with or without 683a81bcbSJohn Baldwin * modification, are permitted provided that the following conditions 783a81bcbSJohn Baldwin * are met: 883a81bcbSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 983a81bcbSJohn Baldwin * notice, this list of conditions and the following disclaimer. 1083a81bcbSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 1183a81bcbSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 1283a81bcbSJohn Baldwin * documentation and/or other materials provided with the distribution. 1383a81bcbSJohn Baldwin * 3. Neither the name of the author nor the names of any co-contributors 1483a81bcbSJohn Baldwin * may be used to endorse or promote products derived from this software 1583a81bcbSJohn Baldwin * without specific prior written permission. 1683a81bcbSJohn Baldwin * 1783a81bcbSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1883a81bcbSJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1983a81bcbSJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2083a81bcbSJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2183a81bcbSJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2283a81bcbSJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2383a81bcbSJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2483a81bcbSJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2583a81bcbSJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2683a81bcbSJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2783a81bcbSJohn Baldwin * SUCH DAMAGE. 2883a81bcbSJohn Baldwin */ 2983a81bcbSJohn Baldwin 3083a81bcbSJohn Baldwin /* 3183a81bcbSJohn Baldwin * This module holds the global variables and functions used to maintain 3283a81bcbSJohn Baldwin * lock_object structures. 3383a81bcbSJohn Baldwin */ 3483a81bcbSJohn Baldwin 3583a81bcbSJohn Baldwin #include <sys/cdefs.h> 3683a81bcbSJohn Baldwin __FBSDID("$FreeBSD$"); 3783a81bcbSJohn Baldwin 3883a81bcbSJohn Baldwin #include <sys/param.h> 3983a81bcbSJohn Baldwin #include <sys/systm.h> 4083a81bcbSJohn Baldwin #include <sys/ktr.h> 4183a81bcbSJohn Baldwin #include <sys/lock.h> 4283a81bcbSJohn Baldwin 4383a81bcbSJohn Baldwin #ifdef DDB 4483a81bcbSJohn Baldwin #include <ddb/ddb.h> 4583a81bcbSJohn Baldwin #endif 4683a81bcbSJohn Baldwin 4783a81bcbSJohn Baldwin CTASSERT(LOCK_CLASS_MAX == 15); 4883a81bcbSJohn Baldwin 4983a81bcbSJohn Baldwin #if LOCK_DEBUG > 0 || defined(DDB) 5083a81bcbSJohn Baldwin struct lock_class *lock_classes[LOCK_CLASS_MAX + 1] = { 5183a81bcbSJohn Baldwin &lock_class_mtx_spin, 5283a81bcbSJohn Baldwin &lock_class_mtx_sleep, 5383a81bcbSJohn Baldwin &lock_class_sx, 5483a81bcbSJohn Baldwin }; 5583a81bcbSJohn Baldwin #endif 5683a81bcbSJohn Baldwin 5783a81bcbSJohn Baldwin void 5883a81bcbSJohn Baldwin lock_init(struct lock_object *lock, struct lock_class *class, const char *name, 5983a81bcbSJohn Baldwin const char *type, int flags) 6083a81bcbSJohn Baldwin { 6183a81bcbSJohn Baldwin int i; 6283a81bcbSJohn Baldwin 6383a81bcbSJohn Baldwin /* Check for double-init and zero object. */ 6483a81bcbSJohn Baldwin KASSERT(!lock_initalized(lock), ("lock \"%s\" %p already initialized", 6583a81bcbSJohn Baldwin name, lock)); 6683a81bcbSJohn Baldwin 6783a81bcbSJohn Baldwin /* Look up lock class to find its index. */ 6883a81bcbSJohn Baldwin for (i = 0; i < LOCK_CLASS_MAX; i++) 6983a81bcbSJohn Baldwin if (lock_classes[i] == class) { 7083a81bcbSJohn Baldwin lock->lo_flags = i << LO_CLASSSHIFT; 7183a81bcbSJohn Baldwin break; 7283a81bcbSJohn Baldwin } 7383a81bcbSJohn Baldwin KASSERT(i < LOCK_CLASS_MAX, ("unknown lock class %p", class)); 7483a81bcbSJohn Baldwin 7583a81bcbSJohn Baldwin /* Initialize the lock object. */ 7683a81bcbSJohn Baldwin lock->lo_name = name; 7783a81bcbSJohn Baldwin lock->lo_type = type != NULL ? type : name; 7883a81bcbSJohn Baldwin lock->lo_flags |= flags | LO_INITIALIZED; 7983a81bcbSJohn Baldwin LOCK_LOG_INIT(lock, 0); 8083a81bcbSJohn Baldwin WITNESS_INIT(lock); 8183a81bcbSJohn Baldwin } 8283a81bcbSJohn Baldwin 8383a81bcbSJohn Baldwin void 8483a81bcbSJohn Baldwin lock_destroy(struct lock_object *lock) 8583a81bcbSJohn Baldwin { 8683a81bcbSJohn Baldwin 8783a81bcbSJohn Baldwin KASSERT(lock_initalized(lock), ("lock %p is not initialized", lock)); 8883a81bcbSJohn Baldwin WITNESS_DESTROY(lock); 8983a81bcbSJohn Baldwin LOCK_LOG_DESTROY(lock, 0); 9083a81bcbSJohn Baldwin lock->lo_flags &= ~LO_INITIALIZED; 9183a81bcbSJohn Baldwin } 9283a81bcbSJohn Baldwin 9383a81bcbSJohn Baldwin #ifdef DDB 9483a81bcbSJohn Baldwin DB_SHOW_COMMAND(lock, db_show_lock) 9583a81bcbSJohn Baldwin { 9683a81bcbSJohn Baldwin struct lock_object *lock; 9783a81bcbSJohn Baldwin struct lock_class *class; 9883a81bcbSJohn Baldwin 9983a81bcbSJohn Baldwin if (!have_addr) 10083a81bcbSJohn Baldwin return; 10183a81bcbSJohn Baldwin lock = (struct lock_object *)addr; 10283a81bcbSJohn Baldwin if (LO_CLASSINDEX(lock) > LOCK_CLASS_MAX) { 10383a81bcbSJohn Baldwin db_printf("Unknown lock class: %d\n", LO_CLASSINDEX(lock)); 10483a81bcbSJohn Baldwin return; 10583a81bcbSJohn Baldwin } 10683a81bcbSJohn Baldwin class = LOCK_CLASS(lock); 10783a81bcbSJohn Baldwin db_printf(" class: %s\n", class->lc_name); 10883a81bcbSJohn Baldwin db_printf(" name: %s\n", lock->lo_name); 10983a81bcbSJohn Baldwin if (lock->lo_type && lock->lo_type != lock->lo_name) 11083a81bcbSJohn Baldwin db_printf(" type: %s\n", lock->lo_type); 11183a81bcbSJohn Baldwin class->lc_ddb_show(lock); 11283a81bcbSJohn Baldwin } 11383a81bcbSJohn Baldwin #endif 114