sys_generic.c (91972) | sys_generic.c (92252) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 |
39 * $FreeBSD: head/sys/kern/sys_generic.c 91972 2002-03-09 22:44:37Z alfred $ | 39 * $FreeBSD: head/sys/kern/sys_generic.c 92252 2002-03-14 01:32:30Z alfred $ |
40 */ 41 42#include "opt_ktrace.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/sysproto.h> 47#include <sys/filedesc.h> --- 643 unchanged lines hidden (view full) --- 691 if (memp) 692 free(memp, M_IOCTLOPS); 693 fdrop(fp, td); 694done: 695 mtx_unlock(&Giant); 696 return (error); 697} 698 | 40 */ 41 42#include "opt_ktrace.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/sysproto.h> 47#include <sys/filedesc.h> --- 643 unchanged lines hidden (view full) --- 691 if (memp) 692 free(memp, M_IOCTLOPS); 693 fdrop(fp, td); 694done: 695 mtx_unlock(&Giant); 696 return (error); 697} 698 |
699static int nselcoll; /* Select collisions since boot */ | 699/* 700 * sellock and selwait are initialized in selectinit() via SYSINIT. 701 */ 702struct mtx sellock; |
700struct cv selwait; | 703struct cv selwait; |
704int nselcoll; /* Select collisions since boot */ |
|
701SYSCTL_INT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, ""); 702 703/* 704 * Select system call. 705 */ 706#ifndef _SYS_SYSPROTO_H_ 707struct select_args { 708 int nd; --- 61 unchanged lines hidden (view full) --- 770 if (uap->name == NULL) \ 771 ibits[x] = NULL; \ 772 else { \ 773 ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \ 774 obits[x] = sbp; \ 775 sbp += ncpbytes / sizeof *sbp; \ 776 error = copyin(uap->name, ibits[x], ncpbytes); \ 777 if (error != 0) \ | 705SYSCTL_INT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, ""); 706 707/* 708 * Select system call. 709 */ 710#ifndef _SYS_SYSPROTO_H_ 711struct select_args { 712 int nd; --- 61 unchanged lines hidden (view full) --- 774 if (uap->name == NULL) \ 775 ibits[x] = NULL; \ 776 else { \ 777 ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \ 778 obits[x] = sbp; \ 779 sbp += ncpbytes / sizeof *sbp; \ 780 error = copyin(uap->name, ibits[x], ncpbytes); \ 781 if (error != 0) \ |
778 goto done_noproclock; \ | 782 goto done_nosellock; \ |
779 } \ 780 } while (0) 781 getbits(in, 0); 782 getbits(ou, 1); 783 getbits(ex, 2); 784#undef getbits 785 if (nbufbytes != 0) 786 bzero(selbits, nbufbytes / 2); 787 788 if (uap->tv) { 789 error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 790 sizeof (atv)); 791 if (error) | 783 } \ 784 } while (0) 785 getbits(in, 0); 786 getbits(ou, 1); 787 getbits(ex, 2); 788#undef getbits 789 if (nbufbytes != 0) 790 bzero(selbits, nbufbytes / 2); 791 792 if (uap->tv) { 793 error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 794 sizeof (atv)); 795 if (error) |
792 goto done_noproclock; | 796 goto done_nosellock; |
793 if (itimerfix(&atv)) { 794 error = EINVAL; | 797 if (itimerfix(&atv)) { 798 error = EINVAL; |
795 goto done_noproclock; | 799 goto done_nosellock; |
796 } 797 getmicrouptime(&rtv); 798 timevaladd(&atv, &rtv); 799 } else { 800 atv.tv_sec = 0; 801 atv.tv_usec = 0; 802 } 803 timo = 0; | 800 } 801 getmicrouptime(&rtv); 802 timevaladd(&atv, &rtv); 803 } else { 804 atv.tv_sec = 0; 805 atv.tv_usec = 0; 806 } 807 timo = 0; |
804 PROC_LOCK(td->td_proc); | 808 mtx_lock(&sellock); |
805retry: 806 ncoll = nselcoll; 807 mtx_lock_spin(&sched_lock); 808 td->td_flags |= TDF_SELECT; 809 mtx_unlock_spin(&sched_lock); | 809retry: 810 ncoll = nselcoll; 811 mtx_lock_spin(&sched_lock); 812 td->td_flags |= TDF_SELECT; 813 mtx_unlock_spin(&sched_lock); |
810 PROC_UNLOCK(td->td_proc); | 814 mtx_unlock(&sellock); 815 816 /* XXX Is there a better place for this? */ 817 TAILQ_INIT(&td->td_selq); |
811 error = selscan(td, ibits, obits, uap->nd); | 818 error = selscan(td, ibits, obits, uap->nd); |
812 PROC_LOCK(td->td_proc); | 819 mtx_lock(&sellock); |
813 if (error || td->td_retval[0]) 814 goto done; 815 if (atv.tv_sec || atv.tv_usec) { 816 getmicrouptime(&rtv); | 820 if (error || td->td_retval[0]) 821 goto done; 822 if (atv.tv_sec || atv.tv_usec) { 823 getmicrouptime(&rtv); |
817 if (timevalcmp(&rtv, &atv, >=)) { 818 /* 819 * An event of our interest may occur during locking a process. 820 * In order to avoid missing the event that occured during locking 821 * the process, test TDF_SELECT and rescan file descriptors if 822 * necessary. 823 */ 824 mtx_lock_spin(&sched_lock); 825 if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) { 826 ncoll = nselcoll; 827 td->td_flags |= TDF_SELECT; 828 mtx_unlock_spin(&sched_lock); 829 PROC_UNLOCK(td->td_proc); 830 error = selscan(td, ibits, obits, uap->nd); 831 PROC_LOCK(td->td_proc); 832 } else 833 mtx_unlock_spin(&sched_lock); | 824 if (timevalcmp(&rtv, &atv, >=)) |
834 goto done; | 825 goto done; |
835 } | |
836 ttv = atv; 837 timevalsub(&ttv, &rtv); 838 timo = ttv.tv_sec > 24 * 60 * 60 ? 839 24 * 60 * 60 * hz : tvtohz(&ttv); 840 } | 826 ttv = atv; 827 timevalsub(&ttv, &rtv); 828 timo = ttv.tv_sec > 24 * 60 * 60 ? 829 24 * 60 * 60 * hz : tvtohz(&ttv); 830 } |
831 832 /* 833 * An event of interest may occur while we do not hold 834 * sellock, so check TDF_SELECT and the number of 835 * collisions and rescan the file descriptors if 836 * necessary. 837 */ |
|
841 mtx_lock_spin(&sched_lock); | 838 mtx_lock_spin(&sched_lock); |
842 td->td_flags &= ~TDF_SELECT; | 839 if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) { 840 mtx_unlock_spin(&sched_lock); 841 goto retry; 842 } |
843 mtx_unlock_spin(&sched_lock); 844 845 if (timo > 0) | 843 mtx_unlock_spin(&sched_lock); 844 845 if (timo > 0) |
846 error = cv_timedwait_sig(&selwait, &td->td_proc->p_mtx, timo); | 846 error = cv_timedwait_sig(&selwait, &sellock, timo); |
847 else | 847 else |
848 error = cv_wait_sig(&selwait, &td->td_proc->p_mtx); | 848 error = cv_wait_sig(&selwait, &sellock); |
849 850 if (error == 0) 851 goto retry; 852 853done: | 849 850 if (error == 0) 851 goto retry; 852 853done: |
854 clear_selinfo_list(td); |
|
854 mtx_lock_spin(&sched_lock); 855 td->td_flags &= ~TDF_SELECT; 856 mtx_unlock_spin(&sched_lock); | 855 mtx_lock_spin(&sched_lock); 856 td->td_flags &= ~TDF_SELECT; 857 mtx_unlock_spin(&sched_lock); |
857 PROC_UNLOCK(td->td_proc); 858done_noproclock: | 858 mtx_unlock(&sellock); 859 860done_nosellock: |
859 /* select is not restarted after signals... */ 860 if (error == ERESTART) 861 error = EINTR; 862 if (error == EWOULDBLOCK) 863 error = 0; 864#define putbits(name, x) \ 865 if (uap->name && (error2 = copyout(obits[x], uap->name, ncpbytes))) \ 866 error = error2; --- 95 unchanged lines hidden (view full) --- 962 } 963 ni = nfds * sizeof(struct pollfd); 964 if (ni > sizeof(smallbits)) 965 bits = malloc(ni, M_TEMP, M_WAITOK); 966 else 967 bits = smallbits; 968 error = copyin(SCARG(uap, fds), bits, ni); 969 if (error) | 861 /* select is not restarted after signals... */ 862 if (error == ERESTART) 863 error = EINTR; 864 if (error == EWOULDBLOCK) 865 error = 0; 866#define putbits(name, x) \ 867 if (uap->name && (error2 = copyout(obits[x], uap->name, ncpbytes))) \ 868 error = error2; --- 95 unchanged lines hidden (view full) --- 964 } 965 ni = nfds * sizeof(struct pollfd); 966 if (ni > sizeof(smallbits)) 967 bits = malloc(ni, M_TEMP, M_WAITOK); 968 else 969 bits = smallbits; 970 error = copyin(SCARG(uap, fds), bits, ni); 971 if (error) |
970 goto done_noproclock; | 972 goto done_nosellock; |
971 if (SCARG(uap, timeout) != INFTIM) { 972 atv.tv_sec = SCARG(uap, timeout) / 1000; 973 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000; 974 if (itimerfix(&atv)) { 975 error = EINVAL; | 973 if (SCARG(uap, timeout) != INFTIM) { 974 atv.tv_sec = SCARG(uap, timeout) / 1000; 975 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000; 976 if (itimerfix(&atv)) { 977 error = EINVAL; |
976 goto done_noproclock; | 978 goto done_nosellock; |
977 } 978 getmicrouptime(&rtv); 979 timevaladd(&atv, &rtv); 980 } else { 981 atv.tv_sec = 0; 982 atv.tv_usec = 0; 983 } 984 timo = 0; | 979 } 980 getmicrouptime(&rtv); 981 timevaladd(&atv, &rtv); 982 } else { 983 atv.tv_sec = 0; 984 atv.tv_usec = 0; 985 } 986 timo = 0; |
985 PROC_LOCK(td->td_proc); | 987 mtx_lock(&sellock); |
986retry: 987 ncoll = nselcoll; 988 mtx_lock_spin(&sched_lock); 989 td->td_flags |= TDF_SELECT; 990 mtx_unlock_spin(&sched_lock); | 988retry: 989 ncoll = nselcoll; 990 mtx_lock_spin(&sched_lock); 991 td->td_flags |= TDF_SELECT; 992 mtx_unlock_spin(&sched_lock); |
991 PROC_UNLOCK(td->td_proc); | 993 mtx_unlock(&sellock); 994 995 /* XXX Is there a better place for this? */ 996 TAILQ_INIT(&td->td_selq); |
992 error = pollscan(td, (struct pollfd *)bits, nfds); | 997 error = pollscan(td, (struct pollfd *)bits, nfds); |
993 PROC_LOCK(td->td_proc); | 998 mtx_lock(&sellock); |
994 if (error || td->td_retval[0]) 995 goto done; 996 if (atv.tv_sec || atv.tv_usec) { 997 getmicrouptime(&rtv); | 999 if (error || td->td_retval[0]) 1000 goto done; 1001 if (atv.tv_sec || atv.tv_usec) { 1002 getmicrouptime(&rtv); |
998 if (timevalcmp(&rtv, &atv, >=)) { 999 /* 1000 * An event of our interest may occur during locking a process. 1001 * In order to avoid missing the event that occured during locking 1002 * the process, test TDF_SELECT and rescan file descriptors if 1003 * necessary. 1004 */ 1005 mtx_lock_spin(&sched_lock); 1006 if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) { 1007 ncoll = nselcoll; 1008 td->td_flags |= TDF_SELECT; 1009 mtx_unlock_spin(&sched_lock); 1010 PROC_UNLOCK(td->td_proc); 1011 error = pollscan(td, (struct pollfd *)bits, nfds); 1012 PROC_LOCK(td->td_proc); 1013 } else 1014 mtx_unlock_spin(&sched_lock); | 1003 if (timevalcmp(&rtv, &atv, >=)) |
1015 goto done; | 1004 goto done; |
1016 } | |
1017 ttv = atv; 1018 timevalsub(&ttv, &rtv); 1019 timo = ttv.tv_sec > 24 * 60 * 60 ? 1020 24 * 60 * 60 * hz : tvtohz(&ttv); 1021 } | 1005 ttv = atv; 1006 timevalsub(&ttv, &rtv); 1007 timo = ttv.tv_sec > 24 * 60 * 60 ? 1008 24 * 60 * 60 * hz : tvtohz(&ttv); 1009 } |
1010 /* 1011 * An event of interest may occur while we do not hold 1012 * sellock, so check TDF_SELECT and the number of collisions 1013 * and rescan the file descriptors if necessary. 1014 */ |
|
1022 mtx_lock_spin(&sched_lock); | 1015 mtx_lock_spin(&sched_lock); |
1023 td->td_flags &= ~TDF_SELECT; | 1016 if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) { 1017 mtx_unlock_spin(&sched_lock); 1018 goto retry; 1019 } |
1024 mtx_unlock_spin(&sched_lock); | 1020 mtx_unlock_spin(&sched_lock); |
1021 |
|
1025 if (timo > 0) | 1022 if (timo > 0) |
1026 error = cv_timedwait_sig(&selwait, &td->td_proc->p_mtx, timo); | 1023 error = cv_timedwait_sig(&selwait, &sellock, timo); |
1027 else | 1024 else |
1028 error = cv_wait_sig(&selwait, &td->td_proc->p_mtx); | 1025 error = cv_wait_sig(&selwait, &sellock); 1026 |
1029 if (error == 0) 1030 goto retry; 1031 1032done: | 1027 if (error == 0) 1028 goto retry; 1029 1030done: |
1031 clear_selinfo_list(td); |
|
1033 mtx_lock_spin(&sched_lock); 1034 td->td_flags &= ~TDF_SELECT; 1035 mtx_unlock_spin(&sched_lock); | 1032 mtx_lock_spin(&sched_lock); 1033 td->td_flags &= ~TDF_SELECT; 1034 mtx_unlock_spin(&sched_lock); |
1036 PROC_UNLOCK(td->td_proc); 1037done_noproclock: | 1035 mtx_unlock(&sellock); 1036 1037done_nosellock: |
1038 /* poll is not restarted after signals... */ 1039 if (error == ERESTART) 1040 error = EINTR; 1041 if (error == EWOULDBLOCK) 1042 error = 0; 1043 if (error == 0) { 1044 error = copyout(bits, SCARG(uap, fds), ni); 1045 if (error) --- 64 unchanged lines hidden (view full) --- 1110int 1111openbsd_poll(td, uap) 1112 register struct thread *td; 1113 register struct openbsd_poll_args *uap; 1114{ 1115 return (poll(td, (struct poll_args *)uap)); 1116} 1117 | 1038 /* poll is not restarted after signals... */ 1039 if (error == ERESTART) 1040 error = EINTR; 1041 if (error == EWOULDBLOCK) 1042 error = 0; 1043 if (error == 0) { 1044 error = copyout(bits, SCARG(uap, fds), ni); 1045 if (error) --- 64 unchanged lines hidden (view full) --- 1110int 1111openbsd_poll(td, uap) 1112 register struct thread *td; 1113 register struct openbsd_poll_args *uap; 1114{ 1115 return (poll(td, (struct poll_args *)uap)); 1116} 1117 |
1118/* 1119 * Remove the references to the thread from all of the objects 1120 * we were polling. 1121 * 1122 * This code assumes that the underlying owner of the selinfo 1123 * structure will hold sellock before it changes it, and that 1124 * it will unlink itself from our list if it goes away. 1125 */ 1126void 1127clear_selinfo_list(td) 1128 struct thread *td; 1129{ 1130 struct selinfo *si; 1131 1132 mtx_assert(&sellock, MA_OWNED); 1133 TAILQ_FOREACH(si, &td->td_selq, si_thrlist) 1134 si->si_thread = NULL; 1135 TAILQ_INIT(&td->td_selq); 1136} 1137 |
|
1118/*ARGSUSED*/ 1119int 1120seltrue(dev, events, td) 1121 dev_t dev; 1122 int events; 1123 struct thread *td; 1124{ 1125 1126 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 1127} 1128 | 1138/*ARGSUSED*/ 1139int 1140seltrue(dev, events, td) 1141 dev_t dev; 1142 int events; 1143 struct thread *td; 1144{ 1145 1146 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 1147} 1148 |
1129static int 1130find_thread_in_proc(struct proc *p, struct thread *td) 1131{ 1132 struct thread *td2; 1133 FOREACH_THREAD_IN_PROC(p, td2) { 1134 if (td2 == td) { 1135 return (1); 1136 } 1137 } 1138 return (0); 1139} 1140 | |
1141/* 1142 * Record a select request. 1143 */ 1144void 1145selrecord(selector, sip) 1146 struct thread *selector; 1147 struct selinfo *sip; 1148{ | 1149/* 1150 * Record a select request. 1151 */ 1152void 1153selrecord(selector, sip) 1154 struct thread *selector; 1155 struct selinfo *sip; 1156{ |
1149 struct proc *p; 1150 pid_t mypid; | |
1151 | 1157 |
1152 mypid = selector->td_proc->p_pid; 1153 if ((sip->si_pid == mypid) && 1154 (sip->si_thread == selector)) { /* XXXKSE should be an ID? */ 1155 return; | 1158 mtx_lock(&sellock); 1159 /* 1160 * If the thread is NULL then take ownership of selinfo 1161 * however if the thread is not NULL and the thread points to 1162 * someone else, then we have a collision, otherwise leave it alone 1163 * as we've owned it in a previous selrecord on this selinfo. 1164 */ 1165 if (sip->si_thread == NULL) { 1166 sip->si_thread = selector; 1167 TAILQ_INSERT_TAIL(&selector->td_selq, sip, si_thrlist); 1168 } else if (sip->si_thread != selector) { 1169 sip->si_flags |= SI_COLL; |
1156 } | 1170 } |
1157 if (sip->si_pid && 1158 (p = pfind(sip->si_pid)) && 1159 (find_thread_in_proc(p, sip->si_thread))) { 1160 mtx_lock_spin(&sched_lock); 1161 if (sip->si_thread->td_wchan == (caddr_t)&selwait) { 1162 mtx_unlock_spin(&sched_lock); 1163 PROC_UNLOCK(p); 1164 sip->si_flags |= SI_COLL; 1165 return; 1166 } 1167 mtx_unlock_spin(&sched_lock); 1168 PROC_UNLOCK(p); 1169 } 1170 sip->si_pid = mypid; 1171 sip->si_thread = selector; | 1171 1172 mtx_unlock(&sellock); |
1172} 1173 1174/* 1175 * Do a wakeup when a selectable event occurs. 1176 */ 1177void 1178selwakeup(sip) | 1173} 1174 1175/* 1176 * Do a wakeup when a selectable event occurs. 1177 */ 1178void 1179selwakeup(sip) |
1179 register struct selinfo *sip; | 1180 struct selinfo *sip; |
1180{ 1181 struct thread *td; | 1181{ 1182 struct thread *td; |
1182 register struct proc *p; | |
1183 | 1183 |
1184 if (sip->si_pid == 0) 1185 return; 1186 if (sip->si_flags & SI_COLL) { | 1184 mtx_lock(&sellock); 1185 td = sip->si_thread; 1186 if ((sip->si_flags & SI_COLL) != 0) { |
1187 nselcoll++; 1188 sip->si_flags &= ~SI_COLL; 1189 cv_broadcast(&selwait); 1190 } | 1187 nselcoll++; 1188 sip->si_flags &= ~SI_COLL; 1189 cv_broadcast(&selwait); 1190 } |
1191 p = pfind(sip->si_pid); 1192 sip->si_pid = 0; 1193 td = sip->si_thread; 1194 if (p != NULL) { 1195 if (!find_thread_in_proc(p, td)) { 1196 PROC_UNLOCK(p); /* lock is in pfind() */; 1197 return; 1198 } 1199 mtx_lock_spin(&sched_lock); 1200 if (td->td_wchan == (caddr_t)&selwait) { 1201 if (td->td_proc->p_stat == SSLEEP) 1202 setrunnable(td); 1203 else 1204 cv_waitq_remove(td); 1205 } else 1206 td->td_flags &= ~TDF_SELECT; 1207 mtx_unlock_spin(&sched_lock); 1208 PROC_UNLOCK(p); /* Lock is in pfind() */ | 1191 if (td == NULL) { 1192 mtx_unlock(&sellock); 1193 return; |
1209 } | 1194 } |
1195 TAILQ_REMOVE(&td->td_selq, sip, si_thrlist); 1196 sip->si_thread = NULL; 1197 mtx_lock_spin(&sched_lock); 1198 if (td->td_wchan == (caddr_t)&selwait) { 1199 if (td->td_proc->p_stat == SSLEEP) 1200 setrunnable(td); 1201 else 1202 cv_waitq_remove(td); 1203 } else 1204 td->td_flags &= ~TDF_SELECT; 1205 mtx_unlock_spin(&sched_lock); 1206 mtx_unlock(&sellock); |
|
1210} 1211 1212static void selectinit __P((void *)); 1213SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, selectinit, NULL) 1214 1215/* ARGSUSED*/ 1216static void 1217selectinit(dummy) 1218 void *dummy; 1219{ 1220 cv_init(&selwait, "select"); | 1207} 1208 1209static void selectinit __P((void *)); 1210SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, selectinit, NULL) 1211 1212/* ARGSUSED*/ 1213static void 1214selectinit(dummy) 1215 void *dummy; 1216{ 1217 cv_init(&selwait, "select"); |
1218 mtx_init(&sellock, "sellck", MTX_DEF); |
|
1221} | 1219} |