static SQInteger thread_wakeup(HSQUIRRELVM v) { SQObjectPtr o = stack_get(v,1); if(type(o) == OT_THREAD) { SQVM *thread = _thread(o); SQInteger state = sq_getvmstate(thread); if(state != SQ_VMSTATE_SUSPENDED) { switch(state) { case SQ_VMSTATE_IDLE: return sq_throwerror(v,_SC("cannot wakeup a idle thread")); break; case SQ_VMSTATE_RUNNING: return sq_throwerror(v,_SC("cannot wakeup a running thread")); break; } } SQInteger wakeupret = sq_gettop(v)>1?1:0; if(wakeupret) { sq_move(thread,v,2); } if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1,SQFalse))) { sq_move(v,thread,-1); sq_pop(thread,1); if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { sq_pop(thread,1); } return 1; } return SQ_ERROR; } return sq_throwerror(v,_SC("wrong parameter")); }
static SQInteger thread_getstackinfos(HSQUIRRELVM v) { SQObjectPtr o = stack_get(v,1); if(type(o) == OT_THREAD) { SQVM *thread = _thread(o); SQInteger threadtop = sq_gettop(thread); SQInteger level; sq_getinteger(v,-1,&level); SQRESULT res = __getcallstackinfos(thread,level); if(SQ_FAILED(res)) { sq_settop(thread,threadtop); if(type(thread->_lasterror) == OT_STRING) { sq_throwerror(v,_stringval(thread->_lasterror)); } else { sq_throwerror(v,_SC("unknown error")); } } if(res > 0) { //some result sq_move(v,thread,-1); sq_settop(thread,threadtop); return 1; } //no result sq_settop(thread,threadtop); return 0; } return sq_throwerror(v,_SC("wrong parameter")); }
static SQInteger thread_call(HSQUIRRELVM v) { SQObjectPtr o = stack_get(v,1); if(type(o) == OT_THREAD) { SQInteger nparams = sq_gettop(v); _thread(o)->Push(_thread(o)->_roottable); for(SQInteger i = 2; i<(nparams+1); i++) sq_move(_thread(o),v,i); if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) { sq_move(v,_thread(o),-1); return 1; } return SQ_ERROR; } return sq_throwerror(v,_SC("wrong parameter")); }
SQInteger SQSharedState::CollectGarbage(SQVM *vm) { SQInteger n=0; SQCollectable *tchain=NULL; SQVM *vms = _thread(_root_vm); vms->Mark(&tchain); SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed(); _refs_table.Mark(&tchain); MarkObject(_registry,&tchain); MarkObject(_consts,&tchain); MarkObject(_metamethodsmap,&tchain); MarkObject(_table_default_delegate,&tchain); MarkObject(_array_default_delegate,&tchain); MarkObject(_string_default_delegate,&tchain); MarkObject(_number_default_delegate,&tchain); MarkObject(_generator_default_delegate,&tchain); MarkObject(_thread_default_delegate,&tchain); MarkObject(_closure_default_delegate,&tchain); MarkObject(_class_default_delegate,&tchain); MarkObject(_instance_default_delegate,&tchain); MarkObject(_weakref_default_delegate,&tchain); SQCollectable *t = _gc_chain; SQCollectable *nx = NULL; while(t) { t->_uiRef++; t->Finalize(); nx = t->_next; if(--t->_uiRef == 0) t->Release(); t = nx; n++; } t = tchain; while(t) { t->UnMark(); t = t->_next; } _gc_chain = tchain; SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed(); assert(z == x); return n; }
SQSharedState::~SQSharedState() { if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } _constructoridx.Null(); _table(_registry)->Finalize(); _table(_consts)->Finalize(); _table(_metamethodsmap)->Finalize(); _registry.Null(); _consts.Null(); _metamethodsmap.Null(); while(!_systemstrings->empty()) { _systemstrings->back().Null(); _systemstrings->pop_back(); } _thread(_root_vm)->Finalize(); _root_vm.Null(); _table_default_delegate.Null(); _array_default_delegate.Null(); _string_default_delegate.Null(); _number_default_delegate.Null(); _closure_default_delegate.Null(); _generator_default_delegate.Null(); _thread_default_delegate.Null(); _class_default_delegate.Null(); _instance_default_delegate.Null(); _weakref_default_delegate.Null(); _refs_table.Finalize(); #ifndef NO_GARBAGE_COLLECTOR SQCollectable *t = _gc_chain; SQCollectable *nx = NULL; if(t) { t->_uiRef++; while(t) { t->Finalize(); nx = t->_next; if(nx) nx->_uiRef++; if(--t->_uiRef == 0) t->Release(); t = nx; } } assert(_gc_chain==NULL); //just to proove a theory while(_gc_chain){ _gc_chain->_uiRef++; _gc_chain->Release(); } #endif sq_delete(_types,SQObjectPtrVec); sq_delete(_systemstrings,SQObjectPtrVec); sq_delete(_metamethods,SQObjectPtrVec); sq_delete(_stringtable,SQStringTable); if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); }
// MainThread static void MainThread() { int i; #ifdef _OPENMP # pragma omp parallel for #endif for ( i = 0; i < 4; i++ ) { #ifdef _OPENMP int tid = omp_get_thread_num(); # pragma omp critical printf("Main : tid %d\n",tid); _thread((void *)(size_t)tid); #endif } return; }
void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) { switch(type(o)){ case OT_TABLE:_table(o)->Mark(chain);break; case OT_ARRAY:_array(o)->Mark(chain);break; case OT_USERDATA:_userdata(o)->Mark(chain);break; case OT_CLOSURE:_closure(o)->Mark(chain);break; case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; case OT_GENERATOR:_generator(o)->Mark(chain);break; case OT_THREAD:_thread(o)->Mark(chain);break; case OT_CLASS:_class(o)->Mark(chain);break; case OT_INSTANCE:_instance(o)->Mark(chain);break; case OT_OUTER:_outer(o)->Mark(chain);break; default: break; //shutup compiler } }
static SQInteger thread_getstatus(HSQUIRRELVM v) { SQObjectPtr &o = stack_get(v,1); switch(sq_getvmstate(_thread(o))) { case SQ_VMSTATE_IDLE: sq_pushstring(v,_SC("idle"),-1); break; case SQ_VMSTATE_RUNNING: sq_pushstring(v,_SC("running"),-1); break; case SQ_VMSTATE_SUSPENDED: sq_pushstring(v,_SC("suspended"),-1); break; default: return sq_throwerror(v,_SC("internal VM error")); } return 1; }
char *strtok (char *string1, const char *string2) { char table[256]; unsigned char *p, *result; #if defined (__MT__) struct _thread *tp = _thread (); #define next (tp->_th_strtok_ptr) #else static unsigned char *next = NULL; #endif if (string1 != NULL) p = (unsigned char *)string1; else { if (next == NULL) return NULL; p = next; } memset (table, 0, 256); while (*string2 != 0) table[(unsigned char)*string2++] = 1; table[0] = 0; while (table[*p]) ++p; result = p; table[0] = 1; while (!table[*p]) ++p; if (*p == 0) { if (p == result) { next = NULL; return NULL; } } else *p++ = 0; next = p; return (char *)result; }
void SQSharedState::RunMark(SQVM *vm,SQCollectable **tchain) { SQVM *vms = _thread(_root_vm); vms->Mark(tchain); _refs_table.Mark(tchain); MarkObject(_registry,tchain); MarkObject(_consts,tchain); MarkObject(_metamethodsmap,tchain); MarkObject(_table_default_delegate,tchain); MarkObject(_array_default_delegate,tchain); MarkObject(_string_default_delegate,tchain); MarkObject(_number_default_delegate,tchain); MarkObject(_generator_default_delegate,tchain); MarkObject(_thread_default_delegate,tchain); MarkObject(_closure_default_delegate,tchain); MarkObject(_class_default_delegate,tchain); MarkObject(_instance_default_delegate,tchain); MarkObject(_weakref_default_delegate,tchain); }
void sq_close(HSQUIRRELVM v) { SQSharedState *ss = _ss(v); _thread(ss->_root_vm)->Finalize(); sq_delete(ss, SQSharedState); }