|
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 { |