| 1 | /*************************************************************************** |
|---|
| 2 | * (c)2004-2011 Broadcom Corporation |
|---|
| 3 | * |
|---|
| 4 | * This program is the proprietary software of Broadcom Corporation and/or its licensors, |
|---|
| 5 | * and may only be used, duplicated, modified or distributed pursuant to the terms and |
|---|
| 6 | * conditions of a separate, written license agreement executed between you and Broadcom |
|---|
| 7 | * (an "Authorized License"). Except as set forth in an Authorized License, Broadcom grants |
|---|
| 8 | * no license (express or implied), right to use, or waiver of any kind with respect to the |
|---|
| 9 | * Software, and Broadcom expressly reserves all rights in and to the Software and all |
|---|
| 10 | * intellectual property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU |
|---|
| 11 | * HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY |
|---|
| 12 | * NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. |
|---|
| 13 | * |
|---|
| 14 | * Except as expressly set forth in the Authorized License, |
|---|
| 15 | * |
|---|
| 16 | * 1. This program, including its structure, sequence and organization, constitutes the valuable trade |
|---|
| 17 | * secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof, |
|---|
| 18 | * and to use this information only in connection with your use of Broadcom integrated circuit products. |
|---|
| 19 | * |
|---|
| 20 | * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" |
|---|
| 21 | * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR |
|---|
| 22 | * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO |
|---|
| 23 | * THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES |
|---|
| 24 | * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, |
|---|
| 25 | * LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION |
|---|
| 26 | * OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF |
|---|
| 27 | * USE OR PERFORMANCE OF THE SOFTWARE. |
|---|
| 28 | * |
|---|
| 29 | * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS |
|---|
| 30 | * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR |
|---|
| 31 | * EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR |
|---|
| 32 | * USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF |
|---|
| 33 | * THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT |
|---|
| 34 | * ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE |
|---|
| 35 | * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF |
|---|
| 36 | * ANY LIMITED REMEDY. |
|---|
| 37 | * |
|---|
| 38 | * $brcm_Workfile: b_objdb.h $ |
|---|
| 39 | * $brcm_Revision: 5 $ |
|---|
| 40 | * $brcm_Date: 9/16/11 3:40p $ |
|---|
| 41 | * |
|---|
| 42 | * Module Description: |
|---|
| 43 | * |
|---|
| 44 | * Revision History: |
|---|
| 45 | * |
|---|
| 46 | * $brcm_Log: /nexus/base/include/b_objdb.h $ |
|---|
| 47 | * |
|---|
| 48 | * 5 9/16/11 3:40p erickson |
|---|
| 49 | * SW7420-2064: clean up unprotected callbacks when client exits, allow |
|---|
| 50 | * re-registration when client connects |
|---|
| 51 | * |
|---|
| 52 | * 4 9/13/11 1:24p erickson |
|---|
| 53 | * SW7420-1148: change client modes to unprotected/protected/untrusted |
|---|
| 54 | * |
|---|
| 55 | * 3 9/2/11 10:01a erickson |
|---|
| 56 | * SW7420-1148: allow implicit insert on acquire. allows non-thunked |
|---|
| 57 | * server to work with thunked client. |
|---|
| 58 | * |
|---|
| 59 | * 2 7/26/11 12:07p erickson |
|---|
| 60 | * SW7420-1992: callback database must take client id so that callbacks |
|---|
| 61 | * can be disconnected when a client releases |
|---|
| 62 | * |
|---|
| 63 | * 1 4/1/11 9:59a erickson |
|---|
| 64 | * SW7420-1671: refactor object database for multiprocess stress |
|---|
| 65 | * |
|---|
| 66 | ************************************************************/ |
|---|
| 67 | #ifndef B_OBJDB_H__ |
|---|
| 68 | #define B_OBJDB_H__ |
|---|
| 69 | |
|---|
| 70 | #include "bdbg.h" |
|---|
| 71 | #include "nexus_types.h" |
|---|
| 72 | |
|---|
| 73 | /** |
|---|
| 74 | object database |
|---|
| 75 | |
|---|
| 76 | this api is internal to nexus. |
|---|
| 77 | used by nexus kernel-mode proxy and user-mode multiprocess thunks. |
|---|
| 78 | it uses static allocation and transparent structs, not dynamic allocation and opaque handles. |
|---|
| 79 | **/ |
|---|
| 80 | |
|---|
| 81 | typedef enum b_objdb_verify |
|---|
| 82 | { |
|---|
| 83 | b_objdb_verify_full, /* verify handle, type and client */ |
|---|
| 84 | b_objdb_verify_partial, /* verify handle and type, not client */ |
|---|
| 85 | b_objdb_verify_none, /* do not verify the handle */ |
|---|
| 86 | b_objdb_verify_max |
|---|
| 87 | } b_objdb_verify; |
|---|
| 88 | |
|---|
| 89 | /* the address of the b_objdb_client instance is the id for the client */ |
|---|
| 90 | struct b_objdb_client |
|---|
| 91 | { |
|---|
| 92 | b_objdb_verify verify; |
|---|
| 93 | bool limited_api; |
|---|
| 94 | }; |
|---|
| 95 | |
|---|
| 96 | /* entries in heap b_objdb_heap. one per handle instance. */ |
|---|
| 97 | struct b_objdb_entry { |
|---|
| 98 | void *handle; |
|---|
| 99 | const struct b_objdb_client *client; /* each object is owned by one client. destroy must match. verify must match client or acquired_client. */ |
|---|
| 100 | const struct b_objdb_client *acquired_client; /* each object can be acquired by one client. release must match. verify must match client or acquired_client. */ |
|---|
| 101 | unsigned order; /* persistent order, used to destroy objects in exact opposite of create */ |
|---|
| 102 | }; |
|---|
| 103 | |
|---|
| 104 | /* dynamically allocated array of entries. one per handle type. */ |
|---|
| 105 | struct b_objdb_heap { |
|---|
| 106 | unsigned count; /* number of entries in the heap */ |
|---|
| 107 | struct b_objdb_entry data[1]; /* variable size trailer */ |
|---|
| 108 | }; |
|---|
| 109 | |
|---|
| 110 | BDBG_OBJECT_ID_DECLARE(b_objdb); |
|---|
| 111 | struct b_objdb_class; |
|---|
| 112 | |
|---|
| 113 | /* |
|---|
| 114 | b_objdb is the object database. There is one instance of b_objdb per module. |
|---|
| 115 | There is one mutex (nexus module handle) per objdb. |
|---|
| 116 | */ |
|---|
| 117 | struct b_objdb { |
|---|
| 118 | BDBG_OBJECT(b_objdb) |
|---|
| 119 | const char *name; /* debug */ |
|---|
| 120 | NEXUS_ModuleHandle module; /* provides synchronization for this DB. _locked functions already have this acquired. */ |
|---|
| 121 | unsigned object_count; |
|---|
| 122 | struct b_objdb_class *class_table; |
|---|
| 123 | |
|---|
| 124 | /* callback to cancel callbacks for a handle */ |
|---|
| 125 | void (*cancel_callbacks_locked)(void *context, void *handle, void *client_id); /* called with module lock already acquired */ |
|---|
| 126 | void *cancel_callbacks_context; |
|---|
| 127 | }; |
|---|
| 128 | |
|---|
| 129 | typedef void (*b_objdb_callback)(void *handle); |
|---|
| 130 | |
|---|
| 131 | /* |
|---|
| 132 | There is one b_objdb_class per class, or interface type. |
|---|
| 133 | A set of b_objdb_classes is assocatied with a single b_objdb. |
|---|
| 134 | It is statically populated using macros in the thunk. |
|---|
| 135 | */ |
|---|
| 136 | struct b_objdb_class { |
|---|
| 137 | struct b_objdb *db; |
|---|
| 138 | const char *type_name; /* handle type name, for debug */ |
|---|
| 139 | b_objdb_callback release; /* func to call for auto-release. this is called locked. */ |
|---|
| 140 | b_objdb_callback destructor; /* func to call for auto-close. this is called locked. */ |
|---|
| 141 | struct b_objdb_heap *objects; /* list of all instances for this object type */ |
|---|
| 142 | }; |
|---|
| 143 | |
|---|
| 144 | #define B_OBJDB_TABLE_BEGIN(NAME) static struct b_objdb_class NAME[] = { |
|---|
| 145 | #define B_OBJDB_TABLE_END {NULL,NULL,NULL,NULL,NULL}}; |
|---|
| 146 | #define B_OBJDB_TABLE_ENTRY(handletype,releasefunc,destructorfunc) {NULL, #handletype, (b_objdb_callback)releasefunc, (b_objdb_callback)destructorfunc, NULL}, |
|---|
| 147 | |
|---|
| 148 | /* b_objdb_init will hook up the statically-declared class_table. the caller must still manually |
|---|
| 149 | set db->module, name, cancel_callbacks and cancel_callbacks_context */ |
|---|
| 150 | int b_objdb_init(struct b_objdb *db, struct b_objdb_class *class_table); |
|---|
| 151 | void b_objdb_uninit(struct b_objdb *db); |
|---|
| 152 | |
|---|
| 153 | /* functions called from thunk. module lock is already acquired. */ |
|---|
| 154 | int b_objdb_insert_locked(struct b_objdb_class *p_class, void *handle, const struct b_objdb_client *client, |
|---|
| 155 | bool acquiring /* if false, this is an insert. if true, this is an acquire. */ |
|---|
| 156 | ); |
|---|
| 157 | int b_objdb_remove_locked(struct b_objdb_class *p_class, void *handle, const struct b_objdb_client *client, |
|---|
| 158 | bool releasing /* if false, this pairs with an insert. if true, this pairs with an acquire. */ |
|---|
| 159 | ); |
|---|
| 160 | int b_objdb_verify_locked(struct b_objdb_class *p_class, void *handle, const struct b_objdb_client *client); |
|---|
| 161 | |
|---|
| 162 | /* clear out all entries, but do not uninit */ |
|---|
| 163 | void b_objdb_clear(struct b_objdb *db); |
|---|
| 164 | |
|---|
| 165 | /* find newest entry for this client in this db. |
|---|
| 166 | returns 0 if an entry was found. */ |
|---|
| 167 | int b_objdb_get_newest_entry(struct b_objdb *db, const struct b_objdb_client *client, struct b_objdb_class **p_class, struct b_objdb_entry **p_entry); |
|---|
| 168 | |
|---|
| 169 | /* uninit is called on auto-close. it will test if the client owns or has acquiring the handle. will perform one or two removes as needed. */ |
|---|
| 170 | void b_objdb_uninit_entry(struct b_objdb_class *p_class, struct b_objdb_entry *entry, const struct b_objdb_client *client); |
|---|
| 171 | |
|---|
| 172 | /* uninit all callbacks for this client */ |
|---|
| 173 | void b_objdb_uninit_client(struct b_objdb *db, const struct b_objdb_client *client); |
|---|
| 174 | |
|---|
| 175 | #endif |
|---|