[PATCH 09/13] mghttpd: Add stack size and scheduling options.

Christian Mauderer christian.mauderer at embedded-brains.de
Thu Apr 21 08:49:49 UTC 2016


From: Christian Mauderer <Christian.Mauderer at embedded-brains.de>

This applies the changes from 54da7c3e55056efd93adece52076b720490258d6.
---
 cpukit/mghttpd/civetweb.c | 117 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 96 insertions(+), 21 deletions(-)

diff --git a/cpukit/mghttpd/civetweb.c b/cpukit/mghttpd/civetweb.c
index 47e1dfe..0c907f0 100644
--- a/cpukit/mghttpd/civetweb.c
+++ b/cpukit/mghttpd/civetweb.c
@@ -1117,10 +1117,18 @@ enum {
 	CONFIG_TCP_NODELAY, /* Prepended CONFIG_ to avoid conflict with the
                          * socket option typedef TCP_NODELAY. */
 	STATIC_FILE_MAX_AGE,
+	THREAD_STACK_SIZE,
+#if !defined(_WIN32)
+	THREAD_PRIORITY,
+	THREAD_POLICY,
+#endif
 
 	NUM_OPTIONS
 };
 
+/* Macros for stringification */
+#define TO_STRING(s) X_TO_STRING(s)
+#define X_TO_STRING(s) #s
 
 /* Config option name, config types, default value */
 static struct mg_option config_options[] = {
@@ -1191,7 +1199,15 @@ static struct mg_option config_options[] = {
     {"_experimental_static_file_max_age",
      CONFIG_TYPE_NUMBER,
      "3600"}, /* TODO: redefine parameter */
-
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+    {"thread_stack_size", CONFIG_TYPE_NUMBER, TO_STRING(USE_STACK_SIZE)},
+#else
+    {"thread_stack_size", CONFIG_TYPE_NUMBER, "0"},
+#endif
+#if !defined(_WIN32)
+    {"thread_priority", CONFIG_TYPE_NUMBER, NULL},
+    {"thread_policy", CONFIG_TYPE_STRING, NULL},
+#endif
     {NULL, CONFIG_TYPE_UNKNOWN, NULL}};
 
 /* Check if the config_options and the corresponding enum have compatible
@@ -3121,19 +3137,22 @@ set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */)
 int
 mg_start_thread(mg_thread_func_t f, void *p)
 {
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
-	/* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384
-	 */
-	return ((_beginthread((void(__cdecl *)(void *))f, USE_STACK_SIZE, p)
+	struct mg_context* ctx = p;
+	char* stacksize = ctx->config[THREAD_STACK_SIZE];
+	unsigned size = 0;
+
+	if (stacksize != NULL) {
+		int size = atoi(stacksize);
+		if (size <= 0) {
+			mg_cry(fc(ctx),
+			    "Stack size has to be a positive number. Is: %d",
+			    size);
+		}
+	}
+	return ((_beginthread((void(__cdecl *)(void *))f, size, p)
 	         == ((uintptr_t)(-1L)))
 	            ? -1
 	            : 0);
-#else
-	return (
-	    (_beginthread((void(__cdecl *)(void *))f, 0, p) == ((uintptr_t)(-1L)))
-	        ? -1
-	        : 0);
-#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
 }
 
 
@@ -3440,6 +3459,68 @@ set_close_on_exec(SOCKET fd, struct mg_connection *conn /* may be null */)
 	}
 }
 
+static void
+set_pthread_attributes(struct mg_context *ctx, pthread_attr_t *attr)
+{
+	char* stacksize = ctx->config[THREAD_STACK_SIZE];
+	char* priority = ctx->config[THREAD_PRIORITY];
+	char* policy = ctx->config[THREAD_POLICY];
+	int noinheritsched = 0;
+
+	if (stacksize != NULL) {
+		int size = atoi(stacksize);
+		if (size <= 0) {
+			mg_cry(fc(ctx),
+			    "Stack size has to be a positive number. Is: %d",
+			    size);
+		}
+		(void) pthread_attr_setstacksize(attr, (size_t) size);
+	}
+
+	if (priority != NULL) {
+		struct sched_param sched_param;
+		memset(&sched_param, 0, sizeof(sched_param));
+		sched_param.sched_priority = atoi(priority);
+		(void) pthread_attr_setschedparam(attr, &sched_param);
+		noinheritsched = 1;
+	}
+
+	if (policy != NULL) {
+		int p_policy;
+		(void) pthread_attr_getschedpolicy(attr, &p_policy);
+
+		switch (policy[0]) {
+		case 'o':
+			p_policy = SCHED_OTHER;
+			break;
+		case 'f':
+			p_policy = SCHED_FIFO;
+			break;
+		case 'r':
+			p_policy = SCHED_RR;
+			break;
+#if (defined(_POSIX_SPORADIC_SERVER) && (_POSIX_SPORADIC_SERVER > 0)) || \
+    (defined(_POSIX_THREAD_SPORADIC_SERVER) && \
+    (_POSIX_THREAD_SPORADIC_SERVER > 0))
+		case 's':
+			p_policy = SCHED_SPORADIC;
+			break;
+#endif
+		default:
+			mg_cry(fc(ctx), "Unknown scheduler: %s", policy);
+			break;
+		}
+
+		(void) pthread_attr_setschedpolicy(attr, p_policy);
+
+		noinheritsched = 1;
+	}
+
+	if (noinheritsched != 0) {
+		(void) pthread_attr_setinheritsched(attr,
+		    PTHREAD_EXPLICIT_SCHED);
+	}
+}
 
 int
 mg_start_thread(mg_thread_func_t func, void *param)
@@ -3447,15 +3528,12 @@ mg_start_thread(mg_thread_func_t func, void *param)
 	pthread_t thread_id;
 	pthread_attr_t attr;
 	int result;
+	struct mg_context* ctx = param;
 
 	(void)pthread_attr_init(&attr);
 	(void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
-	/* Compile-time option to control stack size,
-	 * e.g. -DUSE_STACK_SIZE=16384 */
-	(void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
-#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
+	set_pthread_attributes(ctx, &attr);
 
 	result = pthread_create(&thread_id, &attr, func, param);
 	pthread_attr_destroy(&attr);
@@ -3473,14 +3551,11 @@ mg_start_thread_with_id(mg_thread_func_t func,
 	pthread_t thread_id;
 	pthread_attr_t attr;
 	int result;
+	struct mg_context* ctx = param;
 
 	(void)pthread_attr_init(&attr);
 
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
-	/* Compile-time option to control stack size,
-	 * e.g. -DUSE_STACK_SIZE=16384 */
-	(void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
-#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */
+	set_pthread_attributes(ctx, &attr);
 
 	result = pthread_create(&thread_id, &attr, func, param);
 	pthread_attr_destroy(&attr);
-- 
1.8.4.5



More information about the devel mailing list