import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / port / gen / event_port.c
blob03ebaa11f146c8b95f5380d4cbf3b91534d11672
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include "lint.h"
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <sys/port_impl.h>
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <sys/systm.h>
37 #include <libc.h>
40 * The second argument of _portfs(PORT_CREATE, 0,,,) represents the version
41 * number of the event ports framework. The version number is required to
42 * identify possible changes/extensions of the port_event_t structure. If an
43 * extension is required the port_create() function will be mapped to a second
44 * library create function like port_create_v1(PORT_CREATE, VERSION,,,)
45 * VERSION will be a number > 0.
46 * As long as such an extension is not required the second argument will be
47 * set to 0 and no check will be done in the kernel interface.
49 int
50 port_create()
52 rval_t r;
53 r.r_vals = _portfs(PORT_CREATE | PORT_SYS_NOPORT, 0, 0, 0, 0, 0);
54 return (r.r_val1);
57 int
58 port_associate(int port, int source, uintptr_t object, int events, void *user)
60 rval_t r;
61 r.r_vals = _portfs(PORT_ASSOCIATE, port, source, object, events,
62 (uintptr_t)user);
63 return (r.r_val1);
67 int
68 port_get(int port, port_event_t *pe, struct timespec *to)
70 rval_t r;
71 if (to)
72 r.r_vals = _portfs(PORT_GET, port, (uintptr_t)pe, to->tv_sec,
73 to->tv_nsec, (uintptr_t)to);
74 else
75 r.r_vals = _portfs(PORT_GET, port, (uintptr_t)pe, 0, 0,
76 (uintptr_t)NULL);
77 return (r.r_val1);
80 int
81 port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
82 struct timespec *timeout)
84 rval_t r;
85 if (nget == NULL) {
86 errno = EINVAL;
87 return (-1);
89 r.r_vals = _portfs(PORT_GETN, port, (uintptr_t)list, max, *nget,
90 (uintptr_t)timeout);
91 if (r.r_val1 == -1) {
92 /* global error, errno is already set */
93 return (-1);
95 *nget = r.r_val1;
96 if (r.r_val2 == ETIME) {
97 errno = ETIME;
98 return (-1);
100 return (r.r_val2);
104 port_dissociate(int port, int source, uintptr_t object)
106 rval_t r;
107 r.r_vals = _portfs(PORT_DISSOCIATE, port, source, object, 0, 0);
108 return (r.r_val1);
112 port_send(int port, int events, void *user)
114 rval_t r;
115 r.r_vals = _portfs(PORT_SEND, port, events, (uintptr_t)user,
116 (uintptr_t)NULL, (uintptr_t)NULL);
118 return (r.r_val1);
122 * _port_dispatch() will block if there are not resources available to
123 * satisfy the request.
127 _port_dispatch(int port, int flags, int source, int events, uintptr_t object,
128 void *user)
130 rval_t r;
131 if (flags & PORT_SHARE_EVENT)
132 r.r_vals = _portfs(PORT_DISPATCH, port, source, events, object,
133 (uintptr_t)user);
134 else
135 r.r_vals = _portfs(PORT_DISPATCH | PORT_SYS_NOSHARE, port,
136 source, events, object, (uintptr_t)user);
137 return (r.r_val1);
141 port_sendn(int ports[], int errors[], uint_t nent, int events, void *user)
143 rval_t r;
144 uint_t offset;
145 uint_t lnent;
146 uint_t nevents;
147 if (nent <= PORT_MAX_LIST) {
148 r.r_vals = _portfs(PORT_SENDN | PORT_SYS_NOPORT,
149 (uintptr_t)ports, (uintptr_t)errors, nent, events,
150 (uintptr_t)user);
151 return (r.r_val1);
154 /* use chunks of max PORT_MAX_LIST elements per syscall */
155 nevents = 0;
156 for (offset = 0; offset < nent; ) {
157 lnent = nent - offset;
158 if (nent - offset > PORT_MAX_LIST)
159 lnent = PORT_MAX_LIST;
160 else
161 lnent = nent - offset;
162 r.r_vals = _portfs(PORT_SENDN | PORT_SYS_NOPORT,
163 (uintptr_t)&ports[offset], (uintptr_t)&errors[offset],
164 lnent, events, (uintptr_t)user);
165 if (r.r_val2 == -1) {
166 /* global error, return last no of events submitted */
167 if (nevents)
168 return (nevents);
169 return (-1);
171 nevents += r.r_val1;
172 offset += lnent;
174 /* list submitted */
175 return (nevents);
179 port_alert(int port, int flags, int events, void *user)
181 rval_t r;
182 r.r_vals = _portfs(PORT_ALERT, port, flags, events, (uintptr_t)user,
183 (uintptr_t)NULL);
184 return (r.r_val1);