Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

lang/cplusplus/minipy/trunk: スレッド生成、joinができるようになった。(mutex, cond, sema…

…phoreなどは未実装)
  • Loading branch information...
commit 1c1c11c163369abcb7a5f7792f44d885f98e9e9a 1 parent 35771c4
hayamiz authored
4 bootstrap.inc
View
@@ -1,5 +1,5 @@
/* !! DO NOT EDIT THIS FILE !! */
-/* this file was generated by etc/gen_bootstrap.rb @ Mon Jun 30 13:54:03 +0900 2008 */
+/* this file was generated by etc/gen_bootstrap.rb @ Tue Jul 01 17:13:28 +0900 2008 */
genv.set_sym(Symbol::get("is_int"), Py_val::mk_nfun(Symbol::get("is_int"), 1, native::is_int));
genv.set_sym(Symbol::get("is_float"), Py_val::mk_nfun(Symbol::get("is_float"), 1, native::is_float));
genv.set_sym(Symbol::get("is_string"), Py_val::mk_nfun(Symbol::get("is_string"), 1, native::is_string));
@@ -91,5 +91,3 @@ genv.set_sym(Symbol::get("range"), Py_val::mk_nfun(Symbol::get("range"), -1, nat
genv.set_sym(Symbol::get("pop"), Py_val::mk_nfun(Symbol::get("pop"), -1, native::pop));
genv.set_sym(Symbol::get("ntv_random"), Py_val::mk_nfun(Symbol::get("ntv_random"), -1, native::ntv_random));
genv.set_sym(Symbol::get("sys_sleep"), Py_val::mk_nfun(Symbol::get("sys_sleep"), 1, native::sys_sleep));
-genv.set_sym(Symbol::get("thread_start"), Py_val::mk_nfun(Symbol::get("thread_start"), 2, native::thread_start));
-genv.set_sym(Symbol::get("thread_join"), Py_val::mk_nfun(Symbol::get("thread_join"), 1, native::thread_join));
4 etc/gen_bootstrap.rb
View
@@ -98,10 +98,6 @@
[:ntv_random, -1],
[:sys_sleep, 1],
-
- # experimental
- [:thread_start, 2],
- [:thread_join, 1],
]
puts "/* !! DO NOT EDIT THIS FILE !! */"
63 native.cpp
View
@@ -1511,66 +1511,3 @@ py_val_t native::sys_sleep(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p,
return ret;
}
-
-py_val_t native::thread_start(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p,
- py_val_t * a){
- // thread_start(<function>, <tuple as arguments>)
-
- py_val_t thread = Py_val::mk_thread(a[0]);
-
- Py_thread_args * args = new Py_thread_args();
- args->th = thread->u.th;
- args->strace = bt;
- args->pos = &p;
- args->args = new py_val_t[a[1]->u.nl->size()];
-
- for(uint i = 0; i < a[1]->u.nl->size();i++){
- args->args[i] = a[1]->u.nl->get(i);
- }
-
- if (Py_val::is_vfun(a[0])){
- if (pthread_create(&thread->u.th->th
- , NULL
- , thread_vfun_dispatch
- , args) != 0) {
- runtime_error(bt, p,
- "thread error: cannot create thread");
- }
- } else if (Py_val::is_nfun(a[0])) {
- if (pthread_create(&thread->u.th->th
- , NULL
- , thread_nfun_dispatch
- , args) != 0) {
- runtime_error(bt, p,
- "thread error: cannot create thread");
- }
- }
-
- return thread;
-}
-
-void * native::thread_nfun_dispatch(void * a){
- Py_thread_args * args = static_cast<Py_thread_args*>(a);
-
- args->th->func->u.n->f(args->strace, *args->pos, args->args);
-
- delete(args);
-
- return 0;
-}
-
-void * native::thread_vfun_dispatch(void * a){
-
- Py_thread_args * args = static_cast<Py_thread_args*>(a);
-
- delete(args);
-
- return 0;
-}
-
-py_val_t native::thread_join(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p,
- py_val_t * a){
- // thread_join(<thread>)
-
- return NULL;
-}
9 native.hpp
View
@@ -10,9 +10,6 @@
#include "env.hpp"
#include "tivi.hpp"
-// experimental multithread implementation
-#include <pthread.h>
-
namespace native{
/* 値が特定の型であるかを判定する関数群 */
py_val_t is_int(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p,
@@ -248,12 +245,6 @@ namespace native{
py_val_t * a);
// experimental multithread implementation
- py_val_t thread_start(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p,
- py_val_t * a);
- py_val_t thread_join(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p,
- py_val_t * a);
- void * thread_nfun_dispatch(void * a);
- void * thread_vfun_dispatch(void * a);
}
#endif
15 pyvalues.cpp
View
@@ -645,6 +645,11 @@ bool Py_val::is_number(py_val_t pyval){
return Py_val::is_int(pyval) || Py_val::is_float(pyval);
}
+bool Py_val::is_thread(py_val_t pyval){
+ return is_boxed(pyval) && pyval->type == py_type_thread;
+}
+
+
/* Py_va_tから値を取り出す関数 */
int Py_val::get_int(py_val_t pyval, ConsStack<Stack_trace_entry*> * bt, const SrcPos & pos){
if (!Py_val::is_int(pyval)) {
@@ -1193,8 +1198,16 @@ unsigned int Py_tuple::size(){
Py_thread::Py_thread(py_val_t func){
this->func = func;
+ this->joined = false;
+ pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER;
+ this->join_mutex = mt;
+ pthread_cond_t cnd = PTHREAD_COND_INITIALIZER;
+ this->join_cond = cnd;
+
+ PTH_ASSERT(pthread_mutex_init(&this->join_mutex, NULL));
+ PTH_ASSERT(pthread_cond_init(&this->join_cond, NULL));
}
Py_thread::~Py_thread(){
-
+
}
14 pyvalues.hpp
View
@@ -14,6 +14,7 @@
#include "tokenizer.hpp"
#include "parser.hpp"
#include "symbol.hpp"
+#include "thread.hpp"
class Py_val;
class Py_ifun;
@@ -91,6 +92,8 @@ typedef enum{
py_type_newdict, /* 辞書 */
py_type_newtuple,
py_type_thread,
+ py_type_mutex,
+ py_type_cond,
} py_type_t;
@@ -171,6 +174,7 @@ class Py_val{
static bool is_newtuple(py_val_t pyval);
// static bool is_boxed(py_val_t pyval);
static bool is_number(py_val_t pyval); // is int or float
+ static bool is_thread(py_val_t pyval);
/* 型チェックをし、Py_val_tから値を取り出す.
runtimeエラーを出すのもここです。
@@ -352,6 +356,10 @@ class Py_thread {
public:
pthread_t th;
py_val_t func;
+
+ bool joined;
+ pthread_mutex_t join_mutex;
+ pthread_cond_t join_cond;
Py_thread(py_val_t func);
~Py_thread();
@@ -366,4 +374,10 @@ class Py_thread_args {
void * parent; // Tivi
};
+class Py_mutex {
+public:
+ pthread_mutex_t mutex;
+
+}
+
#endif
15 testdata-parser/thread/basic.py
View
@@ -1,12 +1,15 @@
-def th_print(arg):
- while 1:
- if arg == "b":
- print(arg)
+x = 0
-th_a = start_new_thread(th_print, ("a",))
-th_b = start_new_thread(th_print, ("b",))
+def job():
+ global x
+ for i in range(0,100000):
+ x = x + 1
+
+th_a = start_new_thread(print_string, ("hoge",))
+th_b = start_new_thread(print_string, ("fuga",))
thread_join(th_a)
thread_join(th_b)
+print x
35 tivi.cpp
View
@@ -152,7 +152,7 @@ void Tivi::run(int entry_point, ConsStack<Stack_trace_entry*> * bt){
#define CASE(var) var##_CASE:
#define BREAK
-#define TIVI_NEXTI() (PC++); TIVI_NEXT()
+#define TIVI_NEXTI() (PC++) ; TIVI_NEXT()
#define TIVI_NEXT() goto main_loop
#include "dispatchtable.inc"
@@ -179,6 +179,9 @@ void Tivi::run(int entry_point, ConsStack<Stack_trace_entry*> * bt){
main_loop:
if (PC >= pc_limit) {
+ if (this->is_thread){
+ cerr << "[thread exited by PC limit]" << endl;
+ }
return;
}
@@ -710,7 +713,7 @@ void Tivi::run(int entry_point, ConsStack<Stack_trace_entry*> * bt){
if ((f = TIVI_GREF(TIVI_FETCH_OPERAND())) == py_val_not_found){
runtime_error("no such function ", bt, PC);
}
- bt = CONS_STACK(new Stack_trace_entry(*(symbol_t)vmasm->insns[PC].operand
+ bt = CONS_STACK(new Stack_trace_entry(*genv_rev[(int)this->insns[PC].operand]
, TIVI_FETCH_SRCPOS())
, bt);
} else if (INST == VM_VREF_CALL){
@@ -790,6 +793,7 @@ void Tivi::run(int entry_point, ConsStack<Stack_trace_entry*> * bt){
// no operand
if (this->return_stack.size() == 0){
if (this->is_thread){
+ cerr << "[Success: thread exited by VM_RET]" << endl;
return;
} else {
runtime_error("no place to return", bt, PC);
@@ -1003,12 +1007,25 @@ void Tivi::run(int entry_point, ConsStack<Stack_trace_entry*> * bt){
runtime_error("thread error: cannot create thread", bt, PC);
}
}
+
+ VAL = thread;
TIVI_NEXTI();
}
CASE(VM_THREAD_JOIN){
a[0] = VAL;
- pthread_join(a[0]->u.th->th, NULL);
+ if(!Py_val::is_thread(a[0])){
+ runtime_error("thread_join: invalid argument", bt, PC);
+ }
+
+ PTH_ASSERT(pthread_join(a[0]->u.th->th, NULL));
+
+// PTH_ASSERT(pthread_mutex_lock(&(a[0]->u.th->join_mutex)));
+// while(!a[0]->u.th->joined){
+// PTH_ASSERT(pthread_cond_wait(&(a[0]->u.th->join_cond)
+// , &(a[0]->u.th->join_mutex)));
+// }
+// PTH_ASSERT(pthread_mutex_unlock(&(a[0]->u.th->join_mutex)));
TIVI_NEXTI();
}
@@ -1042,14 +1059,12 @@ void * Tivi::thread_nfun_dispatch(void * a){
, *args->pos, args->args);
delete(args);
-
- return 0;
}
void * Tivi::thread_vfun_dispatch(void * a){
Py_thread_args * args = static_cast<Py_thread_args*>(a);
-
+
Tivi * vm = Tivi::fork(static_cast<Tivi*>(args->parent));
vm->is_thread = true;
@@ -1073,7 +1088,13 @@ void * Tivi::thread_vfun_dispatch(void * a){
vm->run(args->th->func->u.vm_i->addr, args->strace);
+
+ PTH_ASSERT(pthread_mutex_lock(&args->th->join_mutex));
+ args->th->joined = true;
+ PTH_ASSERT(pthread_cond_signal(&args->th->join_cond));
+ PTH_ASSERT(pthread_mutex_unlock(&args->th->join_mutex));
+
delete(args);
- return 0;
+ return NULL;
}
2  tivi.hpp
View
@@ -4,9 +4,11 @@
class Tivi;
#include <stack>
+#include <errno.h>
#include "parser.hpp"
#include "translator.hpp"
#include "native.hpp"
+#include "thread.hpp"
using namespace std;
1  translator.cpp
View
@@ -417,6 +417,7 @@ void Translator::insns_val(const Expr & expr, vm_assembler & vmasm, LocalEnv * l
} else if (func == Symbol::get("thread_join")){
this->insns_val(*expr.u.call->args[0], vmasm, lenv);
vmasm.THREAD_JOIN(expr.pos);
+ break;
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.