port_impl.h revision 4123:e5cb484f034e
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2006 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
33extern "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
83typedef 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 */
94typedef struct port_queue {
95	kmutex_t 	portq_mutex;
96	kcondvar_t	portq_closecv;
97	kcondvar_t	portq_block_cv;
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#define	PORTQ_BLOCKED	   0x20 /* port is blocked by port_getn() */
120#define	PORTQ_POLLWK_PEND  0x40 /* pollwakeup is pending, blocks port close */
121
122#define	VTOEP(v)  ((struct port *)(v->v_data))
123#define	EPTOV(ep) ((struct vnode *)(ep)->port_vnode)
124
125
126typedef	struct	port {
127	vnode_t		*port_vnode;
128	kmutex_t	port_mutex;
129	kcondvar_t	port_cv;	/* resource control */
130	uint_t		port_flags;
131	pid_t		port_pid;
132	int		port_fd;
133	uint_t		port_max_events; /* max. number of event per port */
134	uint_t		port_max_list;	/* max. number of list structs	*/
135	uint_t		port_curr;	/* current number of event structs */
136	pollhead_t	port_pollhd;
137	timespec_t	port_ctime;
138	uid_t		port_uid;
139	gid_t		port_gid;
140	port_queue_t	port_queue;	/* global queue */
141} port_t;
142
143/* defines for port_flags */
144#define	PORT_INIT	0x01		/* port initialized */
145#define	PORT_CLOSED	0x02		/* owner closed the port */
146#define	PORT_EVENTS	0x04		/* waiting for event resources */
147
148/*
149 * global control structure of port framework
150 */
151typedef	struct	port_control {
152	kmutex_t	pc_mutex;
153	uint_t		pc_nents;	/* ports currently allocated */
154	struct	kmem_cache *pc_cache;	/* port event structures */
155} port_control_t;
156
157
158/*
159 * Every thread waiting on an object will use this structure to store
160 * all dependencies (flags, counters, events) before it awakes with
161 * some events/transactions completed
162 */
163typedef	struct	portget {
164	int		portget_state;
165	uint_t		portget_nget;	/* number of expected events */
166	pid_t		portget_pid;
167	kcondvar_t	portget_cv;
168	port_alert_t	portget_alert;
169	struct	portget	*portget_next;
170	struct	portget	*portget_prev;
171} portget_t;
172
173/* defines for portget_state */
174#define	PORTGET_ALERT		0x01	/* wake up and return alert event */
175
176extern	port_control_t	port_control;
177extern	uint_t	port_max_list;
178
179/*
180 * port_getn() needs this structure to manage inter-process event delivery.
181 */
182typedef struct	port_gettimer {
183	ushort_t	pgt_flags;
184	ushort_t	pgt_loop;
185	int		pgt_timecheck;
186	timespec_t	pgt_rqtime;
187	timespec_t	*pgt_rqtp;
188	struct timespec	*pgt_timeout;
189} port_gettimer_t;
190
191/* pgt_flags */
192#define	PORTGET_ONE		0x01	/* return only 1 object */
193#define	PORTGET_WAIT_EVENTS	0x02	/* thread is waiting for new events */
194
195/*
196 * portfd_t is required to synchronize the association of fds with a port
197 * and the per-process list of open files.
198 * There is a pointer to a portfd structure in uf_entry_t.
199 * If a fd is closed then closeandsetf() is able to detect the association of
200 * the fd with a port or with a list of ports. closeandsetf() will dissociate
201 * the fd from the port(s).
202 */
203typedef struct portfd {
204	struct polldat	pfd_pd;
205	struct portfd	*pfd_next;
206	struct portfd	*pfd_prev;
207} portfd_t;
208
209#define	PFTOD(pfd)	(&(pfd)->pfd_pd)
210#define	PDTOF(pdp)	((struct portfd *)(pdp))
211#define	PORT_FD_BUCKET(pcp, fd) \
212	(&(pcp)->pc_hash[((fd) % (pcp)->pc_hashsize)])
213
214/*
215 * port_kstat_t contains the event port kernel values which are
216 * exported to kstat.
217 * Currently only the number of active ports is exported.
218 */
219typedef struct port_kstat {
220	kstat_named_t	pks_ports;
221} port_kstat_t;
222
223/* misc functions */
224int	port_alloc_event_block(port_t *, int, int, struct port_kevent **);
225void	port_push_eventq(port_queue_t *);
226void	port_remove_done_event(struct port_kevent *);
227struct	port_kevent *port_get_kevent(list_t *, struct port_kevent *);
228void	port_block(port_queue_t *);
229void	port_unblock(port_queue_t *);
230
231/* PORT_SOURCE_FD cache management */
232void port_pcache_remove_fd(port_fdcache_t *, portfd_t *);
233int port_remove_fd_object(portfd_t *, struct port *, port_fdcache_t *);
234
235/* file close management */
236extern void addfd_port(int, portfd_t *);
237extern void delfd_port(int, portfd_t *);
238
239#endif	/* _KERNEL */
240
241#ifdef	__cplusplus
242}
243#endif
244
245#endif	/* _SYS_PORT_IMPL_H */
246