10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57063Sraf * Common Development and Distribution License (the "License"). 67063Sraf * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 217063Sraf 220Sstevel@tonic-gate /* 23*9264SRoger.Faulkner@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #ifndef _SYS_LCHAN_IMPL_H 280Sstevel@tonic-gate #define _SYS_LCHAN_IMPL_H 290Sstevel@tonic-gate 300Sstevel@tonic-gate #ifdef __cplusplus 310Sstevel@tonic-gate extern "C" { 320Sstevel@tonic-gate #endif 330Sstevel@tonic-gate 340Sstevel@tonic-gate #define LWPCHAN_CVPOOL 0 350Sstevel@tonic-gate #define LWPCHAN_MPPOOL 1 360Sstevel@tonic-gate 377063Sraf #define LWPCHAN_INITIAL_BITS 2 /* initially: 4 hash buckets */ 387063Sraf #define LWPCHAN_MAX_BITS 16 /* finally: up to 64K hash buckets */ 390Sstevel@tonic-gate 400Sstevel@tonic-gate /* 410Sstevel@tonic-gate * An lwpchan entry translates a process-shared lwp sync object's 420Sstevel@tonic-gate * virtual address into its logical address, an lwpchan, previously 430Sstevel@tonic-gate * computed via as_getmemid(). 440Sstevel@tonic-gate */ 450Sstevel@tonic-gate typedef struct lwpchan_entry { 460Sstevel@tonic-gate caddr_t lwpchan_addr; /* virtual address */ 47*9264SRoger.Faulkner@Sun.COM caddr_t lwpchan_uaddr; /* address of lock registration */ 480Sstevel@tonic-gate uint16_t lwpchan_type; /* sync object type field */ 490Sstevel@tonic-gate uint16_t lwpchan_pool; /* LWPCHAN_CVPOOL/LWPCHAN_MPPOOL */ 500Sstevel@tonic-gate lwpchan_t lwpchan_lwpchan; /* unique logical address */ 510Sstevel@tonic-gate struct lwpchan_entry *lwpchan_next; /* hash chain */ 520Sstevel@tonic-gate } lwpchan_entry_t; 530Sstevel@tonic-gate 540Sstevel@tonic-gate /* 550Sstevel@tonic-gate * Hash bucket head. The mutex protects the consistency of the hash chain. 560Sstevel@tonic-gate * Also, p->p_lcp cannot be changed while any one hash bucket lock is held. 570Sstevel@tonic-gate * (The resizing thread must acquire all of the hash bucket locks.) 580Sstevel@tonic-gate */ 590Sstevel@tonic-gate typedef struct lwpchan_hashbucket { 600Sstevel@tonic-gate kmutex_t lwpchan_lock; 610Sstevel@tonic-gate lwpchan_entry_t *lwpchan_chain; 620Sstevel@tonic-gate } lwpchan_hashbucket_t; 630Sstevel@tonic-gate 640Sstevel@tonic-gate /* 650Sstevel@tonic-gate * Each process maintains a cache of lwpchan translations for sync objects 660Sstevel@tonic-gate * (lwp_mutex_t, lwp_cond_t, lwp_sema_t) that are shared between processes. 670Sstevel@tonic-gate * The lwpchan cache is a hash table used to look up previously-computed 680Sstevel@tonic-gate * lwpchan_t's by process virtual address. We keep this cache because we 690Sstevel@tonic-gate * believe that as_getmemid() is slow and we only need to call it once, 700Sstevel@tonic-gate * then remember the results. The hashing function is very simple, and 710Sstevel@tonic-gate * assumes an even distribution of sync objects within the process's 720Sstevel@tonic-gate * address space. When hash chains become too long, the cache is resized 730Sstevel@tonic-gate * on the fly. The cache is freed when the process exits or execs. 740Sstevel@tonic-gate */ 750Sstevel@tonic-gate typedef struct lwpchan_data { 760Sstevel@tonic-gate uint_t lwpchan_bits; /* number of bits */ 770Sstevel@tonic-gate uint_t lwpchan_size; /* 1 << lwpchan_bits */ 780Sstevel@tonic-gate uint_t lwpchan_mask; /* lwpchan_size - 1 */ 790Sstevel@tonic-gate uint_t lwpchan_entries; /* number of entries in the cache */ 800Sstevel@tonic-gate lwpchan_hashbucket_t *lwpchan_cache; 810Sstevel@tonic-gate struct lwpchan_data *lwpchan_next_data; 820Sstevel@tonic-gate } lwpchan_data_t; 830Sstevel@tonic-gate 840Sstevel@tonic-gate /* 850Sstevel@tonic-gate * exported functions 860Sstevel@tonic-gate */ 870Sstevel@tonic-gate void lwpchan_delete_mapping(proc_t *, caddr_t start, caddr_t end); 880Sstevel@tonic-gate void lwpchan_destroy_cache(int); 890Sstevel@tonic-gate 900Sstevel@tonic-gate #ifdef __cplusplus 910Sstevel@tonic-gate } 920Sstevel@tonic-gate #endif 930Sstevel@tonic-gate 940Sstevel@tonic-gate #endif /* _SYS_LCHAN_IMPL_H */ 95