rev 316 - in trunk: include/prothon src

SVN User <[email protected]>
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-04-10 03:59:39 -0400 (Sat, 10 Apr 2004)
New Revision: 316

Modified:
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/src/builtins-core.c
   trunk/src/builtins-thread.c
   trunk/src/interp.c
   trunk/src/interp.h
   trunk/src/main.c
   trunk/src/object.c
   trunk/src/thread.h
Log:
Prothon level threads are now implemented and working

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/include/prothon/prothon.h	2004-04-10 07:59:39 UTC (rev 316)
@@ -199,13 +199,21 @@
 typedef pr_str_t* pr_str_p;
 
 typedef struct frame_t* frame_p;
-
 typedef struct interp_state_s* isp;
 
+typedef struct user_thread_s {
+	obj_p func;
+	obj_p params;
+	int   access;
+} user_thread_t;
+
+typedef user_thread_t* user_thread_p;
+
 typedef struct {
 	apr_os_thread_t		apr_os_thread;
 	apr_thread_t*		apr_thread;
 	int					main_id;
+	user_thread_t		user_thread_data;
 	int					running;
 	isp					ist;
 	frame_p				frame;
@@ -564,12 +572,15 @@
 
 // LISTn: Convenience list create functions
 // list1, list2, ... are convenience functions that allow you to create
-// new list objects that contain 1 to 6 item objects.
+// new list objects that contain 1 to 8 item objects.
 obj_p list1(isp ist, obj_p p1);
 obj_p list2(isp ist, obj_p p1, obj_p p2);
 obj_p list3(isp ist, obj_p p1, obj_p p2, obj_p p3);
 obj_p list4(isp ist, obj_p p1, obj_p p2, obj_p p3, obj_p p4);
-obj_p list6(isp ist, obj_p item1, obj_p item2, obj_p item3, obj_p item4, obj_p item5, obj_p item6 );
+obj_p list6(isp ist, obj_p item1, obj_p item2, obj_p item3, obj_p item4, 
+			         obj_p item5, obj_p item6 );
+obj_p list8(isp ist, obj_p item1, obj_p item2, obj_p item3, obj_p item4, 
+			         obj_p item5, obj_p item6, obj_p item7, obj_p item8 );
 
 // NEW_TUPLE_OBJ: Create a new immutable tuple object
 // A tuple is identical to a list except that at the Prothon level it is
@@ -652,7 +663,8 @@
 // arugments for the thread_func function.
 // Note: thread_func must call register_thread() (see below) immediately after
 // starting.
-obj_p new_thread_obj(isp ist, apr_thread_start_t thread_func, void *thread_data);
+// You may provide a blank thread_obj as an input parameter if you wish.
+obj_p new_thread_obj(isp ist, apr_thread_start_t thread_func, void *thread_data, obj_p thread_obj);
 
 // REGISTER_THREAD: Register a newly started thread
 // This tells Prothon that a thread has actually started, releasees the

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/include/prothon/prothon_dll.h	2004-04-10 07:59:39 UTC (rev 316)
@@ -79,7 +79,10 @@
 	obj_p		(*list2)(isp ist, obj_p p1, obj_p p2);
 	obj_p		(*list3)(isp ist, obj_p p1, obj_p p2, obj_p p3);
 	obj_p		(*list4)(isp ist, obj_p p1, obj_p p2, obj_p p3, obj_p p4);
-	obj_p		(*list6)(isp ist, obj_p p1, obj_p p2, obj_p p3, obj_p p4, obj_p p5, obj_p p6);
+	obj_p		(*list6)(isp ist, obj_p p1, obj_p p2, obj_p p3, obj_p p4, 
+		                          obj_p p5, obj_p p6);
+	obj_p		(*list8)(isp ist, obj_p p1, obj_p p2, obj_p p3, obj_p p4, 
+		                          obj_p p5, obj_p p6, obj_p p7, obj_p p8);
 	obj_p		(*new_hash_obj)(isp ist, i32_t num);
 	obj_p		(*new_int_obj)(isp ist, i64_t num);
 	obj_p		(*new_float_obj)(isp ist, double num);
@@ -213,6 +216,7 @@
 #define list3				(*services->list3)
 #define list4				(*services->list4)
 #define list6				(*services->list6)
+#define list8				(*services->list8)
 #define raise_exception		(*services->raise_exception)
 #define new_object			(*services->new_object)
 #define add_doc_to_obj		(*services->add_doc_to_obj)

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/src/builtins-core.c	2004-04-10 07:59:39 UTC (rev 316)
@@ -152,10 +152,20 @@
 	return parms[1];
 }
 
