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 * Copyright 2001 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1988 AT&T */ 26 /* All Rights Reserved */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <sys/select.h> 31 #include <sys/types.h> 32 #include <rpc/trace.h> 33 #include <sys/time.h> 34 #include <sys/poll.h> 35 #include "rpc_mt.h" 36 37 38 /* 39 * Given an fd_set pointer and the number of bits to check in it, 40 * initialize the supplied pollfd array for RPC's use (RPC only 41 * polls for input events). We return the number of pollfd slots 42 * we initialized. 43 */ 44 int 45 __rpc_select_to_poll( 46 int fdmax, /* number of bits we must test */ 47 fd_set *fdset, /* source fd_set array */ 48 struct pollfd *p0) /* target pollfd array */ 49 { 50 /* register declarations ordered by expected frequency of use */ 51 register int j; /* loop counter */ 52 register int n; 53 register struct pollfd *p = p0; 54 55 /* 56 * For each fd, if the appropriate bit is set convert it into 57 * the appropriate pollfd struct. 58 */ 59 trace2(TR___rpc_select_to_poll, 0, fdmax); 60 j = ((fdmax >= FD_SETSIZE) ? FD_SETSIZE : fdmax); 61 for (n = 0; n < j; n++) { 62 if (FD_ISSET(n, fdset)) { 63 p->fd = n; 64 p->events = MASKVAL; 65 p->revents = 0; 66 p++; 67 } 68 } 69 trace2(TR___rpc_select_to_poll, 1, fdmax); 70 return (p - p0); 71 } 72 73 /* 74 * Arguments are similar to rpc_select_to_poll() except that 75 * the second argument is pointer to an array of pollfd_t 76 * which is the source array which will be compressed and 77 * copied to the target array in p0. The size of the 78 * source argument is given by pollfdmax. The array can be 79 * sparse. The space for the target is allocated before 80 * calling this function. It should have atleast pollfdmax 81 * elements. This function scans the source pollfd array 82 * and copies only the valid ones to the target p0. 83 */ 84 int 85 __rpc_compress_pollfd(int pollfdmax, pollfd_t *srcp, pollfd_t *p0) 86 { 87 int n; 88 pollfd_t *p = p0; 89 90 trace2(TR___rpc_compress_pollfd, 0, p0); 91 92 for (n = 0; n < pollfdmax; n++) { 93 if (POLLFD_ISSET(n, srcp)) { 94 p->fd = srcp[n].fd; 95 p->events = srcp[n].events; 96 p->revents = 0; 97 p++; 98 } 99 } 100 101 trace2(TR___rpc_compress_pollfd, 1, pollfdmax); 102 return (p - p0); 103 } 104 105 /* 106 * Convert from timevals (used by select) to milliseconds (used by poll). 107 */ 108 int 109 __rpc_timeval_to_msec(struct timeval *t) 110 { 111 int t1, tmp; 112 113 /* 114 * We're really returning t->tv_sec * 1000 + (t->tv_usec / 1000) 115 * but try to do so efficiently. Note: 1000 = 1024 - 16 - 8. 116 */ 117 trace1(TR___rpc_timeval_to_msec, 0); 118 tmp = (int)t->tv_sec << 3; 119 t1 = -tmp; 120 t1 += t1 << 1; 121 t1 += tmp << 7; 122 if (t->tv_usec) 123 t1 += t->tv_usec / 1000; 124 125 trace1(TR___rpc_timeval_to_msec, 1); 126 return (t1); 127 } 128