xref: /illumos-gate/usr/src/uts/common/sys/port_impl.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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