summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--event-internal.h1
-rw-r--r--event.c15
-rw-r--r--event_iocp.c12
-rw-r--r--include/event2/event.h10
-rw-r--r--iocp-internal.h4
-rw-r--r--test/bench_http.c2
-rw-r--r--test/regress_iocp.c6
-rw-r--r--test/regress_main.c2
8 files changed, 39 insertions, 13 deletions
diff --git a/event-internal.h b/event-internal.h
index 7d97d98e..256f3086 100644
--- a/event-internal.h
+++ b/event-internal.h
@@ -285,6 +285,7 @@ struct event_config_entry {
struct event_config {
TAILQ_HEAD(event_configq, event_config_entry) entries;
+ int n_cpus_hint;
enum event_method_feature require_features;
enum event_base_config_flag flags;
};
diff --git a/event.c b/event.c
index aaf8f28b..8e8c324b 100644
--- a/event.c
+++ b/event.c
@@ -615,19 +615,19 @@ event_base_new_with_config(const struct event_config *cfg)
#ifdef WIN32
if (cfg && (cfg->flags & EVENT_BASE_FLAG_STARTUP_IOCP))
- event_base_start_iocp(base);
+ event_base_start_iocp(base, cfg->n_cpus_hint);
#endif
return (base);
}
int
-event_base_start_iocp(struct event_base *base)
+event_base_start_iocp(struct event_base *base, int n_cpus)
{
#ifdef WIN32
if (base->iocp)
return 0;
- base->iocp = event_iocp_port_launch();
+ base->iocp = event_iocp_port_launch(n_cpus);
if (!base->iocp) {
event_warnx("%s: Couldn't launch IOCP", __func__);
return -1;
@@ -919,6 +919,15 @@ event_config_require_features(struct event_config *cfg,
}
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
event_priority_init(int npriorities)
{
return event_base_priority_init(current_base, npriorities);
diff --git a/event_iocp.c b/event_iocp.c
index 19c7bffc..254ed90d 100644
--- a/event_iocp.c
+++ b/event_iocp.c
@@ -162,8 +162,10 @@ event_get_win32_extension_fns(void)
return &the_extension_fns;
}
+#define N_CPUS_DEFAULT 2
+
struct event_iocp_port *
-event_iocp_port_launch(void)
+event_iocp_port_launch(int n_cpus)
{
struct event_iocp_port *port;
int i;
@@ -173,12 +175,16 @@ event_iocp_port_launch(void)
if (!(port = mm_calloc(1, sizeof(struct event_iocp_port))))
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));
if (!port->threads)
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;
if (!port->port)
goto err;
diff --git a/include/event2/event.h b/include/event2/event.h
index e9d0048f..fa0f625d 100644
--- a/include/event2/event.h
+++ b/include/event2/event.h
@@ -227,6 +227,16 @@ int event_config_require_features(struct event_config *cfg, int feature);
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.
Use event_base_new_with_config() to initialize a new event base, taking
diff --git a/iocp-internal.h b/iocp-internal.h
index 2b740bcc..eb2eae49 100644
--- a/iocp-internal.h
+++ b/iocp-internal.h
@@ -155,7 +155,7 @@ void evbuffer_commit_write(struct evbuffer *, ev_ssize_t);
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
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);
/* 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);
/* FIXME document. */
diff --git a/test/bench_http.c b/test/bench_http.c
index fdcf49dd..4b2eb3cd 100644
--- a/test/bench_http.c
+++ b/test/bench_http.c
@@ -133,7 +133,7 @@ main(int argc, char **argv)
case 'i':
use_iocp = 1;
evthread_use_windows_threads();
- event_base_start_iocp(base);
+ event_base_start_iocp(base, 0);
break;
#endif
default:
diff --git a/test/regress_iocp.c b/test/regress_iocp.c
index 96d8eb3e..920da2a7 100644
--- a/test/regress_iocp.c
+++ b/test/regress_iocp.c
@@ -170,7 +170,7 @@ test_iocp_port(void *ptr)
event_overlapped_init(&o1.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(!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(wbuf, NULL);
- port = event_iocp_port_launch();
+ port = event_iocp_port_launch(0);
tt_assert(port);
tt_assert(rbuf);
tt_assert(wbuf);
@@ -310,7 +310,7 @@ test_iocp_bufferevent_async(void *ptr)
char buf[128];
size_t n;
- event_base_start_iocp(data->base);
+ event_base_start_iocp(data->base, 0);
port = event_base_get_iocp(data->base);
tt_assert(port);
diff --git a/test/regress_main.c b/test/regress_main.c
index 7d18938b..3732f098 100644
--- a/test/regress_main.c
+++ b/test/regress_main.c
@@ -209,7 +209,7 @@ basic_test_setup(const struct testcase_t *testcase)
exit(1);
}
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);
return (void*)TT_SKIP;
}