mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -04:00
Add event_config_set_num_cpus_hint for tuning thread pools, etc.
This commit is contained in:
parent
499452f4c2
commit
2447fe8886
@ -285,6 +285,7 @@ struct event_config_entry {
|
|||||||
struct event_config {
|
struct event_config {
|
||||||
TAILQ_HEAD(event_configq, event_config_entry) entries;
|
TAILQ_HEAD(event_configq, event_config_entry) entries;
|
||||||
|
|
||||||
|
int n_cpus_hint;
|
||||||
enum event_method_feature require_features;
|
enum event_method_feature require_features;
|
||||||
enum event_base_config_flag flags;
|
enum event_base_config_flag flags;
|
||||||
};
|
};
|
||||||
|
15
event.c
15
event.c
@ -615,19 +615,19 @@ event_base_new_with_config(const struct event_config *cfg)
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (cfg && (cfg->flags & EVENT_BASE_FLAG_STARTUP_IOCP))
|
if (cfg && (cfg->flags & EVENT_BASE_FLAG_STARTUP_IOCP))
|
||||||
event_base_start_iocp(base);
|
event_base_start_iocp(base, cfg->n_cpus_hint);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (base);
|
return (base);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
event_base_start_iocp(struct event_base *base)
|
event_base_start_iocp(struct event_base *base, int n_cpus)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (base->iocp)
|
if (base->iocp)
|
||||||
return 0;
|
return 0;
|
||||||
base->iocp = event_iocp_port_launch();
|
base->iocp = event_iocp_port_launch(n_cpus);
|
||||||
if (!base->iocp) {
|
if (!base->iocp) {
|
||||||
event_warnx("%s: Couldn't launch IOCP", __func__);
|
event_warnx("%s: Couldn't launch IOCP", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
@ -918,6 +918,15 @@ event_config_require_features(struct event_config *cfg,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
event_config_set_num_cpus_hint(struct event_config *cfg, int cpus)
|
||||||
|
{
|
||||||
|
if (!cfg)
|
||||||
|
return (-1);
|
||||||
|
cfg->n_cpus_hint = cpus;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
event_priority_init(int npriorities)
|
event_priority_init(int npriorities)
|
||||||
{
|
{
|
||||||
|
12
event_iocp.c
12
event_iocp.c
@ -162,8 +162,10 @@ event_get_win32_extension_fns(void)
|
|||||||
return &the_extension_fns;
|
return &the_extension_fns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define N_CPUS_DEFAULT 2
|
||||||
|
|
||||||
struct event_iocp_port *
|
struct event_iocp_port *
|
||||||
event_iocp_port_launch(void)
|
event_iocp_port_launch(int n_cpus)
|
||||||
{
|
{
|
||||||
struct event_iocp_port *port;
|
struct event_iocp_port *port;
|
||||||
int i;
|
int i;
|
||||||
@ -173,12 +175,16 @@ event_iocp_port_launch(void)
|
|||||||
|
|
||||||
if (!(port = mm_calloc(1, sizeof(struct event_iocp_port))))
|
if (!(port = mm_calloc(1, sizeof(struct event_iocp_port))))
|
||||||
return NULL;
|
return NULL;
|
||||||
port->n_threads = 2;
|
|
||||||
|
if (n_cpus <= 0)
|
||||||
|
n_cpus = N_CPUS_DEFAULT;
|
||||||
|
port->n_threads = n_cpus * 2;
|
||||||
port->threads = calloc(port->n_threads, sizeof(HANDLE));
|
port->threads = calloc(port->n_threads, sizeof(HANDLE));
|
||||||
if (!port->threads)
|
if (!port->threads)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
port->port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, port->n_threads);
|
port->port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
|
||||||
|
n_cpus);
|
||||||
port->ms = -1;
|
port->ms = -1;
|
||||||
if (!port->port)
|
if (!port->port)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -226,6 +226,16 @@ int event_config_require_features(struct event_config *cfg, int feature);
|
|||||||
* will be initialized, and how they'll work. */
|
* will be initialized, and how they'll work. */
|
||||||
int event_config_set_flag(struct event_config *cfg, int flag);
|
int event_config_set_flag(struct event_config *cfg, int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records a hint for the number of CPUs in the system. This is used for
|
||||||
|
* tuning thread pools, etc, for optimal performance.
|
||||||
|
*
|
||||||
|
* @param cfg the event configuration object
|
||||||
|
* @param cpus the number of cpus
|
||||||
|
* @return 0 on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
int event_config_set_num_cpus_hint(struct event_config *cfg, int cpus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize the event API.
|
Initialize the event API.
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ void evbuffer_commit_write(struct evbuffer *, ev_ssize_t);
|
|||||||
|
|
||||||
This interface is unstable, and will change.
|
This interface is unstable, and will change.
|
||||||
*/
|
*/
|
||||||
struct event_iocp_port *event_iocp_port_launch(void);
|
struct event_iocp_port *event_iocp_port_launch(int n_cpus);
|
||||||
|
|
||||||
/** Associate a file descriptor with an iocp, such that overlapped IO on the
|
/** Associate a file descriptor with an iocp, such that overlapped IO on the
|
||||||
fd will happen on one of the iocp's worker threads.
|
fd will happen on one of the iocp's worker threads.
|
||||||
@ -181,7 +181,7 @@ struct event_base;
|
|||||||
struct event_iocp_port *event_base_get_iocp(struct event_base *base);
|
struct event_iocp_port *event_base_get_iocp(struct event_base *base);
|
||||||
|
|
||||||
/* FIXME document. */
|
/* FIXME document. */
|
||||||
int event_base_start_iocp(struct event_base *base);
|
int event_base_start_iocp(struct event_base *base, int n_cpus);
|
||||||
void event_base_stop_iocp(struct event_base *base);
|
void event_base_stop_iocp(struct event_base *base);
|
||||||
|
|
||||||
/* FIXME document. */
|
/* FIXME document. */
|
||||||
|
@ -133,7 +133,7 @@ main(int argc, char **argv)
|
|||||||
case 'i':
|
case 'i':
|
||||||
use_iocp = 1;
|
use_iocp = 1;
|
||||||
evthread_use_windows_threads();
|
evthread_use_windows_threads();
|
||||||
event_base_start_iocp(base);
|
event_base_start_iocp(base, 0);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -170,7 +170,7 @@ test_iocp_port(void *ptr)
|
|||||||
event_overlapped_init(&o1.eo, dummy_cb);
|
event_overlapped_init(&o1.eo, dummy_cb);
|
||||||
event_overlapped_init(&o2.eo, dummy_cb);
|
event_overlapped_init(&o2.eo, dummy_cb);
|
||||||
|
|
||||||
port = event_iocp_port_launch();
|
port = event_iocp_port_launch(0);
|
||||||
tt_assert(port);
|
tt_assert(port);
|
||||||
|
|
||||||
tt_assert(!event_iocp_activate_overlapped(port, &o1.eo, 10, 100));
|
tt_assert(!event_iocp_activate_overlapped(port, &o1.eo, 10, 100));
|
||||||
@ -255,7 +255,7 @@ test_iocp_evbuffer(void *ptr)
|
|||||||
evbuffer_enable_locking(rbuf, NULL);
|
evbuffer_enable_locking(rbuf, NULL);
|
||||||
evbuffer_enable_locking(wbuf, NULL);
|
evbuffer_enable_locking(wbuf, NULL);
|
||||||
|
|
||||||
port = event_iocp_port_launch();
|
port = event_iocp_port_launch(0);
|
||||||
tt_assert(port);
|
tt_assert(port);
|
||||||
tt_assert(rbuf);
|
tt_assert(rbuf);
|
||||||
tt_assert(wbuf);
|
tt_assert(wbuf);
|
||||||
@ -310,7 +310,7 @@ test_iocp_bufferevent_async(void *ptr)
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
event_base_start_iocp(data->base);
|
event_base_start_iocp(data->base, 0);
|
||||||
port = event_base_get_iocp(data->base);
|
port = event_base_get_iocp(data->base);
|
||||||
tt_assert(port);
|
tt_assert(port);
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ basic_test_setup(const struct testcase_t *testcase)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (testcase->flags & TT_ENABLE_IOCP_FLAG) {
|
if (testcase->flags & TT_ENABLE_IOCP_FLAG) {
|
||||||
if (event_base_start_iocp(base)<0) {
|
if (event_base_start_iocp(base, 0)<0) {
|
||||||
event_base_free(base);
|
event_base_free(base);
|
||||||
return (void*)TT_SKIP;
|
return (void*)TT_SKIP;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user