-DEF(Object, get_read_access, NULL) {
+DEF(Object, read_access, NULL) {
 	return new_int_obj(ist, get_obj_rdacc(self));
 }
 
+DEF(Object, read_access_str, NULL) {
+	switch (get_obj_rdacc(self)) {
+		case 0:	return new_string_obj(ist, "guest");
+		case 1: return new_string_obj(ist, "user1");
+		case 2: return new_string_obj(ist, "user2");
+		case 3: return new_string_obj(ist, "system");
+		default:return new_string_obj(ist, "<invalid access value>");
+	}
+}
+
 DEF(Object, set_write_access, FORM_RPARAM)  {
 	CHECK_TYPE_EXC(parms[1], OBJ(INT_PROTO), "integer");
 	if (ist->access < get_obj_wracc(self)) {
@@ -166,10 +176,20 @@
 	return parms[1];
 }
 
-DEF(Object, get_write_access, NULL) {
+DEF(Object, write_access, NULL) {
 	return new_int_obj(ist, get_obj_wracc(self));
 }
 
+DEF(Object, write_access_str, NULL) {
+	switch (get_obj_wracc(self)) {
+		case 0:	return new_string_obj(ist, "guest");
+		case 1: return new_string_obj(ist, "user1");
+		case 2: return new_string_obj(ist, "user2");
+		case 3: return new_string_obj(ist, "system");
+		default:return new_string_obj(ist, "<invalid access value>");
+	}
+}
+
 DEF(Object, __getitem__, FORM_RPARAM) {
 	raise_exception(ist, OBJ(TYPE_EXC), "indexing not supported on this object");
 	return NULL;
@@ -599,9 +619,11 @@
 	MODULE_ADD_SYM(Object, __init__);
 	MODULE_ADD_SYM(Object, clone);
 	MODULE_ADD_SYM(Object, set_read_access);
-	MODULE_ADD_SYM(Object, get_read_access);
+	MODULE_ADD_SYM(Object, read_access);
+	MODULE_ADD_SYM(Object, read_access_str);
 	MODULE_ADD_SYM(Object, set_write_access);
-	MODULE_ADD_SYM(Object, get_write_access);
+	MODULE_ADD_SYM(Object, write_access);
+	MODULE_ADD_SYM(Object, write_access_str);
 	MODULE_ADD_SYM(Object, has_proto_QUES);
 	MODULE_ADD_SYM(Object, set_proto);
 	MODULE_ADD_SYM(Object, add_proto);

Modified: trunk/src/builtins-thread.c
===================================================================
--- trunk/src/builtins-thread.c	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/src/builtins-thread.c	2004-04-10 07:59:39 UTC (rev 316)
@@ -90,8 +90,8 @@
 static apr_pool_t *thread_pool = NULL;
 
 //********************************* new_thread_obj ****************************
-obj_p new_thread_obj(isp ist, apr_thread_start_t thread_func, void *thread_data)
-{
+obj_p new_thread_obj( isp ist, apr_thread_start_t thread_func, 
+					  void *thread_data, obj_p thread_obj ) {
 	apr_status_t aprerr;
 	apr_thread_t *new_thread = NULL;
 	char buf[1024];
@@ -117,10 +117,12 @@
 	 * calls register_thread(). */
 	pr_lock(&thread_registry_lock);
 
-	new_thread_object = new_object(ist, OBJ(THREAD_PROTO));
-	new_thread_object->data_type = OBJ_TYPE_DATAPTR;
-	new_thread_object->data.ptr  = pr_malloc(sizeof(pr_thread_t));
-	memset(new_thread_object->data.ptr, 0, sizeof(pr_thread_t));
+	if (!thread_obj) {
+		thread_obj = new_object(ist, OBJ(THREAD_PROTO));
+		thread_obj->data_type = OBJ_TYPE_DATAPTR;
+		thread_obj->data.ptr  = pr_malloc(sizeof(pr_thread_t));
+		memset(thread_obj->data.ptr, 0, sizeof(pr_thread_t));
+	}
 
 	if ( ( aprerr = apr_thread_create( &new_thread, thread_attr, thread_func,
 					            thread_data, thread_pool ) ) != APR_SUCCESS ) {
@@ -128,7 +130,8 @@
 			apr_strerror(aprerr, buf, sizeof(buf)));
 		pr_exit(1);
 	}
-	return new_thread_object;
+	new_thread_object = thread_obj;
+	return thread_obj;
 }
 
 //********************************* os_thread_2_apr ***************************
@@ -150,7 +153,7 @@
 	return res;
 }
 
-// ***************************** Thread ******************************************
+// ***************************** Thread ***************************************
 
 MODULE_START(Thread)
 {
@@ -166,17 +169,42 @@
 }
 
 
-DEF(Thread, __init__, list2(ist, sym(ist, "access"), new_int_obj(ist, -1))) {
-	int rqacclevel;
-	CHECK_TYPE_EXC(parms[1], OBJ(INT_PROTO), "integer");
-	rqacclevel = (int) parms[1]->data.i64;
-	if (rqacclevel == -1) rqacclevel = ist->access;
-	if (ist->access < rqacclevel) {
+DEF(Thread, __init__, list8(ist, sym(ist, "func"),   NULL,
+								 sym(ist, "params"), OBJ(NONE),
+								 sym(ist, "name"),   OBJ(NONE),
+								 sym(ist, "access"), new_int_obj(ist, -1) ) ) {
+	char buf[30];
+	obj_p name_obj;
+	user_thread_p uthread;
+
+	CHECK_TYPE_EXC(parms[1], OBJ(FUNC_PROTO),   "function");
+	if (parms[3] != OBJ(NONE))
+		CHECK_TYPE_EXC(parms[3], OBJ(SEQ_PROTO), "sequence");
+	if (parms[5] != OBJ(NONE))
+		CHECK_TYPE_EXC(parms[5], OBJ(STRING_PROTO), "string");
+	CHECK_TYPE_EXC(parms[7], OBJ(INT_PROTO),    "integer");
+	self->data_type = OBJ_TYPE_DATAPTR;
+	self->data.ptr  = pr_malloc(sizeof(pr_thread_t));
+	memset(self->data.ptr, 0, sizeof(pr_thread_t));
+	uthread = &(((pr_thread_p)self->data.ptr)->user_thread_data);
+	uthread->func   = parms[1]; 
+	uthread->params = parms[3]; 
+	uthread->access = (int) parms[7]->data.i64;
+	if (uthread->access == -1) uthread->access = ist->access;
+	if (ist->access < uthread->access) {
 		raise_exception(ist, OBJ(PERMISSION_EXC), 
 			"attempt to start thread with higher access level than own");	
 		return NULL;
 	}
-	// ist->access = rqacclevel;  XXX
+	if (parms[5] == OBJ(NONE)) {
+		apr_snprintf(buf, sizeof(buf), "uThread%lx", (unsigned long)(intptr_t) self);
+		name_obj = new_string_obj(ist, buf);
+	} else
+		name_obj = parms[5];
+	read_unlock(ist, self);
+	set_attr(ist, self, sym(ist, "name"), name_obj);
+	new_thread_obj(ist, (apr_thread_start_t) user_thread, uthread, self);
+	read_lock(ist, self);
 	return OBJ(NONE);
 }
 
@@ -190,6 +218,25 @@
 	return new_string_obj(ist, name);
 }
 
+DEF(Thread, access, NULL) {
+	return new_int_obj(ist, ist->access);
+}
+
+DEF(Thread, access_str, NULL) {
+	switch (ist->access) {
+		case 0:	return new_string_obj(ist, "guest");
+		case 1: return new_string_obj(ist, "user1");
+		case 2: return new_string_obj(ist, "user2");
+		case 3: return new_string_obj(ist, "system");
+		default:return new_string_obj(ist, "<invalid access value>");
+	}
+}
+
+DEF(Thread, running, NULL) {
+	if (thread_running(self)) return OBJ(PR_TRUE);
+	else                      return OBJ(PR_FALSE);
+}
+
 DEF(Thread, __objlist__, FORM_RPARAM) {
 	return parms[1];
 }
@@ -198,5 +245,8 @@
 	MODULE_SUB_INIT(Thread);
 	MODULE_ADD_SYM(Thread, __init__);
 	MODULE_ADD_SYM(Thread, __str__);
+	MODULE_ADD_SYM(Thread, access);
+	MODULE_ADD_SYM(Thread, access_str);
+	MODULE_ADD_SYM(Thread, running);
 	MODULE_ADD_SYM(Thread, __objlist__);
 }

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/src/interp.c	2004-04-10 07:59:39 UTC (rev 316)
@@ -248,11 +248,10 @@
 
 //******************************** load_frame_params **************************
 void load_frame_params( isp ist,
-						frame_p old_frame, 
+						obj_p locals, 
 					    obj_p func_obj, 
 					    int parm_cnt, obj_p *actparams) {
 	int i, llen;
-	obj_p locals = old_frame->next_frame->locals;
 	fparam_proc_state_t fparam_proc_state;
 	switch (map_params(ist, &fparam_proc_state, func_obj, parm_cnt, actparams))
 		   {case 1: goto fparmerr; case 2: goto paramerr;}
@@ -889,7 +888,7 @@
 												frame->locals, new_locals, func_obj, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
-					load_frame_params(ist, frame, func_obj, param*2, fr_stack+fr_sp+1);
+					load_frame_params(ist, new_locals, func_obj, param*2, fr_stack+fr_sp+1);
 					if (intrp_exobj) break;
 					switch_frame = new_frame;
 				} else if (has_proto_QUES(ist, func_obj, OBJ(GEN_PROTO))) {
@@ -897,7 +896,7 @@
 					if (intrp_exobj) break;
 					tmp_frame = func_obj->data.ptr;
 					frame->next_frame = tmp_frame;
-					load_frame_params(ist, frame, func_obj, param*2, fr_stack+fr_sp+1);
+					load_frame_params(ist, tmp_frame->locals, func_obj, param*2, fr_stack+fr_sp+1);
 					if (intrp_exobj) break;
 					fr_push(func_obj);
 				} else {
@@ -986,7 +985,7 @@
 												frame->locals, new_locals, func_obj, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
-					load_frame_params(ist, frame, func_obj, param*2, fr_stack+fr_sp+2);
+					load_frame_params(ist, new_locals, func_obj, param*2, fr_stack+fr_sp+2);
 					if (intrp_exobj) break;
 					switch_frame = new_frame;
 				} else if (has_proto_QUES(ist, func_obj, OBJ(GEN_PROTO))) {
@@ -994,7 +993,7 @@
 					if (intrp_exobj) break;
 					tmp_frame = func_obj->data.ptr;
 					frame->next_frame = tmp_frame;
-					load_frame_params(ist, frame, func_obj, param*2, fr_stack+fr_sp+2);
+					load_frame_params(ist, tmp_frame->locals, func_obj, param*2, fr_stack+fr_sp+2);
 					if (intrp_exobj) break;
 					fr_push(func_obj);
 				} else {
@@ -1247,7 +1246,7 @@
 		new_frame->called_from_c = TRUE;
 		ist->frame->next_frame = new_frame;
 		new_frame->prev_frame = ist->frame;
-		load_frame_params( ist, frame, func_obj, parm_cnt, lbl_val_arr);
+		load_frame_params( ist, new_locals, func_obj, parm_cnt, lbl_val_arr);
 		ist->frame = new_frame;
 		if (intrp_exobj) {
 			if (!func_sym) del_unlock(self);
@@ -1480,6 +1479,46 @@
 	return NULL;
 }
 
+// ***************************** User Thread **********************************
+#define MAX_NUM_PARAMS	64
+void* user_thread(apr_thread_t *handle, void *argv) {
+	user_thread_p uthread = (user_thread_p) argv;
+	isp ist = get_ist(uthread->access);
+	obj_p func_obj = uthread->func;
+	frame_p new_frame;
+	obj_p new_locals, syn_self, lbl_val_arr[MAX_NUM_PARAMS]; 
+	int i, parm_cnt = (int) list_len(ist, uthread->params) * 2;
+	obj_p thread_obj = register_thread(ist, handle);
+	pr_thread_p thread_p = thread_obj->data.ptr;
+
+	if (parm_cnt > MAX_NUM_PARAMS) {
+		printf("User thread error: too many user thread parameters");
+		thread_p->running = FALSE;
+		return NULL;
+	}
+	for (i=0; i < parm_cnt; i += 2) {
+		lbl_val_arr[i]   = NULL;
+		lbl_val_arr[i+1] = list_item(ist, uthread->params, i/2);
+	}
+	new_locals = new_object(ist, NULL);
+	set_attr(ist, thread_obj, SYM(__LOCALS__), new_locals);
+	syn_self = get_attr(ist, func_obj, SYM(__SELF__));
+	new_frame = create_frame( ist, syn_self, NULL, thread_obj, NULL, NULL, new_locals, func_obj, NULL );
+	new_frame->called_from_c = TRUE;
+	new_frame->prev_frame = NULL;
+	load_frame_params( ist, new_locals, func_obj, parm_cnt, lbl_val_arr);
+	if (intrp_exobj) {
+		printf("User thread exception");
+		check_exceptions(ist);
+		thread_p->running = FALSE;
+		return NULL;
+	}
+	ist->frame = new_frame;
+	exec_loop(ist);
+	thread_p->running = FALSE;
+	return NULL;
+}
+
 #define CODE_DATA_STR_SIZE	1024
 
 //******************************** codedata ***********************************

Modified: trunk/src/interp.h
===================================================================
--- trunk/src/interp.h	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/src/interp.h	2004-04-10 07:59:39 UTC (rev 316)
@@ -111,6 +111,7 @@
 } fparam_proc_state_t;
 
 void *main_thread(apr_thread_t *handle, void *filename);
+void *user_thread(apr_thread_t *handle, void *argv); 
 
 obj_p exec_string(isp ist, char* str, int get_frame, frame_p *framep);
 

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/src/main.c	2004-04-10 07:59:39 UTC (rev 316)
@@ -138,7 +138,7 @@
 
 	main_argv_obj = get_attr(ist, sys_argv_obj, sym(ist, "argv"));
 	if (main_argv_obj && list_len(ist, main_argv_obj)) {
-		main1_thread_obj = new_thread_obj(ist, (apr_thread_start_t)main_thread, main_argv_obj);
+		main1_thread_obj = new_thread_obj(ist, (apr_thread_start_t)main_thread, main_argv_obj, NULL);
 		main1_thread_ptr = main1_thread_obj->data.ptr;
 		if (cmd_line_option_i_flg) 
 			main1_thread_ptr->save_frame = TRUE;
@@ -148,14 +148,14 @@
 	if (threads) {
 		int i;
 		for (i = 0; i < (int) list_len(ist, threads); i++)
-			new_thread_obj(ist, (apr_thread_start_t)main_thread, list_item(ist, threads, i));
+			new_thread_obj(ist, (apr_thread_start_t)main_thread, list_item(ist, threads, i), NULL);
 	}
 
-	new_thread_obj(ist, (apr_thread_start_t)mem_mgr_thread, NULL);
+	new_thread_obj(ist, (apr_thread_start_t)mem_mgr_thread, NULL, NULL);
 
 #ifdef DEBUG_THREADS
 	SetThreadName("main");
-	new_thread_obj(ist, (apr_thread_start_t)torture_scan_thread, torture_scan_num_ptr);
+	new_thread_obj(ist, (apr_thread_start_t)torture_scan_thread, torture_scan_num_ptr, NULL);
 #endif
 
 #ifdef DEBUG_THREADS

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/src/object.c	2004-04-10 07:59:39 UTC (rev 316)
@@ -1113,7 +1113,8 @@
 }
 
 //********************************* list6 *************************************
-obj_p list6(isp ist, obj_p item1, obj_p item2, obj_p item3, obj_p item4, obj_p item5, obj_p item6){
+obj_p list6(isp ist, obj_p item1, obj_p item2, obj_p item3, obj_p item4, 
+			         obj_p item5, obj_p item6 ){
 	obj_p list_obj = new_list_obj(ist, 6);
 	list_append_no_lock(list_obj, item1); list_append_no_lock(list_obj, item2);
 	list_append_no_lock(list_obj, item3); list_append_no_lock(list_obj, item4);
@@ -1121,6 +1122,17 @@
 	return list_obj;
 }
 
+//********************************* list8 *************************************
+obj_p list8(isp ist, obj_p item1, obj_p item2, obj_p item3, obj_p item4, 
+			         obj_p item5, obj_p item6, obj_p item7, obj_p item8 ){
+	obj_p list_obj = new_list_obj(ist, 8);
+	list_append_no_lock(list_obj, item1); list_append_no_lock(list_obj, item2);
+	list_append_no_lock(list_obj, item3); list_append_no_lock(list_obj, item4);
+	list_append_no_lock(list_obj, item5); list_append_no_lock(list_obj, item6);
+	list_append_no_lock(list_obj, item7); list_append_no_lock(list_obj, item8);
+	return list_obj;
+}
+
 //********************************* new_dict_obj ******************************
 obj_p new_dict_obj(isp ist, int initial_size){
 	obj_p dict_obj = new_object(ist, OBJ(DICT_PROTO));

Modified: trunk/src/thread.h
===================================================================
--- trunk/src/thread.h	2004-04-10 05:14:24 UTC (rev 315)
+++ trunk/src/thread.h	2004-04-10 07:59:39 UTC (rev 316)
@@ -57,7 +57,9 @@
 #define THREAD_H
 
 #include "clist.h"
+#include "interp.h"
 
+
 extern obj_p new_thread_object;
 extern clist_p thread_registry;
 //extern DECLARE_PR_LOCK(thread_registry_lock);
@@ -65,9 +67,9 @@
 
 #define thread_saveframe(thread_obj) (((pr_thread_p)((thread_obj)->data.ptr))->save_frame)
 #define thread_frame(thread_obj)     (((pr_thread_p)((thread_obj)->data.ptr))->frame)
+#define thread_running(thread_obj)   (((pr_thread_p)((thread_obj)->data.ptr))->running)
 
 obj_p register_thread(isp ist, apr_thread_t *this_thread);
-obj_p new_thread_obj(isp ist, apr_thread_start_t thread_func, void *thread_data);
 apr_thread_t* os_thread_2_apr(apr_os_thread_t os_thread);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.