性能优化

This commit is contained in:
zsxxsz 2014-02-26 22:57:09 +08:00
parent b8360008e5
commit ecc0992eb1
6 changed files with 124 additions and 16 deletions

View File

@ -1,6 +1,18 @@
修改历史列表:
------------------------------------------------------------------------
430) 2014.2.26
430.1) performance: events.h 将自旋锁的方式关闭否则在32位机器上会造成 CPU
过高
429) 2014.2.24
429.1) bugfix: events_epoll_thr.c 当流对象有缓存数据需要事件引擎从应用级触发时,
为了防止主线程在子线程的函数 event_enable_read 中修改 fdtabs 和调用
epoll_ctl/EPOLL_CTL_ADD 之间调用了 event_disable_readwrite 中的
epoll_ctl/EPOLL_CTL_DEL 而出错,需要在 event_enable_read 区分处理互斥锁的位置
------------------------------------------------------------------------
428) 2014.2.22
428.1) bugfix: events_iocp.c 关闭未决状态的完成端口在 WIN XP 下存在 BUG应该
在套接字关闭前先取得完成端口状态

View File

@ -155,9 +155,11 @@ struct ACL_EVENT {
};
/* 如果采用自旋锁,必须保持加锁时间非常短 */
/*
#ifdef ACL_HAS_SPINLOCK
#define EVENT_USE_SPINLOCK
#endif
*/
typedef struct EVENT_THR {
ACL_EVENT event;

View File

@ -50,6 +50,14 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream,
ACL_EVENT_FDTABLE *fdp;
ACL_SOCKET sockfd;
struct epoll_event ev;
int fd_ready;
if (ACL_VSTREAM_BFRD_CNT(stream) > 0
|| (stream->flag & ACL_VSTREAM_FLAG_BAD))
{
fd_ready = 1;
} else
fd_ready = 0;
sockfd = ACL_VSTREAM_SOCK(stream);
fdp = (ACL_EVENT_FDTABLE*) stream->fdp;
@ -80,13 +88,20 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream,
}
if ((fdp->flag & EVENT_FDTABLE_FLAG_READ) != 0)
{
acl_msg_info("has set read");
return;
}
stream->nrefer++;
fdp->flag = EVENT_FDTABLE_FLAG_READ | EVENT_FDTABLE_FLAG_EXPT;
memset(&ev, 0, sizeof(ev));
#if 0
ev.events = EPOLLIN | EPOLLHUP | EPOLLERR | EPOLLET;
#else
ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;
#endif
ev.data.ptr = fdp;
THREAD_LOCK(&event_thr->event.tb_mutex);
@ -94,13 +109,41 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream,
fdp->fdidx = eventp->fdcnt;
eventp->fdtabs[eventp->fdcnt++] = fdp;
THREAD_UNLOCK(&event_thr->event.tb_mutex);
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD, sockfd, &ev) < 0)
if (fd_ready) {
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD,
sockfd, &ev) < 0)
{
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}
THREAD_UNLOCK(&event_thr->event.tb_mutex);
if (event_thr->event.blocked && event_thr->event.evdog
&& event_dog_client(event_thr->event.evdog) != stream)
{
event_dog_notify(event_thr->event.evdog);
}
} else {
THREAD_UNLOCK(&event_thr->event.tb_mutex);
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD,
sockfd, &ev) < 0)
{
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}
}
}
static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream,
int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context)
{
@ -155,10 +198,15 @@ static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream,
THREAD_UNLOCK(&event_thr->event.tb_mutex);
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD, sockfd, &ev) < 0)
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD, sockfd, &ev) < 0) {
if (errno == EEXIST)
acl_msg_warn("%s: epool_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epool_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}
}
static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream,
int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context)
@ -168,6 +216,12 @@ static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream,
ACL_EVENT_FDTABLE *fdp;
ACL_SOCKET sockfd;
struct epoll_event ev;
int fd_ready;
if ((stream->flag & ACL_VSTREAM_FLAG_BAD))
fd_ready = 1;
else
fd_ready = 0;
sockfd = ACL_VSTREAM_SOCK(stream);
fdp = (ACL_EVENT_FDTABLE*) stream->fdp;
@ -212,13 +266,35 @@ static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream,
fdp->fdidx = eventp->fdcnt;
eventp->fdtabs[eventp->fdcnt++] = fdp;
THREAD_UNLOCK(&event_thr->event.tb_mutex);
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD, sockfd, &ev) < 0)
if (fd_ready) {
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD,
sockfd, &ev) < 0)
{
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}
THREAD_UNLOCK(&event_thr->event.tb_mutex);
} else {
THREAD_UNLOCK(&event_thr->event.tb_mutex);
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD,
sockfd, &ev) < 0)
{
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}
}
}
/* event_disable_readwrite - disable request for read or write events */
static void event_disable_readwrite(ACL_EVENT *eventp, ACL_VSTREAM *stream)
@ -262,13 +338,22 @@ static void event_disable_readwrite(ACL_EVENT *eventp, ACL_VSTREAM *stream)
if (fdp->flag & EVENT_FDTABLE_FLAG_READ)
stream->nrefer--;
else
acl_msg_info("not set read");
if (fdp->flag & EVENT_FDTABLE_FLAG_WRITE)
stream->nrefer--;
event_fdtable_reset(fdp);
if (epoll_ctl(event_thr->handle, EPOLL_CTL_DEL, sockfd, NULL) < 0)
acl_msg_fatal("%s: epoll_ctl: %s", myname, acl_last_serror());
if (epoll_ctl(event_thr->handle, EPOLL_CTL_DEL, sockfd, NULL) < 0) {
if (errno == ENOENT)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}
}
static int event_isrset(ACL_EVENT *eventp acl_unused, ACL_VSTREAM *stream)
@ -438,6 +523,13 @@ TAG_DONE:
event_thr_fire(eventp);
}
static void event_add_dog(ACL_EVENT *eventp)
{
EVENT_EPOLL_THR *event_thr = (EVENT_EPOLL_THR*) eventp;
event_thr->event.evdog = event_dog_create((ACL_EVENT*) event_thr, 1);
}
static void event_free(ACL_EVENT *eventp)
{
const char *myname = "event_free";
@ -468,6 +560,7 @@ ACL_EVENT *event_epoll_alloc_thr(int fdsize acl_unused)
event_thr->event.event.use_thread = 1;
event_thr->event.event.loop_fn = event_loop;
event_thr->event.event.free_fn = event_free;
event_thr->event.event.add_dog_fn = event_add_dog;
event_thr->event.event.enable_read_fn = event_enable_read;
event_thr->event.event.enable_write_fn = event_enable_write;
event_thr->event.event.enable_listen_fn = event_enable_listen;

View File

@ -748,7 +748,7 @@ static ACL_EVENT *event_open(int event_mode, acl_pthread_pool_t *threads)
acl_event_set_fire_hook(event, event_fire_begin,
event_fire_end, threads);
if (acl_var_threads_check_inter > 0)
if (acl_var_threads_check_inter >= 0)
acl_event_set_check_inter(event, acl_var_threads_check_inter);
if (acl_var_threads_qlen_warn > 0)

View File

@ -136,7 +136,7 @@ private:
static void service_exit(void*);
// 当线程创建后调用的回调函数
static void thread_init(void*);
static int thread_init(void*);
// 当线程退出前调用的回调函数
static void thread_exit(void*);

View File

@ -258,10 +258,11 @@ void master_threads2::service_exit(void*)
__mt->proc_on_exit();
}
void master_threads2::thread_init(void*)
int master_threads2::thread_init(void*)
{
acl_assert(__mt != NULL);
__mt->thread_on_init();
return 0;
}
void master_threads2::thread_exit(void*)