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 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <sys/types.h>
28 #include <sys/systm.h>
29 #include <sys/cred.h>
30 #include <sys/modctl.h>
31 #include <sys/vfs.h>
32 #include <sys/vfs_opreg.h>
33 #include <sys/sysmacros.h>
34 #include <sys/cmn_err.h>
35 #include <sys/stat.h>
36 #include <sys/errno.h>
37 #include <sys/kmem.h>
38 #include <sys/file.h>
39 #include <sys/kstat.h>
40 #include <sys/port_impl.h>
41 #include <sys/task.h>
42 #include <sys/project.h>
43
44 /*
45 * Event Ports can be shared across threads or across processes.
46 * Every thread/process can use an own event port or a group of them
1362 port_block(portq); /* block other threads here */
1363 nmax = max < portq->portq_nent ? max : portq->portq_nent;
1364
1365 if (portq->portq_tnent) {
1366 /*
1367 * Move remaining events from previous thread back to the
1368 * port event queue.
1369 */
1370 port_push_eventq(portq);
1371 }
1372 /* move port event queue to a temporary queue */
1373 list_move_tail(&portq->portq_get_list, &portq->portq_list);
1374 glist = &portq->portq_get_list; /* use temporary event queue */
1375 tnent = portq->portq_nent; /* get current number of events */
1376 portq->portq_nent = 0; /* no events in the port event queue */
1377 portq->portq_flags |= PORTQ_WAIT_EVENTS; /* detect incoming events */
1378 mutex_exit(&portq->portq_mutex); /* event queue can be reused now */
1379
1380 if (model == DATAMODEL_NATIVE) {
1381 eventsz = sizeof (port_event_t);
1382 kevp = kmem_alloc(eventsz * nmax, KM_NOSLEEP);
1383 if (kevp == NULL) {
1384 if (nmax > pp->port_max_list)
1385 nmax = pp->port_max_list;
1386 kevp = kmem_alloc(eventsz * nmax, KM_SLEEP);
1387 }
1388 results = kevp;
1389 lev = NULL; /* start with first event in the queue */
1390 for (nevents = 0; nevents < nmax; ) {
1391 pev = port_get_kevent(glist, lev);
1392 if (pev == NULL) /* no more events available */
1393 break;
1394 if (pev->portkev_flags & PORT_KEV_FREE) {
1395 /* Just discard event */
1396 list_remove(glist, pev);
1397 pev->portkev_flags &= ~(PORT_CLEANUP_DONE);
1398 if (PORT_FREE_EVENT(pev))
1399 port_free_event_local(pev, 0);
1400 tnent--;
1401 continue;
1402 }
1403
1404 /* move event data to copyout list */
1405 if (port_copy_event(&kevp[nevents], pev, glist)) {
1406 /*
1407 * Event can not be delivered to the
1408 * current process.
1409 */
1410 if (lev != NULL)
1411 list_insert_after(glist, lev, pev);
1412 else
1413 list_insert_head(glist, pev);
1414 lev = pev; /* last checked event */
1415 } else {
1416 nevents++; /* # of events ready */
1417 }
1418 }
1419 #ifdef _SYSCALL32_IMPL
1420 } else {
1421 port_event32_t *kevp32;
1422
1423 eventsz = sizeof (port_event32_t);
1424 kevp32 = kmem_alloc(eventsz * nmax, KM_NOSLEEP);
1425 if (kevp32 == NULL) {
1426 if (nmax > pp->port_max_list)
1427 nmax = pp->port_max_list;
1428 kevp32 = kmem_alloc(eventsz * nmax, KM_SLEEP);
1429 }
1430 results = kevp32;
1431 lev = NULL; /* start with first event in the queue */
1432 for (nevents = 0; nevents < nmax; ) {
1433 pev = port_get_kevent(glist, lev);
1434 if (pev == NULL) /* no more events available */
1435 break;
1436 if (pev->portkev_flags & PORT_KEV_FREE) {
1437 /* Just discard event */
1438 list_remove(glist, pev);
1439 pev->portkev_flags &= ~(PORT_CLEANUP_DONE);
1440 if (PORT_FREE_EVENT(pev))
1441 port_free_event_local(pev, 0);
1442 tnent--;
1443 continue;
1444 }
1445
1446 /* move event data to copyout list */
1447 if (port_copy_event32(&kevp32[nevents], pev, glist)) {
1448 /*
1449 * Event can not be delivered to the
|
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 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2015 Joyent, Inc. All rights reserved.
29 */
30
31 #include <sys/types.h>
32 #include <sys/systm.h>
33 #include <sys/cred.h>
34 #include <sys/modctl.h>
35 #include <sys/vfs.h>
36 #include <sys/vfs_opreg.h>
37 #include <sys/sysmacros.h>
38 #include <sys/cmn_err.h>
39 #include <sys/stat.h>
40 #include <sys/errno.h>
41 #include <sys/kmem.h>
42 #include <sys/file.h>
43 #include <sys/kstat.h>
44 #include <sys/port_impl.h>
45 #include <sys/task.h>
46 #include <sys/project.h>
47
48 /*
49 * Event Ports can be shared across threads or across processes.
50 * Every thread/process can use an own event port or a group of them
1366 port_block(portq); /* block other threads here */
1367 nmax = max < portq->portq_nent ? max : portq->portq_nent;
1368
1369 if (portq->portq_tnent) {
1370 /*
1371 * Move remaining events from previous thread back to the
1372 * port event queue.
1373 */
1374 port_push_eventq(portq);
1375 }
1376 /* move port event queue to a temporary queue */
1377 list_move_tail(&portq->portq_get_list, &portq->portq_list);
1378 glist = &portq->portq_get_list; /* use temporary event queue */
1379 tnent = portq->portq_nent; /* get current number of events */
1380 portq->portq_nent = 0; /* no events in the port event queue */
1381 portq->portq_flags |= PORTQ_WAIT_EVENTS; /* detect incoming events */
1382 mutex_exit(&portq->portq_mutex); /* event queue can be reused now */
1383
1384 if (model == DATAMODEL_NATIVE) {
1385 eventsz = sizeof (port_event_t);
1386
1387 if (nmax == 0) {
1388 kevp = NULL;
1389 } else {
1390 kevp = kmem_alloc(eventsz * nmax, KM_NOSLEEP);
1391 if (kevp == NULL) {
1392 if (nmax > pp->port_max_list)
1393 nmax = pp->port_max_list;
1394 kevp = kmem_alloc(eventsz * nmax, KM_SLEEP);
1395 }
1396 }
1397
1398 results = kevp;
1399 lev = NULL; /* start with first event in the queue */
1400 for (nevents = 0; nevents < nmax; ) {
1401 pev = port_get_kevent(glist, lev);
1402 if (pev == NULL) /* no more events available */
1403 break;
1404 if (pev->portkev_flags & PORT_KEV_FREE) {
1405 /* Just discard event */
1406 list_remove(glist, pev);
1407 pev->portkev_flags &= ~(PORT_CLEANUP_DONE);
1408 if (PORT_FREE_EVENT(pev))
1409 port_free_event_local(pev, 0);
1410 tnent--;
1411 continue;
1412 }
1413
1414 /* move event data to copyout list */
1415 if (port_copy_event(&kevp[nevents], pev, glist)) {
1416 /*
1417 * Event can not be delivered to the
1418 * current process.
1419 */
1420 if (lev != NULL)
1421 list_insert_after(glist, lev, pev);
1422 else
1423 list_insert_head(glist, pev);
1424 lev = pev; /* last checked event */
1425 } else {
1426 nevents++; /* # of events ready */
1427 }
1428 }
1429 #ifdef _SYSCALL32_IMPL
1430 } else {
1431 port_event32_t *kevp32;
1432
1433 eventsz = sizeof (port_event32_t);
1434
1435 if (nmax == 0) {
1436 kevp32 = NULL;
1437 } else {
1438 kevp32 = kmem_alloc(eventsz * nmax, KM_NOSLEEP);
1439 if (kevp32 == NULL) {
1440 if (nmax > pp->port_max_list)
1441 nmax = pp->port_max_list;
1442 kevp32 = kmem_alloc(eventsz * nmax, KM_SLEEP);
1443 }
1444 }
1445
1446 results = kevp32;
1447 lev = NULL; /* start with first event in the queue */
1448 for (nevents = 0; nevents < nmax; ) {
1449 pev = port_get_kevent(glist, lev);
1450 if (pev == NULL) /* no more events available */
1451 break;
1452 if (pev->portkev_flags & PORT_KEV_FREE) {
1453 /* Just discard event */
1454 list_remove(glist, pev);
1455 pev->portkev_flags &= ~(PORT_CLEANUP_DONE);
1456 if (PORT_FREE_EVENT(pev))
1457 port_free_event_local(pev, 0);
1458 tnent--;
1459 continue;
1460 }
1461
1462 /* move event data to copyout list */
1463 if (port_copy_event32(&kevp32[nevents], pev, glist)) {
1464 /*
1465 * Event can not be delivered to the
|