Lines 13-19
Link Here
|
13 |
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings |
13 |
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings |
14 |
* AB. All Rights Reserved.'' |
14 |
* AB. All Rights Reserved.'' |
15 |
* |
15 |
* |
16 |
* $Id$ |
16 |
* 2005-08-31 |
|
|
17 |
* This has been modified by Matthew Reilly of SIPphone Inc. to |
18 |
* enable kernel poll (+K true) support via the epoll mechanism in Linux 2.6 |
19 |
* Portions created by SIPphone Inc. are Copyright 2005, SIPphone Inc. |
20 |
* These modifications are released under the Erlang Public License. |
21 |
* |
22 |
* $Id: otp_src_R10B-6_epoll.patch,v 1.1 2005/09/02 00:18:04 mreilly Exp $ |
17 |
*/ |
23 |
*/ |
18 |
|
24 |
|
19 |
#ifdef HAVE_CONFIG_H |
25 |
#ifdef HAVE_CONFIG_H |
Lines 50-55
Link Here
|
50 |
# define USE_DEVPOLL |
56 |
# define USE_DEVPOLL |
51 |
# include <sys/devpoll.h> |
57 |
# include <sys/devpoll.h> |
52 |
# endif |
58 |
# endif |
|
|
59 |
# ifdef HAVE_LINUX_EPOLL_H /* Too minimize code changes, we pretend we have HAVE_LINUX_KPOLL_H as well */ |
60 |
# define HAVE_LINUX_KPOLL_H 1 |
61 |
# endif |
53 |
# ifdef HAVE_LINUX_KPOLL_H |
62 |
# ifdef HAVE_LINUX_KPOLL_H |
54 |
# define USE_DEVPOLL |
63 |
# define USE_DEVPOLL |
55 |
# include <asm/page.h> |
64 |
# include <asm/page.h> |
Lines 58-64
Link Here
|
58 |
# ifndef POLLREMOVE |
67 |
# ifndef POLLREMOVE |
59 |
# define POLLREMOVE 0x1000 /* some day it will make it to bits/poll.h ;-) */ |
68 |
# define POLLREMOVE 0x1000 /* some day it will make it to bits/poll.h ;-) */ |
60 |
# endif |
69 |
# endif |
61 |
# include <linux/kpoll.h> |
70 |
# ifdef HAVE_LINUX_EPOLL_H |
|
|
71 |
# include <sys/epoll.h> |
72 |
# else |
73 |
# include <linux/kpoll.h> |
74 |
# endif |
62 |
# endif |
75 |
# endif |
63 |
# ifdef USE_DEVPOLL /* can only use one of them ... */ |
76 |
# ifdef USE_DEVPOLL /* can only use one of them ... */ |
64 |
# ifdef USE_KQUEUE |
77 |
# ifdef USE_KQUEUE |
Lines 201-208
Link Here
|
201 |
|
214 |
|
202 |
static int dev_poll_fd; /* fd for /dev/poll */ |
215 |
static int dev_poll_fd; /* fd for /dev/poll */ |
203 |
#ifdef HAVE_LINUX_KPOLL_H |
216 |
#ifdef HAVE_LINUX_KPOLL_H |
|
|
217 |
|
218 |
#ifdef HAVE_LINUX_EPOLL_H |
219 |
static struct epoll_event* dev_epoll_map; |
220 |
/* XXX Implement correct mapping from POLLIN/POLLOUT to/from EPOLLIN/EPOLLOUT */ |
221 |
/* Currenltly POLLIN/POLLOUT == EPOLLIN/EPOLLOUT. So these macros will work */ |
222 |
#define EPOLL_TO_POLL(bit_map) (bit_map) |
223 |
#define POLL_TO_EPOLL(bit_map) (bit_map & (EPOLLIN|EPOLLOUT)) |
224 |
#else |
204 |
static char * dev_poll_map; /* mmap'ed area from kernel /dev/kpoll */ |
225 |
static char * dev_poll_map; /* mmap'ed area from kernel /dev/kpoll */ |
205 |
static struct k_poll dev_poll; /* control block for /dev/kpoll */ |
226 |
static struct k_poll dev_poll; /* control block for /dev/kpoll */ |
|
|
227 |
#endif /* HAVE_LINUX_KPOLL_H */ |
206 |
static int max_poll_idx; /* highest non /dev/kpoll fd */ |
228 |
static int max_poll_idx; /* highest non /dev/kpoll fd */ |
207 |
|
229 |
|
208 |
static void kpoll_enable(); |
230 |
static void kpoll_enable(); |
Lines 212-218
Link Here
|
212 |
static struct pollfd* dev_poll_rfds = NULL; /* Allocated at startup */ |
234 |
static struct pollfd* dev_poll_rfds = NULL; /* Allocated at startup */ |
213 |
|
235 |
|
214 |
static void devpoll_init(void); |
236 |
static void devpoll_init(void); |
215 |
static void devpoll_update_pix(int pix); |
237 |
static void devpoll_update_pix(int pix, int old_events); |
216 |
#ifdef HAVE_SYS_DEVPOLL_H |
238 |
#ifdef HAVE_SYS_DEVPOLL_H |
217 |
static void devpoll_clear_pix(int pix); |
239 |
static void devpoll_clear_pix(int pix); |
218 |
#endif /* HAVE_SYS_DEVPOLL_H */ |
240 |
#endif /* HAVE_SYS_DEVPOLL_H */ |
Lines 2021-2027
Link Here
|
2021 |
|
2043 |
|
2022 |
#ifdef USE_DEVPOLL |
2044 |
#ifdef USE_DEVPOLL |
2023 |
if (poll_fds[pix].events != old_events) |
2045 |
if (poll_fds[pix].events != old_events) |
2024 |
devpoll_update_pix(pix); |
2046 |
devpoll_update_pix(pix, old_events); |
2025 |
#endif |
2047 |
#endif |
2026 |
#ifdef USE_KQUEUE |
2048 |
#ifdef USE_KQUEUE |
2027 |
if (poll_fds[pix].events != old_events) |
2049 |
if (poll_fds[pix].events != old_events) |
Lines 2077-2083
Link Here
|
2077 |
if ( old_events && (dev_poll_fd != -1) ) { |
2099 |
if ( old_events && (dev_poll_fd != -1) ) { |
2078 |
/* Tell /dev/[k]poll that we are not interested any more ... */ |
2100 |
/* Tell /dev/[k]poll that we are not interested any more ... */ |
2079 |
poll_fds[pix].events = POLLREMOVE; |
2101 |
poll_fds[pix].events = POLLREMOVE; |
2080 |
devpoll_update_pix(pix); |
2102 |
devpoll_update_pix(pix, old_events); |
2081 |
/* devpoll_update_pix may change the pix */ |
2103 |
/* devpoll_update_pix may change the pix */ |
2082 |
pix = fd_data[fd].pix; |
2104 |
pix = fd_data[fd].pix; |
2083 |
poll_fds[pix].events = 0; |
2105 |
poll_fds[pix].events = 0; |
Lines 2134-2140
Link Here
|
2134 |
#ifdef HAVE_SYS_DEVPOLL_H |
2156 |
#ifdef HAVE_SYS_DEVPOLL_H |
2135 |
devpoll_clear_pix(pix); |
2157 |
devpoll_clear_pix(pix); |
2136 |
#endif /* HAVE_SYS_DEVPOLL_H */ |
2158 |
#endif /* HAVE_SYS_DEVPOLL_H */ |
2137 |
devpoll_update_pix(pix); |
2159 |
devpoll_update_pix(pix, old_events); |
2138 |
} |
2160 |
} |
2139 |
#endif |
2161 |
#endif |
2140 |
#ifdef USE_KQUEUE |
2162 |
#ifdef USE_KQUEUE |
Lines 2692-2697
Link Here
|
2692 |
nof_ready_fds = vr; |
2714 |
nof_ready_fds = vr; |
2693 |
|
2715 |
|
2694 |
#if HAVE_LINUX_KPOLL_H |
2716 |
#if HAVE_LINUX_KPOLL_H |
|
|
2717 |
#ifdef HAVE_LINUX_EPOLL_H |
2718 |
if ( do_event_poll ) { |
2719 |
if ((r = epoll_wait(dev_poll_fd,dev_epoll_map,max_fd_plus_one,0)) > 0) { |
2720 |
for (i = 0; (i < r); i++) { |
2721 |
short revents = dev_epoll_map[i].events; |
2722 |
|
2723 |
if (revents != 0) { |
2724 |
int fd = dev_epoll_map[i].data.fd; |
2725 |
rp->pfd.fd = fd; |
2726 |
rp->pfd.events = poll_fds[fd_data[fd].pix].events; |
2727 |
rp->pfd.revents = EPOLL_TO_POLL(revents); |
2728 |
rp->iport = fd_data[fd].inport; |
2729 |
rp->oport = fd_data[fd].outport; |
2730 |
rp++; |
2731 |
nof_ready_fds ++; |
2732 |
} |
2733 |
} |
2734 |
} |
2735 |
} |
2736 |
|
2737 |
#else |
2695 |
if ( do_event_poll ) { |
2738 |
if ( do_event_poll ) { |
2696 |
/* Now do the fast poll */ |
2739 |
/* Now do the fast poll */ |
2697 |
dev_poll.kp_timeout = 0; |
2740 |
dev_poll.kp_timeout = 0; |
Lines 2714-2719
Link Here
|
2714 |
nof_ready_fds += r; |
2757 |
nof_ready_fds += r; |
2715 |
} |
2758 |
} |
2716 |
} |
2759 |
} |
|
|
2760 |
#endif /*HAVE_LINUX_EPOLL_H */ |
2717 |
#endif |
2761 |
#endif |
2718 |
|
2762 |
|
2719 |
} else { |
2763 |
} else { |
Lines 3622-3627
Link Here
|
3622 |
poll_fds[pix].revents = 0; |
3666 |
poll_fds[pix].revents = 0; |
3623 |
} |
3667 |
} |
3624 |
|
3668 |
|
|
|
3669 |
#ifdef HAVE_LINUX_EPOLL_H |
3670 |
static void epoll_init() |
3671 |
{ |
3672 |
/* max_files is just a hint to the kernel */ |
3673 |
if ( (dev_poll_fd=epoll_create(max_files)) < 0 ) { |
3674 |
DEBUGF(("Will use poll()\n")); |
3675 |
dev_poll_fd = -1; /* We will not use ekpoll */ |
3676 |
} else { |
3677 |
DEBUGF(("Will use epoll\n")); |
3678 |
dev_epoll_map = (struct epoll_event *) erts_alloc(ERTS_ALC_T_POLL_FDS, (sizeof(struct epoll_event) * max_files)); |
3679 |
erts_sys_misc_mem_sz += sizeof(struct epoll_event) * max_files; |
3680 |
} |
3681 |
} |
3682 |
#else |
3625 |
static void kpoll_init() |
3683 |
static void kpoll_init() |
3626 |
{ |
3684 |
{ |
3627 |
if ( (dev_poll_fd=open("/dev/kpoll",O_RDWR)) < 0 ) { |
3685 |
if ( (dev_poll_fd=open("/dev/kpoll",O_RDWR)) < 0 ) { |
Lines 3643-3648
Link Here
|
3643 |
dev_poll_rfds = NULL; |
3701 |
dev_poll_rfds = NULL; |
3644 |
} |
3702 |
} |
3645 |
} |
3703 |
} |
|
|
3704 |
#endif /* HAVE_LINUX_EPOLL_H */ |
3646 |
|
3705 |
|
3647 |
#endif /* HAVE_LINUX_KPOLL_H */ |
3706 |
#endif /* HAVE_LINUX_KPOLL_H */ |
3648 |
|
3707 |
|
Lines 3672-3678
Link Here
|
3672 |
} else { |
3731 |
} else { |
3673 |
/* Determine use of poll vs. /dev/poll at runtime */ |
3732 |
/* Determine use of poll vs. /dev/poll at runtime */ |
3674 |
#ifdef HAVE_LINUX_KPOLL_H |
3733 |
#ifdef HAVE_LINUX_KPOLL_H |
|
|
3734 |
#ifdef HAVE_LINUX_EPOLL_H |
3735 |
epoll_init(); |
3736 |
#else |
3675 |
kpoll_init(); |
3737 |
kpoll_init(); |
|
|
3738 |
#endif |
3676 |
#else |
3739 |
#else |
3677 |
#ifdef HAVE_SYS_DEVPOLL_H |
3740 |
#ifdef HAVE_SYS_DEVPOLL_H |
3678 |
solaris_devpoll_init(); |
3741 |
solaris_devpoll_init(); |
Lines 3698-3704
Link Here
|
3698 |
return count; |
3761 |
return count; |
3699 |
} |
3762 |
} |
3700 |
|
3763 |
|
3701 |
static void devpoll_update_pix(int pix) |
3764 |
static void devpoll_update_pix(int pix, int old_events) |
3702 |
{ |
3765 |
{ |
3703 |
int res; |
3766 |
int res; |
3704 |
|
3767 |
|
Lines 3713-3722
Link Here
|
3713 |
|
3776 |
|
3714 |
#endif |
3777 |
#endif |
3715 |
if ( dev_poll_fd != -1 ) { |
3778 |
if ( dev_poll_fd != -1 ) { |
|
|
3779 |
#ifdef HAVE_LINUX_EPOLL_H |
3780 |
int events = poll_fds[pix].events; |
3781 |
int fd = poll_fds[pix].fd; |
3782 |
if (old_events && events & POLLREMOVE) { |
3783 |
/* Delete file descriptor from epoll list */ |
3784 |
res = epoll_ctl(dev_poll_fd,EPOLL_CTL_DEL,fd,NULL); |
3785 |
/* XXX check return code */ |
3786 |
} else { |
3787 |
struct epoll_event epoll_ctl_event; |
3788 |
epoll_ctl_event.data.fd = fd; |
3789 |
epoll_ctl_event.events = POLL_TO_EPOLL(events); |
3790 |
if (old_events) { |
3791 |
/* Modify exiting fd */ |
3792 |
res = epoll_ctl(dev_poll_fd,EPOLL_CTL_MOD,fd,&epoll_ctl_event); |
3793 |
/* XXX check return code */ |
3794 |
} else { |
3795 |
/* Add fd to epoll list */ |
3796 |
res = epoll_ctl(dev_poll_fd,EPOLL_CTL_ADD,fd,&epoll_ctl_event); |
3797 |
/* XXX check return code */ |
3798 |
} |
3799 |
} |
3800 |
#else |
3716 |
if ( (res=devpoll_write(dev_poll_fd,&poll_fds[pix],sizeof(struct pollfd))) != |
3801 |
if ( (res=devpoll_write(dev_poll_fd,&poll_fds[pix],sizeof(struct pollfd))) != |
3717 |
(sizeof(struct pollfd)) ) { |
3802 |
(sizeof(struct pollfd)) ) { |
3718 |
erl_exit(1,"Can't write to /dev/poll\n"); |
3803 |
erl_exit(1,"Can't write to /dev/poll\n"); |
3719 |
} |
3804 |
} |
|
|
3805 |
#endif /* HAVE_LINUX_EPOLL_H */ |
3720 |
} |
3806 |
} |
3721 |
#if HAVE_LINUX_KPOLL_H |
3807 |
#if HAVE_LINUX_KPOLL_H |
3722 |
} else { |
3808 |
} else { |