Move /trace and /mem to C.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4724 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		| @@ -5,6 +5,7 @@ | ||||
| #include "mem.h" | ||||
| #include "task.h" | ||||
| #include "tlscontext.js.h" | ||||
| #include "trace.h" | ||||
| #include "util.js.h" | ||||
|  | ||||
| #include "picohttpparser.h" | ||||
| @@ -18,6 +19,8 @@ | ||||
| #include <alloca.h> | ||||
| #endif | ||||
|  | ||||
| #define tf_countof(a) ((int)(sizeof((a)) / sizeof(*(a)))) | ||||
|  | ||||
| static JSClassID _httpd_class_id; | ||||
| static JSClassID _httpd_request_class_id; | ||||
|  | ||||
| @@ -365,6 +368,65 @@ void _httpd_request_finalizer(JSRuntime* runtime, JSValue value) | ||||
| 	tf_http_request_release(request); | ||||
| } | ||||
|  | ||||
| static void _httpd_endpoint_trace(tf_http_request_t* request) | ||||
| { | ||||
| 	if (_httpd_redirect(request)) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	tf_task_t* task = request->user_data; | ||||
| 	tf_trace_t* trace = tf_task_get_trace(task); | ||||
| 	tf_trace_begin(trace, __func__); | ||||
| 	char* json = tf_trace_export(trace); | ||||
| 	const char* headers[] = | ||||
| 	{ | ||||
| 		"Content-Type", "application/json; charset=utf-8", | ||||
| 		"Access-Control-Allow-Origin", "*", | ||||
| 	}; | ||||
| 	tf_http_respond(request, 200, headers, tf_countof(headers) / 2, json, json ? strlen(json) : 0); | ||||
| 	tf_free(json); | ||||
| 	tf_trace_end(trace); | ||||
| } | ||||
|  | ||||
| static void _httpd_endpoint_mem(tf_http_request_t* request) | ||||
| { | ||||
| 	if (_httpd_redirect(request)) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	tf_task_t* task = request->user_data; | ||||
| 	tf_trace_t* trace = tf_task_get_trace(task); | ||||
| 	tf_trace_begin(trace, __func__); | ||||
|  | ||||
| 	char* response = NULL; | ||||
| 	size_t length = 0; | ||||
|  | ||||
| 	int count = 0; | ||||
| 	tf_mem_allocation_t* alloc = tf_mem_summarize_allocations(&count); | ||||
| 	for (int i = 0; i < count; i++) | ||||
| 	{ | ||||
| 		const char* stack = tf_util_backtrace_to_string(alloc[i].frames, alloc[i].frames_count); | ||||
| 		int line = snprintf(NULL, 0, "%zd bytes in %d allocations\n%s\n\n", alloc[i].size, alloc[i].count, stack); | ||||
| 		response = tf_realloc(response, length + line); | ||||
| 		snprintf(response + length, line, "%zd bytes in %d allocations\n%s\n\n", alloc[i].size, alloc[i].count, stack); | ||||
| 		length += line - 1; | ||||
| 		tf_free((void*)stack); | ||||
| 	} | ||||
| 	tf_free(alloc); | ||||
|  | ||||
| 	const char* headers[] = | ||||
| 	{ | ||||
| 		"Content-Type", "text/plain; charset=utf-8", | ||||
| 		"Access-Control-Allow-Origin", "*", | ||||
| 	}; | ||||
| 	tf_http_respond(request, 200, headers, tf_countof(headers) / 2, response, length); | ||||
| 	tf_free(response); | ||||
|  | ||||
| 	tf_trace_end(trace); | ||||
| } | ||||
|  | ||||
| void tf_httpd_register(JSContext* context) | ||||
| { | ||||
| 	JS_NewClassID(&_httpd_class_id); | ||||
| @@ -395,6 +457,9 @@ void tf_httpd_register(JSContext* context) | ||||
| 	tf_http_t* http = tf_http_create(loop); | ||||
| 	JS_SetOpaque(httpd, http); | ||||
|  | ||||
| 	tf_http_add_handler(http, "/trace", _httpd_endpoint_trace, task); | ||||
| 	tf_http_add_handler(http, "/mem", _httpd_endpoint_mem, task); | ||||
|  | ||||
| 	JS_SetPropertyStr(context, httpd, "handlers", JS_NewObject(context)); | ||||
| 	JS_SetPropertyStr(context, httpd, "all", JS_NewCFunction(context, _httpd_all, "all", 2)); | ||||
| 	JS_SetPropertyStr(context, httpd, "registerSocketHandler", JS_NewCFunction(context, _httpd_register_socket_handler, "register_socket_handler", 2)); | ||||
|   | ||||
| @@ -199,7 +199,10 @@ tf_mem_allocation_t* tf_mem_summarize_allocations(int* out_count) | ||||
| { | ||||
| 	summary_t summary = { 0 }; | ||||
| 	tf_mem_walk_allocations(_tf_mem_summarize, &summary); | ||||
| 	qsort(summary.allocations, summary.count, sizeof(tf_mem_allocation_t), _tf_mem_size_compare); | ||||
| 	if (summary.count) | ||||
| 	{ | ||||
| 		qsort(summary.allocations, summary.count, sizeof(tf_mem_allocation_t), _tf_mem_size_compare); | ||||
| 	} | ||||
| 	*out_count = summary.count; | ||||
| 	tf_mem_allocation_t* result = tf_malloc(sizeof(tf_mem_allocation_t) * summary.count); | ||||
| 	if (result) | ||||
|   | ||||
							
								
								
									
										46
									
								
								src/task.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/task.c
									
									
									
									
									
								
							| @@ -181,7 +181,6 @@ static JSValue _tf_task_version(JSContext* context, JSValueConst this_val, int a | ||||
| static JSValue _tf_task_platform(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); | ||||
| static JSValue _tf_task_get_parent(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); | ||||
| static JSValue _tf_task_exit(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); | ||||
| static JSValue _tf_task_trace(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); | ||||
| static JSValue _tf_task_getStats(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); | ||||
| static JSValue _tf_task_getFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); | ||||
|  | ||||
| @@ -781,22 +780,6 @@ static void _tf_task_release_export(tf_taskstub_t* stub, exportid_t exportId) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static JSValue _tf_task_trace(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||
| { | ||||
| 	tf_task_t* task = JS_GetContextOpaque(context); | ||||
| 	if (!task->_trace) | ||||
| 	{ | ||||
| 		return JS_UNDEFINED; | ||||
| 	} | ||||
|  | ||||
| 	tf_trace_begin(task->_trace, __func__); | ||||
| 	char* trace = tf_trace_export(task->_trace); | ||||
| 	JSValue result = JS_NewString(context, trace); | ||||
| 	tf_free(trace); | ||||
| 	tf_trace_end(task->_trace); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| static JSValue _tf_task_getStats(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||
| { | ||||
| 	tf_task_t* task = JS_GetContextOpaque(context); | ||||
| @@ -938,32 +921,6 @@ static JSValue _tf_task_getHitches(JSContext* context, JSValueConst this_val, in | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| static JSValue _tf_task_getAllocations(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||
| { | ||||
| 	tf_task_t* task = JS_GetContextOpaque(context); | ||||
| 	tf_trace_begin(task->_trace, __func__); | ||||
| 	JSValue result = JS_NewObject(context); | ||||
|  | ||||
| 	int count = 0; | ||||
| 	tf_mem_allocation_t* allocation_info = tf_mem_summarize_allocations(&count); | ||||
|  | ||||
| 	JSValue allocations = JS_NewArray(context); | ||||
| 	JS_SetPropertyStr(context, result, "allocations", allocations); | ||||
| 	for (int i = 0; i < count; i++) | ||||
| 	{ | ||||
| 		JSValue allocation = JS_NewObject(context); | ||||
| 		JS_SetPropertyStr(context, allocation, "size", JS_NewInt64(context, allocation_info[i].size)); | ||||
| 		JS_SetPropertyStr(context, allocation, "count", JS_NewInt32(context, allocation_info[i].count)); | ||||
| 		const char* stack = tf_util_backtrace_to_string(allocation_info[i].frames, allocation_info[i].frames_count); | ||||
| 		JS_SetPropertyStr(context, allocation, "stack", JS_NewString(context, stack ? stack : "")); | ||||
| 		tf_free((void*)stack); | ||||
| 		JS_SetPropertyUint32(context, allocations, i, allocation); | ||||
| 	} | ||||
| 	tf_free(allocation_info); | ||||
| 	tf_trace_end(task->_trace); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| static JSValue _tf_task_disconnectionsDebug(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||
| { | ||||
| 	tf_task_t* task = JS_GetContextOpaque(context); | ||||
| @@ -1746,11 +1703,10 @@ void tf_task_activate(tf_task_t* task) | ||||
| 			tf_ssb_server_open(task->_ssb, task->_ssb_port); | ||||
| 		} | ||||
|  | ||||
| 		JS_SetPropertyStr(context, global, "trace", JS_NewCFunction(context, _tf_task_trace, "trace", 1)); | ||||
| 		JS_SetPropertyStr(context, global, "getStats", JS_NewCFunction(context, _tf_task_getStats, "getStats", 0)); | ||||
|  | ||||
| 		JS_SetPropertyStr(context, global, "getDebug", JS_NewCFunction(context, _tf_task_getDebug, "getDebug", 0)); | ||||
| 		JS_SetPropertyStr(context, global, "getHitches", JS_NewCFunction(context, _tf_task_getHitches, "getHitches", 0)); | ||||
| 		JS_SetPropertyStr(context, global, "getAllocations", JS_NewCFunction(context, _tf_task_getAllocations, "getAllocations", 0)); | ||||
| 		JS_SetPropertyStr(context, global, "disconnectionsDebug", JS_NewCFunction(context, _tf_task_disconnectionsDebug, "disconnectionsDebug", 0)); | ||||
| 	} | ||||
| 	else | ||||
|   | ||||
		Reference in New Issue
	
	Block a user