void SpellTask::on_run() { THREAD_CHECKPOINT( tasks, 900 ); Mobile::Character* caster = caster_.get(); if ( !caster->orphan() ) { THREAD_CHECKPOINT( tasks, 911 ); spell_->cast( caster ); THREAD_CHECKPOINT( tasks, 912 ); } THREAD_CHECKPOINT( tasks, 999 ); }
void regen_resources() { THREAD_CHECKPOINT( tasks, 700 ); time_t now = poltime(); for ( ResourceDefs::iterator itr = gamestate.resourcedefs.begin(), end = gamestate.resourcedefs.end(); itr != end; ++itr ) { ( *itr ).second->regenerate( now ); } THREAD_CHECKPOINT( tasks, 799 ); }
void step_scripts( polclock_t* clocksleft, bool* pactivity ) { // cerr << "r"; THREAD_CHECKPOINT( scripts, 102 ); *pactivity = (!runlist.empty()); THREAD_CHECKPOINT( scripts, 103 ); run_ready(); // cerr << "h"; THREAD_CHECKPOINT( scripts, 104 ); check_blocked( clocksleft ); THREAD_CHECKPOINT( scripts, 105 ); if (!runlist.empty()) *clocksleft = 0; THREAD_CHECKPOINT( scripts, 106 ); }
void check_blocked( polclock_t* pclocksleft ) { polclock_t now_clock = polclock(); sleep_cycles += holdlist.size() + notimeoutholdlist.size(); polclock_t clocksleft = POLCLOCKS_PER_SEC * 60; for(;;) { THREAD_CHECKPOINT( scripts, 131 ); HoldList::iterator itr = holdlist.begin(); if (itr == holdlist.end()) break; UOExecutor* ex = (*itr).second; // ++ex->sleep_cycles; passert( ex->os_module->blocked_ ); passert( ex->os_module->sleep_until_clock_ != 0 ); clocksleft = ex->os_module->sleep_until_clock_ - now_clock; if ( clocksleft <= 0 ) { if (clocksleft == 0) INC_PROFILEVAR( scripts_ontime ); else INC_PROFILEVAR( scripts_late ); // wakey-wakey // read comment above to understand what goes on here. // the return value is already on the stack. THREAD_CHECKPOINT( scripts, 132 ); ex->os_module->revive(); } else { break; } } *pclocksleft = clocksleft; }
void run_ready() { THREAD_CHECKPOINT( scripts, 110 ); while (!runlist.empty()) { ExecList::iterator itr = runlist.begin(); UOExecutor* ex = *itr; runlist.pop_front(); // remove it directly, since itr can get invalid during execution OSExecutorModule* os_module = ex->os_module; scripts_thread_script = ex->scriptname(); int inscount = 0; int totcount = 0; int insleft = os_module->priority / priority_divide; if (insleft == 0) insleft = 1; THREAD_CHECKPOINT( scripts, 111 ); while (ex->runnable()) { ++ex->instr_cycles; THREAD_CHECKPOINT( scripts, 112 ); scripts_thread_scriptPC = ex->PC; ex->execInstr(); THREAD_CHECKPOINT( scripts, 113 ); if (os_module->blocked_) { ex->warn_runaway_on_cycle = ex->instr_cycles + config.runaway_script_threshold; ex->runaway_cycles = 0; break; } if (ex->instr_cycles == ex->warn_runaway_on_cycle) { ex->runaway_cycles += config.runaway_script_threshold; if (os_module->warn_on_runaway) { script_log << "Runaway script[" << os_module->pid() << "]: " << ex->scriptname() << " (" << ex->runaway_cycles << " cycles)" << endl; ex->show_context( script_log, ex->PC ); } ex->warn_runaway_on_cycle += config.runaway_script_threshold; } if (os_module->critical) { ++inscount; ++totcount; if (inscount > 1000) { inscount = 0; if(config.report_critical_scripts) cerr << "Critical script " << ex->scriptname() << " has run for " << totcount << " instructions" << endl; } continue; } if (!--insleft) { break; } } // hmm, this new terminology (runnable()) is confusing // in this case. Technically, something that is blocked // isn't runnable. if (!ex->runnable()) { if (ex->error() || ex->done) { THREAD_CHECKPOINT( scripts, 114 ); if((ex->pParent != NULL) && ex->pParent->runnable()) { ranlist.push_back(ex); //ranlist.splice( ranlist.end(), runlist, itr ); ex->pParent->os_module->revive(); } else { //runlist.erase( itr ); delete ex; } continue; } else if (!ex->os_module->blocked_) { THREAD_CHECKPOINT( scripts, 115 ); //runlist.erase( itr ); ex->os_module->in_hold_list_ = OSExecutorModule::DEBUGGER_LIST; debuggerholdlist.insert( ex ); continue; } } if (ex->os_module->blocked_) { THREAD_CHECKPOINT( scripts, 116 ); if (ex->os_module->sleep_until_clock_) { ex->os_module->in_hold_list_ = OSExecutorModule::TIMEOUT_LIST; ex->os_module->hold_itr_ = holdlist.insert( HoldList::value_type( ex->os_module->sleep_until_clock_, ex ) ); } else { ex->os_module->in_hold_list_ = OSExecutorModule::NOTIMEOUT_LIST; notimeoutholdlist.insert( ex ); } //runlist.erase( itr ); --ex->sleep_cycles; // it'd get counted twice otherwise --sleep_cycles; THREAD_CHECKPOINT( scripts, 117 ); } else { ranlist.push_back(ex); //ranlist.splice( ranlist.end(), runlist, itr ); } } THREAD_CHECKPOINT( scripts, 118 ); runlist.swap( ranlist ); THREAD_CHECKPOINT( scripts, 119 ); }
/* NOTE: If this changes, code in client.cpp must change - pause() and restart() use pre-encrypted values of 33 00 and 33 01. */ void Client::transmit_encrypted( const void* data, int len ) { THREAD_CHECKPOINT( active_client, 100 ); const unsigned char* cdata = (const unsigned char*)data; unsigned char* pch; int i; int bidx; // Offset in output byte EncryptedPktBuffer* outbuffer = PktHelper::RequestPacket<EncryptedPktBuffer>( ENCRYPTEDPKTBUFFER ); pch = reinterpret_cast<unsigned char*>( outbuffer->getBuffer() ); bidx = 0; THREAD_CHECKPOINT( active_client, 101 ); for ( i = 0; i < len; i++ ) { THREAD_CHECKPOINT( active_client, 102 ); unsigned char ch = cdata[i]; int nbits = Core::keydesc[ch].nbits; unsigned short inval = Core::keydesc[ch].bits_reversed; THREAD_CHECKPOINT( active_client, 103 ); while ( nbits-- ) { THREAD_CHECKPOINT( active_client, 104 ); *pch <<= 1; if ( inval & 1 ) *pch |= 1; bidx++; if ( bidx == 8 ) { THREAD_CHECKPOINT( active_client, 105 ); pch++; bidx = 0; } THREAD_CHECKPOINT( active_client, 106 ); inval >>= 1; } THREAD_CHECKPOINT( active_client, 107 ); } THREAD_CHECKPOINT( active_client, 108 ); { int nbits = Core::keydesc[0x100].nbits; unsigned short inval = Core::keydesc[0x100].bits_reversed; THREAD_CHECKPOINT( active_client, 109 ); while ( nbits-- ) { THREAD_CHECKPOINT( active_client, 110 ); *pch <<= 1; if ( inval & 1 ) *pch |= 1; bidx++; THREAD_CHECKPOINT( active_client, 111 ); if ( bidx == 8 ) { pch++; bidx = 0; } THREAD_CHECKPOINT( active_client, 112 ); inval >>= 1; } } THREAD_CHECKPOINT( active_client, 113 ); if ( bidx == 0 ) { pch--; } else { *pch <<= ( 8 - bidx ); } THREAD_CHECKPOINT( active_client, 114 ); passert_always( pch - reinterpret_cast<unsigned char*>( outbuffer->buffer ) + 1 <= int( sizeof outbuffer->buffer ) ); THREAD_CHECKPOINT( active_client, 115 ); xmit( &outbuffer->buffer, static_cast<unsigned short>( pch - reinterpret_cast<unsigned char*>( outbuffer->buffer ) + 1 ) ); PktHelper::ReAddPacket( outbuffer ); THREAD_CHECKPOINT( active_client, 116 ); }
/*void check_scheduled_tasks( void ) { unsigned idx; unsigned count; time_t now; if (p_task_list) { now = poltime(NULL); count = p_task_list->count(); for( idx = 0; idx < count; idx++ ) { ScheduledTask *task = (*p_task_list)[idx]; if (task->ready(now)) { task->execute(now); } if (task->cancelled) { p_task_list->remove( idx ); delete task; } } } } */ void check_scheduled_tasks( polclock_t* clocksleft, bool* pactivity ) { THREAD_CHECKPOINT( tasks, 101 ); TaskScheduler::cleanse(); polclock_t now_clock = polclock(); TRACEBUF_ADDELEM( "check_scheduled_tasks now_clock", now_clock ); bool activity = false; passert( !task_queue.empty() ); THREAD_CHECKPOINT( tasks, 102 ); for ( ;; ) { THREAD_CHECKPOINT( tasks, 103 ); ScheduledTask* task = task_queue.top(); TRACEBUF_ADDELEM( "check_scheduled_tasks toptask->nextrun", task->next_run_clock() ); THREAD_CHECKPOINT( tasks, 104 ); if ( !task->ready( now_clock ) ) { *clocksleft = task->clocksleft( now_clock ); *pactivity = activity; TRACEBUF_ADDELEM( "check_scheduled_tasks clocksleft", *clocksleft ); return; } THREAD_CHECKPOINT( tasks, 105 ); if ( !task->late( now_clock ) ) { INC_PROFILEVAR( tasks_ontime ); } else { INC_PROFILEVAR( tasks_late ); INC_PROFILEVAR_BY( tasks_late_ticks, task->ticks_late( now_clock ) ); } THREAD_CHECKPOINT( tasks, 106 ); task_queue.pop(); THREAD_CHECKPOINT( tasks, 107 ); task->execute( now_clock ); THREAD_CHECKPOINT( tasks, 108 ); activity = true; if ( task->cancelled ) { THREAD_CHECKPOINT( tasks, 109 ); delete task; } else { THREAD_CHECKPOINT( tasks, 110 ); task_queue.push( task ); } THREAD_CHECKPOINT( tasks, 111 ); } }