Beispiel #1
0
void
TimeScheduler::update(float time)
{
  while(!schedule.empty() && schedule.front().wakeup_time < time) {
    HSQOBJECT thread_ref = schedule.front().thread_ref;

    sq_pushobject(global_vm, thread_ref);
    sq_getweakrefval(global_vm, -1);

    HSQUIRRELVM scheduled_vm;
    if(sq_gettype(global_vm, -1) == OT_THREAD &&
       SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
      if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
        std::ostringstream msg;
        msg << "Error waking VM: ";
        sq_getlasterror(scheduled_vm);
        if(sq_gettype(scheduled_vm, -1) != OT_STRING) {
          msg << "(no info)";
        } else {
          const char* lasterr;
          sq_getstring(scheduled_vm, -1, &lasterr);
          msg << lasterr;
        }
        log_warning << msg.str() << std::endl;
        sq_pop(scheduled_vm, 1);
      }
    }

    sq_release(global_vm, &thread_ref);
    sq_pop(global_vm, 2);

    std::pop_heap(schedule.begin(), schedule.end());
    schedule.pop_back();
  }
}
Beispiel #2
0
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"));
}
Beispiel #3
0
void
ThreadQueue::wakeup()
{
  // we traverse the list in reverse orders and use indices. This should be
  // robust for scripts that add new entries to the list while we're traversing
  // it
  size_t i = threads.size() - 1;
  size_t end = static_cast<size_t>(0 - 1);
  size_t size_begin = threads.size();
  while(i != end) {
    HSQOBJECT object = threads[i];

    sq_pushobject(global_vm, object);
    sq_getweakrefval(global_vm, -1);

    HSQUIRRELVM scheduled_vm;
    if(sq_gettype(global_vm, -1) == OT_THREAD &&
       SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
      if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
        log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
      }
    }

    sq_release(global_vm, &object);
    sq_pop(global_vm, 1);
    i--;
  }

  threads.erase(threads.begin(), threads.begin() + size_begin);
}
static bool program_memoryarea(HSQUIRRELVM co, const struct reader_handle *h, struct flash_memory_driver *t, bool compare, SQInteger *state, struct textcontrol *log)
{
	if(t->programming.length == 0){
		if(t->programming.offset != 0 && compare == true){
			if(program_compare(h, t) == false){
				log->append(log->object, wgT("%s memory compare failed, offset 0x%06x\n"), t->memory.name, t->programming.offset);
				return false;
			}
		}

		sq_wakeupvm(co, SQFalse, SQFalse, SQTrue, SQFalse);
		*state = sq_getvmstate(co);
	}else{
		program_execute(h, t);
	}
	return true;
}
Beispiel #5
0
/**
 * スレッドのメイン処理
 * @param diff 経過時間
 * @return スレッド実行終了なら true
 */
bool
Thread::_main(long diff)
{
	// スレッドとして動作できてない場合は即終了
	if (_status == THREAD_NONE) {
		return true;
	}

	if (_status == THREAD_LOADING_FILE) {
		// ファイル読み込み処理
		const char *dataAddr;
		int dataSize;
		if (sqobjCheckFile(_fileHandler, &dataAddr, &dataSize)) {
			_init();
			SQRESULT ret = sqstd_loadmemory(_thread, dataAddr, dataSize, _scriptName.getString(), SQTrue);
			sqobjCloseFile(_fileHandler);
			_fileHandler = NULL;
			if (SQ_SUCCEEDED(ret)) {
				_status = THREAD_RUN;
			} else {
				// exit相当
				printError();
				_exit();
				return true;
			}
		} else {
			// 読み込み完了待ち
			return false;
		}
	} else if (_status == THREAD_LOADING_FUNC) {
		// スクリプト読み込み処理
		_init();
		_func.push(_thread);
		_func.clear();
		_status = THREAD_RUN;
	}

	_currentTick += diff;
	
	// タイムアウト処理
	if (_waitTimeout >= 0) {
		_waitTimeout -= diff;
		if (_waitTimeout < 0) {
			_clearWait();
		}
	}
		
	// スレッド実行
	if (!isWait() && _status == THREAD_RUN) {
		SQRESULT result;
		if (sq_getvmstate(_thread) == SQ_VMSTATE_SUSPENDED) {
			_waitResult.push(_thread);
			_waitResult.clear();
			result = sq_wakeupvm(_thread, SQTrue, SQTrue, SQTrue, SQFalse);
		} else {
			sq_pushroottable(_thread);
			SQInteger n = _args.pushArray(_thread) + 1;
			_args.clear();
			result = sq_call(_thread, n, SQTrue, SQTrue);
		}
		if (SQ_FAILED(result)) {
			// スレッドがエラー終了
			printError();
			_exit();
		} else {
			// 終了コード取得。return/suspend の値が格納される
			_exitCode.getStack(_thread, -1);
			sq_pop(_thread, 1);
			if (sq_getvmstate(_thread) == SQ_VMSTATE_IDLE) {
				// スレッドが終了
				_exit();
			}
		}
	}
	
	return _status == THREAD_NONE;
}