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);