1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_PORT_IMPL_H 28 #define _SYS_PORT_IMPL_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * Note: 38 * The contents of this file are private to the implementation of the 39 * Solaris system and event ports subsystem and are subject to change 40 * at any time without notice. 41 */ 42 43 #include <sys/poll_impl.h> 44 #include <sys/port.h> 45 #include <sys/port_kernel.h> 46 #include <sys/vnode.h> 47 48 /* 49 * port system call codes 50 */ 51 #define PORT_CREATE 0 /* create a port */ 52 #define PORT_ASSOCIATE 1 /* register object or object list */ 53 #define PORT_DISSOCIATE 2 /* remove object association */ 54 #define PORT_SEND 3 /* send user-defined event to a port */ 55 #define PORT_SENDN 4 /* send user-defined event to a list of ports */ 56 #define PORT_GET 5 /* receive object with events */ 57 #define PORT_GETN 6 /* receive list of objects with events */ 58 #define PORT_ALERT 7 /* set port in alert mode */ 59 #define PORT_DISPATCH 8 /* dispatch object with events */ 60 61 #define PORT_SYS_NOPORT 0x100 /* system call without port-id */ 62 #define PORT_SYS_NOSHARE 0x200 /* non shareable event */ 63 #define PORT_CODE_MASK 0xff 64 65 /* port_dispatch() flags */ 66 #define PORT_SHARE_EVENT 0x01 /* event can be shared between procs */ 67 68 /* port limits */ 69 #define PORT_MAX_LIST 8192 /* max. # of list ent. per syscall */ 70 71 #ifdef _KERNEL 72 73 #define PORT_SCACHE_SIZE 16 /* start source cache size */ 74 #define PORT_SHASH(cookie) (cookie & (PORT_SCACHE_SIZE-1)) 75 76 /* portkev_flags masks */ 77 #define PORT_CLEANUP_DONE (PORT_KEV_FREE|PORT_KEV_DONEQ) 78 #define PORT_KEV_CACHE (PORT_KEV_CACHED|PORT_KEV_SCACHED) 79 #define PORT_KEV_WIRED (PORT_KEV_PRIVATE|PORT_KEV_CACHE) 80 81 #define PORT_FREE_EVENT(pev) (((pev)->portkev_flags & PORT_KEV_CACHE) == 0) 82 83 typedef struct port_alert { 84 int portal_events; /* passed to alert event */ 85 pid_t portal_pid; /* owner of the alert mode */ 86 uintptr_t portal_object; /* passed to alert event */ 87 void *portal_user; /* passed to alert event */ 88 } port_alert_t; 89 90 /* 91 * The port_queue_t structure is responsible for the management of all 92 * event activities within a port. 93 */ 94 typedef struct port_queue { 95 kmutex_t portq_mutex; 96 kmutex_t portq_block_mutex; 97 kcondvar_t portq_closecv; 98 int portq_flags; 99 uint_t portq_nent; /* number of events in the queue */ 100 uint_t portq_nget; /* events required for waiting thread */ 101 uint_t portq_tnent; /* number of events in the temp queue */ 102 int portq_thrcnt; /* # of threads waiting for events */ 103 int portq_getn; /* # of threads retrieving events */ 104 struct portget *portq_thread; /* queue of waiting threads */ 105 struct port_fdcache *portq_pcp; /* fd cache */ 106 list_t portq_list; /* port event list */ 107 list_t portq_get_list; /* port event list for port_get(n) */ 108 kmutex_t portq_source_mutex; 109 port_source_t **portq_scache; 110 port_alert_t portq_alert; /* alert event data */ 111 } port_queue_t; 112 113 /* defines for portq_flags */ 114 #define PORTQ_ALERT 0x01 /* port in alert state */ 115 #define PORTQ_CLOSE 0x02 /* closing port */ 116 #define PORTQ_WAIT_EVENTS 0x04 /* waiting for new events */ 117 #define PORTQ_POLLIN 0x08 /* events available in the event queue */ 118 #define PORTQ_POLLOUT 0x10 /* space available for new events */ 119 120 #define VTOEP(v) ((struct port *)(v->v_data)) 121 #define EPTOV(ep) ((struct vnode *)(ep)->port_vnode) 122 123 124 typedef struct port { 125 vnode_t *port_vnode; 126 kmutex_t port_mutex; 127 kcondvar_t port_cv; /* resource control */ 128 uint_t port_flags; 129 pid_t port_pid; 130 int port_fd; 131 uint_t port_max_events; /* max. number of event per port */ 132 uint_t port_max_list; /* max. number of list structs */ 133 uint_t port_curr; /* current number of event structs */ 134 pollhead_t port_pollhd; 135 timespec_t port_ctime; 136 uid_t port_uid; 137 gid_t port_gid; 138 port_queue_t port_queue; /* global queue */ 139 } port_t; 140 141 /* defines for port_flags */ 142 #define PORT_INIT 0x01 /* port initialized */ 143 #define PORT_CLOSED 0x02 /* owner closed the port */ 144 #define PORT_EVENTS 0x04 /* waiting for event resources */ 145 146 /* 147 * global control structure of port framework 148 */ 149 typedef struct port_control { 150 kmutex_t pc_mutex; 151 uint_t pc_nents; /* ports currently allocated */ 152 struct kmem_cache *pc_cache; /* port event structures */ 153 } port_control_t; 154 155 156 /* 157 * Every thread waiting on an object will use this structure to store 158 * all dependencies (flags, counters, events) before it awakes with 159 * some events/transactions completed 160 */ 161 typedef struct portget { 162 int portget_state; 163 uint_t portget_nget; /* number of expected events */ 164 pid_t portget_pid; 165 kcondvar_t portget_cv; 166 port_alert_t portget_alert; 167 struct portget *portget_next; 168 struct portget *portget_prev; 169 } portget_t; 170 171 /* defines for portget_state */ 172 #define PORTGET_ALERT 0x01 /* wake up and return alert event */ 173 174 extern port_control_t port_control; 175 extern uint_t port_max_list; 176 177 /* 178 * port_getn() needs this structure to manage inter-process event delivery. 179 */ 180 typedef struct port_gettimer { 181 ushort_t pgt_flags; 182 ushort_t pgt_loop; 183 int pgt_timecheck; 184 timespec_t pgt_rqtime; 185 timespec_t *pgt_rqtp; 186 struct timespec *pgt_timeout; 187 } port_gettimer_t; 188 189 /* pgt_flags */ 190 #define PORTGET_ONE 0x01 /* return only 1 object */ 191 #define PORTGET_WAIT_EVENTS 0x02 /* thread is waiting for new events */ 192 193 /* 194 * portfd_t is required to synchronize the association of fds with a port 195 * and the per-process list of open files. 196 * There is a pointer to a portfd structure in uf_entry_t. 197 * If a fd is closed then closeandsetf() is able to detect the association of 198 * the fd with a port or with a list of ports. closeandsetf() will dissociate 199 * the fd from the port(s). 200 */ 201 typedef struct portfd { 202 struct polldat pfd_pd; 203 struct portfd *pfd_next; 204 struct portfd *pfd_prev; 205 } portfd_t; 206 207 #define PFTOD(pfd) (&(pfd)->pfd_pd) 208 #define PDTOF(pdp) ((struct portfd *)(pdp)) 209 #define PORT_FD_BUCKET(pcp, fd) \ 210 (&(pcp)->pc_hash[((fd) % (pcp)->pc_hashsize)]) 211 212 /* 213 * port_kstat_t contains the event port kernel values which are 214 * exported to kstat. 215 * Currently only the number of active ports is exported. 216 */ 217 typedef struct port_kstat { 218 kstat_named_t pks_ports; 219 } port_kstat_t; 220 221 /* misc functions */ 222 int port_alloc_event_block(port_t *, int, int, struct port_kevent **); 223 void port_push_eventq(port_queue_t *); 224 void port_remove_done_event(struct port_kevent *); 225 struct port_kevent *port_get_kevent(list_t *, struct port_kevent *); 226 227 /* PORT_SOURCE_FD cache management */ 228 void port_pcache_remove_fd(port_fdcache_t *, portfd_t *); 229 void port_remove_fd_object(portfd_t *, struct port *, port_fdcache_t *); 230 231 /* file close management */ 232 extern void addfd_port(int, portfd_t *); 233 extern void delfd_port(int, portfd_t *); 234 235 #endif /* _KERNEL */ 236 237 #ifdef __cplusplus 238 } 239 #endif 240 241 #endif /* _SYS_PORT_IMPL_H */ 242