void logError(const char *fmt, ...) { LockID lock = Thread.EnterLock(MUTEX_LOG); FILE *logfile = NULL; va_list ap; logfile = fopen("opengta2.log", "a"); va_start(ap, fmt); if (logfile) fprintf(logfile,"[%.3f] Error: ",curtime()); printf("[%.3f] Error: ",curtime()); //Print to log history #ifndef DEDICATED_SERVER char text[8192]; vsnprintf(text,8192,fmt,ap); Console.printf("\003%s\n",text); #endif if (logfile) vfprintf(logfile, fmt, ap); vprintf(fmt, ap); va_end(ap); if (logfile) fprintf(logfile, "\n"); printf("\n"); if (logfile) fclose(logfile); breakpoint(); Thread.LeaveLock(lock); }
void debugTestTimerLoop(float FPSLimit, float interval) { logWrite("FPS must be %.2f. dT must be %.4f seconds",FPSLimit,interval); logDisableDebugOutput = true; float startTime = curtime(); int startFrames = Timer.totalFrames; Timer.Frame(); //First frame Timer.FPSLimit = FPSLimit; while ((curtime() - startTime < 2.0f) && (Timer.totalFrames - startFrames < 64)) { Thread.Sleep(interval); Timer.Frame(); logWrite("Time: %.8f sec; dT: %.8f; FPS: %.4f",Timer.Time(),Timer.dT(),Timer.FPS()); if (abs(Timer.dT() - interval) > 0.1f) { logError("Timer test failed: dT difference too high (> d0.1 sec)"); return; } if ((FPSLimit > 0) && (abs(Timer.FPS() - FPSLimit) > 0.05f * FPSLimit)) { logError("Timer test failed: FPS difference too high (>5%, >%.5f sec)",0.05f * FPSLimit); return; } } logDisableDebugOutput = false; }
void logWritem(const char *fmt, ...) { #ifdef _DEBUG LockID lock = Thread.EnterLock(MUTEX_LOG); FILE *logfile = NULL; va_list ap; logfile = fopen("opengta2.log", "a"); va_start(ap, fmt); if (logfile) fprintf(logfile,"[%.3f] \t",curtime()); if (!logDisableDebugOutput) printf("[%.3f] \t",curtime()); //Print to log history #ifndef DEDICATED_SERVER char text[8192]; vsnprintf(text,8192,fmt,ap); Console.printf("\001%s\n",text); #endif if (logfile) vfprintf(logfile, fmt, ap); if (!logDisableDebugOutput) vprintf(fmt, ap); va_end(ap); if (logfile) fprintf(logfile, "\n"); if (!logDisableDebugOutput) printf("\n"); if (logfile) fclose(logfile); Thread.LeaveLock(lock); #endif }
int main() { long long aisz, aosz; double dt; double t0, t1, t2; char *buf; int i; // t0=clock(); t0=curtime(); aisz=0; buf=malloc(1<<20); while(!feof(stdin)) // while(1) { i=fread(buf, 1, 1<<20, stdin); aisz+=1<<20; t1=curtime(); t2=t1-t0; dt=t2; fprintf(stderr, "%.3fMB/s %.3f \r", (aisz/(1024.0*1024.0))/dt, dt); // fprintf(stderr, "%.3fMB/s %.3f(%d) \r", // (aisz/(1024.0*1024.0))/dt, dt, t2); } printf("\n"); printf("dt=%.3fs\n", dt); }
void test_mydifftime() { struct timeval begin, end; curtime(&begin); usleep(5); curtime(&end); printf("Time Diff:%llu\n", mydifftime(&begin, &end)); }
void *worker(void *arg) { struct state *s = arg; s->workfn = s->opi & MFwrt ? wwriter : wreader; s->posfn = s->opi & MFrnd ? randpos : linpos; s->fd = open(fn, (s->opi & MFwrt ? O_WRONLY : O_RDONLY) | oflags); if (s->fd < 0) { int e = errno; decnr(); errno = e; edie(fn); } s->stime = curtime(); for(;;) { if (term) break; if (s->workfn(s, s->posfn(s)) < 0) { perror(ion[s->opi]); break; } ++s->ioc; incc(); if (bm && s->ioc >= bm) break; } decnr(); return 0; }
int enqueue(queue_t *q, RTP_header *h, unsigned ft, unsigned char *p, unsigned l, unsigned scale) { unsigned j = 0; double t = h->timestamp / (double)scale; if (q->mode & MODE_STREAM || .99 * t <= curtime()) { if (!lock(&q->lock)) return 0; if (l > sizeof q->packets[q->s].p) goto PS; while (j++ < q->n && q->packets[q->s].blocked) INC(q); if (q->packets[q->s].blocked) goto PS; q->packets[q->s].id = h->id; q->packets[q->s].tstamp = t; q->packets[q->s].frame = ft; q->packets[q->s].size = l; q->packets[q->s].next = 0; q->packets[q->s].prev = 0; q->packets[q->s].blocked = 1; memcpy(q->packets[q->s].p, p, l); addpacket(q, &q->packets[q->s]); INC(q); unlock(&q->lock); return 1; } else { return 0; } PS: seterror(err_PS); unlock(&q->lock); return 0; }
void lprintf(char *fmt, ...) { va_list ap; char buf[1024], *prefix; FILE *out; /* CRITICAL SECTION */ pthread_mutex_lock(&log_mutex); va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); prefix = curtime(); out = log_fp; if (!out) { prefix = "***"; out = stdout; } fprintf(out, "[%s] %s", prefix, buf); fflush(out); pthread_mutex_unlock(&log_mutex); /* CRITICAL SECTION */ return ; }
// calculates the avg. fps and simulation rate once every NITER iterations // returns a simrate and fps of -1 for the first NITER iterations void framerate(long simtime, double *simrate, int *fps) { int j; static int i = 0; static long frmtime = -1; static double simsum = -1, frmsum = -1; static long simtimes[NITER], frmtimes[NITER]; struct timespec now; static struct timespec markt; now = curtime(); if (markt.tv_sec == 0 && markt.tv_nsec == 0) markt = now; else { frmtime = convtns(tdiff(now, markt)); markt = now; simtimes[i] = simtime; frmtimes[i++] = frmtime; if (i == NITER) { simsum = frmsum = 0; for (j = 0; j < NITER; j++) { simsum += simtimes[j]; frmsum += frmtimes[j]; } i = 0; } } *simrate = (simsum == -1) ? -1 : (double) simsum / frmsum; *fps = (frmsum == -1) ? -1 : round((double) 1e9 * NITER / frmsum); }
void request_slot(int i) { requested_slot = i; request_sent_time = curtime(); char buffer[32]; sprintf(buffer, "omg req %i", i); state = STATE_REQUESTED; send_msg(buffer); }
void logStart() { FILE* logfile = fopen("opengta2.log","w+"); if (!logfile) { printf("[%.3f] Error: unable to write log file\n", curtime()); } else fclose(logfile); #ifndef DEDICATED_SERVER Console.consoleTempText = (char*)malloc(CONSOLE_TEMP_TEXT_SIZE); //FIXME Console.consoleTempTextPtr = Console.consoleTempText; Console.consoleTextSize = 16384; #endif logDisableDebugOutput = false; }
// return capped length of time for the last cycle through main()'s loop // (this value is used to tell the physics engine how much time to simulate.) // also slow things down to MAXFPS; leave at least MINIDLEP% cpu idle // TODO: avoid overflow with multi-second time deltas on 32 bit systems. long timebal(void) { long calctime, waitt, truewaitt, minidle, totalt; static long waitdiff; struct timespec now; static struct timespec markt, marktbeforeidle; now = curtime(); if (markt.tv_sec == 0 && markt.tv_nsec == 0) markt = marktbeforeidle = now; calctime = convtns(tdiff(now, markt)); marktbeforeidle = now; waitt = MINFT - calctime - waitdiff; // free a minimum of MINIDLEP% cpu minidle = calctime * MINIDLEP / 100; waitt = (waitt < minidle) ? minidle : waitt; waitns(waitt); markt = curtime(); truewaitt = convtns(tdiff(markt, marktbeforeidle)); if (waitdiff == 0) waitdiff = truewaitt - waitt; else waitdiff = (9 * waitdiff) / 10 + (truewaitt - waitt) / 10; totalt = calctime + truewaitt; // avoid positive feedback loop causing scheduled simulation time to // escalate on slower machines totalt = (totalt > MAXFT) ? MAXFT : totalt; return totalt; }
int simulated_annealing(int n, double seconds) { default_random_engine rng; uniform_real_distribution<double> randfloat(0.0, 1.0); uniform_int_distribution<int> randint(0, n - 2); // random initial solution vi sol(n); rep(i,0,n) sol[i] = i + 1; random_shuffle(sol.begin(), sol.end()); // initialize score int score = 0; rep(i,1,n) score += abs(sol[i] - sol[i-1]); int iters = 0; double T0 = 100.0, T1 = 0.001, progress = 0, temp = T0, starttime = curtime(); while (true) { if (!(iters & ((1 << 4) - 1))) { progress = (curtime() - starttime) / seconds; temp = T0 * pow(T1 / T0, progress); if (progress > 1.0) break; } // random mutation int a = randint(rng); // compute delta for mutation int delta = 0; if (a > 0) delta += abs(sol[a+1] - sol[a-1]) - abs(sol[a] - sol[a-1]); if (a+2 < n) delta += abs(sol[a] - sol[a+2]) - abs(sol[a+1] - sol[a+2]); // maybe apply mutation if (delta >= 0 || randfloat(rng) < exp(delta / temp)) { swap(sol[a], sol[a+1]); score += delta; // if (score >= target) return; } iters++; } return score; }
void Network_Message::End() { if (!Network.msgSendLock) { logError("Trying to end message without starting it!"); } *(unsigned short*)(rawBuffer) = rawSize; //Message size Network.numPacketsSent++; float fakeLag = Convar.GetFloat(Network.cvFakeLag)/1000.0f; if (fakeLag > 0.0f) { sendTime = curtime() + fakeLag; } else { doSendData(); sendTime = 0.0f; } Thread.LeaveLock(Network.msgSendLock); Network.msgSendLock = 0; }
static void pst(FILE *f) { double ct = curtime(); double r[4] = { 0, 0, 0, 0 }; unsigned c[4] = { 0, 0, 0, 0 }; unsigned i; double d; for(i = 0; i < ntt; ++i) { d = ct - states[i].stime; r[states[i].opi] += states[i].ioc / d; c[states[i].opi] += states[i].ioc; } //#if 1 // for(i = 0; i < 4; ++i) // if (c[i]) // fprintf(f, " %s %u %.2f", ion[i], c[i], r[i] * bs / 1024 / 1024); //#endif }
void dequeue(queue_t *q) { int r; packet_t *pl; if (!lock(&q->lock)) return; pl = q->packetlist; while (pl) { if (q->mode & MODE_STREAM || pl->tstamp <= curtime()) { if (0 < (r = sendbuf(pl->p, pl->size, pl->frame == A ? AUDIO : VIDEO))) { q->bytes_sent += r; pl = delpacket(q, pl); } } } unlock(&q->lock); }
void Network_Manager::Frame() { //Send delayed packets LockID lockID = Thread.EnterLock(MUTEX_NETWORK_SENDBUF); for (uint i = 0; i < Connections.Count; i++) { if (Connections[i]->connectionOpen) { for (uint j = 0; j < Connections[i]->sendQueue.AllocCount; j++) { if ((Connections[i]->sendQueue[j]->networkConnection) && (Connections[i]->sendQueue[j]->sendTime > 0.0f) && (curtime() > Connections[i]->sendQueue[j]->sendTime)) { Connections[i]->sendQueue[j]->doSendData(); } } } } Thread.LeaveLock(lockID); //Update all connections for (uint i = 0; i < Connections.Count; i++) { if ((Connections[i]->socketHandle < 0) && (Connections[i]->connectionOpen)) { //Free up resources Connections[i]->Close(); if (i == 0) { IsConnected = false; IsServer = false; } //Destroy client connections for (uint j = 0; j < Clients.List.AllocCount; j++) { if (Clients[j]->Connection == Connections[i]) { Clients[j]->Connection = 0; } } } else Connections[i]->Update(); } //Check if we disconnected if (!IsServer) { if (Connections[0]->socketHandle < 0) IsConnected = false; } //Synchronize server time/get ping if ((!IsServer) && (IsConnected) && (curtime() - prevTimeSyncTick > (Convar.GetFloat(cvTimeRate)))) { prevTimeSyncTick = curtime(); if (prevTimeSyncMessageTime <= 0) { //Make a new network request to server Network_Message* msg = Connections[0]->NewMessage(); msg->Start(NETMESSAGE_TIMESYNC); msg->SendFloat(ServerTimer.Time()); msg->End(); prevTimeSyncMessageTime = ServerTimer.Time(); } } /*if (Connections[1]->socketHandle >= 0) { if (Timer.Time() - testTime > 0.25f) { testTime = Timer.Time(); char buf[256]; sprintf(buf,"Time: %.3f\r",Timer.Time()); Network_Message* msg = Connections[1]->NewMessage(); msg->Start(100); msg->SendString(buf); msg->End(); } }*/ }
void setup_clock(void) { clk_tck = sysconf(_SC_CLK_TCK); gtime = curtime(); }
void reset_clock(void) { gtime = curtime(); }
s64 curtime_ms() { return(curtime()*1000); }
double sendrate(queue_t *q) { return q->bytes_sent / curtime(); }
// main AI thinking routine, called every frame for every monster void monsteraction(dynent *m) { if (m->enemy->state==CS_DEAD) { m->enemy = player1; m->anger = 0; } normalise(m, m->targetyaw); if (m->targetyaw>m->ypr.x) { // slowly turn monster towards his target m->ypr.x += curtime()*0.5f; if (m->targetyaw<m->ypr.x) m->ypr.x = m->targetyaw; } else { m->ypr.x -= curtime()*0.5f; if (m->targetyaw>m->ypr.x) m->ypr.x = m->targetyaw; } const float disttoenemy = distance(m->o, m->enemy->o); m->ypr.y = atan2(m->enemy->o.y-m->o.y, disttoenemy)*180.f/float(pi); // special case: if we run into scenery if (m->blocked) { m->blocked = false; // try to jump over obstackle (rare) if (!rnd(20000/monstertypes[m->mtype].speed)) m->jumpnext = true; // search for a way around (common) else if (m->trigger<lastmillis() && (m->monsterstate!=M_HOME || !rnd(5))) { m->targetyaw += 180.f+rnd(180); // patented "random walk" AI pathfinding (tm) ;) transition(m, M_SEARCH, 1, 400, 1000); } } const auto enemyyaw = -atan2(m->enemy->o.x-m->o.x, m->enemy->o.z-m->o.z)/float(pi)*180.f+180.f; switch (m->monsterstate) { case M_PAIN: case M_ATTACKING: case M_SEARCH: if (m->trigger<lastmillis()) transition(m, M_HOME, 1, 100, 200); break; // state classic sp monster start in, wait for visual contact case M_SLEEP: { vec3f target; // skip running physics if (edit::mode() || !enemylos(m, target)) return; normalise(m, enemyyaw); const auto angle = abs(enemyyaw-m->ypr.x); if (disttoenemy<8.f || // the better the angle to the player (disttoenemy<16.f && angle<135.f) || // the further the monster can (disttoenemy<32.f && angle<90.f) || // see/hear (disttoenemy<64.f && angle<45.f) || angle<10) { transition(m, M_HOME, 1, 500, 200); sound::play(sound::GRUNT1+rnd(2), &m->o); } } break; // this state is the delay between wanting to shoot and actually firing case M_AIMING: if (m->trigger<lastmillis()) { m->lastaction = 0; m->attacking = true; shoot(m, m->attacktarget); transition(m, M_ATTACKING, 0, 600, 0); } break; // monster has visual contact, heads straight for player and may want to // shoot at any time case M_HOME: m->targetyaw = enemyyaw; if (m->trigger<lastmillis()) { vec3f target; // no visual contact anymore, let monster get as close as possible then // search for player if (!enemylos(m, target)) transition(m, M_HOME, 1, 800, 500); else { // the closer the monster is the more likely he wants to shoot if (!rnd((int)disttoenemy/3+1) && m->enemy->state==CS_ALIVE) { // get ready to fire m->attacktarget = target; transition(m, M_AIMING, 0, monstertypes[m->mtype].lag, 10); } else // track player some more transition(m, M_HOME, 1, monstertypes[m->mtype].rate, 0); } } break; } physics::moveplayer(m, 1, false); // use physics to move monster }
/** * Handles network traffic. */ void network() { char buffer[1024]; size_t size; struct sockaddr src_addr; socklen_t addrlen; FD_ZERO(&readset); FD_SET(sockfd,&readset); tv.tv_sec = 0; tv.tv_usec = 0; if(select(sockfd+1,&readset,NULL,NULL,&tv) > 0) { size = recvfrom(sockfd, buffer, 1024, 0, &src_addr, &addrlen); //printf(">> %s\n", buffer); if(strncmp(buffer,"omg ",4)==0) { char * data = buffer+4; switch(state) { case STATE_INIT: break; case STATE_REQUESTED: if(CMD("nak")) { int slot; sscanf(data, "nak %d", &slot); printf("Recived nak for slot %i\n", slot); ++slot; if(slot < 4) request_slot(slot); else { printf("No free slots, shutting down"); exit(2); } } break; case STATE_PLAYING: if(CMD("req")) { int slot; sscanf(data, "req %d", &slot); if(me != NULL && me->id == slot) { sprintf(buffer, "omg nak %d", slot); send_msg(buffer); } else { sprintf(buffer, "omg hai %d %f %f %f", me->id, me->pos.x, me->pos.y, me->angle); send_msg(buffer); } } else if(CMD("mov")) { int id; sscanf(data, "mov %d", &id); Player * p = get_or_create_plajur(id); if(p != NULL) { sscanf(data, "mov %d %f %f %f %d %f %f %f",&id, &p->pos.x, &p->pos.y, &p->angle, (int*)&p->current_base_texture, &p->velocity.x, &p->velocity.y, &p->da); } } else if(CMD("hai")) { int id; sscanf(data, "hai %d", &id); Player * p = get_or_create_plajur(id); if(p != NULL) { sscanf(data, "hai %d %f %f %f",&id, &p->pos.x, &p->pos.y, &p->angle); } } else if(CMD("rot")) { int id; sscanf(data, "rot %d", &id); Player * p = get_or_create_plajur(id); if(p != NULL) { sscanf(data, "rot %d %f %f",&id, &p->angle, &p->da); } } else if(CMD("fir")) { int id; sscanf(data, "fir %d", &id); Player * p = get_or_create_plajur(id); if(id != me->id && id < NUM_PLAYERS) { p->fire = true; } } else if(CMD("nof")) { int id; sscanf(data, "nof %d", &id); Player * p = players[id]; if(id != me->id && p!=NULL) { p->fire = false; } } else if(CMD("kil")) { int id; sscanf(data, "kil %d", &id); Player * p = players[id]; if(p!=NULL) { p->dead = 1; } } break; } } else { buffer[size] = 0; fprintf(stderr,"Recieved invalid data: %s\n", buffer); } } //Check if the slot request has time out (aka succeded) if(request_sent_time+0.5 < curtime() && state == STATE_REQUESTED) { ready = true; me = create_player(myname, requested_slot); state = STATE_PLAYING; } }
void debugTestMalloc() { logWrite("Testing memory allocation"); float startTime; logDisableDebugOutput = true; void* ptrs[TEST_ALLOCATIONS_IN_CYCLE]; for (int j = 0; j < TEST_ALLOCATION_CYCLES; j++) { logWrite("Memory alloc/free cycle %d, peak usage %d bytes",j,mem.malloc_max); startTime = curtime(); for (int i = 0; i < TEST_ALLOCATIONS_IN_CYCLE; i++) { ptrs[i] = mem.alloc(TEST_ALLOCATION_CYCLE_SIZE); if (!ptrs[i]) { logError("Memory test failed: null block returned"); return; } } for (int i = 0; i < TEST_ALLOCATIONS_IN_CYCLE; i++) mem.free(ptrs[i]); logWrite("Cycle time %.5f seconds",curtime() - startTime); } logWrite("Allocating large memory chunk (%d mb)",TEST_ALLOC_LARGE_CHUNK_MB); startTime = curtime(); void* largePtr = mem.alloc(TEST_ALLOC_LARGE_CHUNK_MB*1024*1024); logWrite("Done, %.5f seconds",curtime() - startTime); if (!largePtr) { logError("Could not allocate large memory chunk"); } logWrite("Filling with pattern..."); startTime = curtime(); for (int i = 0; i < TEST_ALLOC_LARGE_CHUNK_MB*1024*1024; i++) { ((char*)largePtr)[i] = (i ^ 0xFF) & 0xFF; } logWrite("Done, %.5f seconds",curtime() - startTime); mem.free(largePtr); logWrite("Testing string pool..."); for (int i = 0; i < TEST_ALLOCATE_NUM_STRINGS; i++) { int strSize = Random.Int(1,TEST_ALLOCATE_MAX_STR_SIZE); char* strPtr = mem.alloc_string(strSize); if (mem.malloc_memory > 256*1024*1024) { logWrite("Too much memory used, terminating earlier with %d strings",i+1); break; } for (int j = 0; j < strSize; j++) strPtr[j] = (i ^ j) & 0xFF; } int stringpool_size = 0; int stringpool_used = 0; int stringpool_lost = 0; for (int i = 0; i <= mem.malloc_curstringpool; i++) { stringpool_size += mem.malloc_stringpoolsz[i]; stringpool_used += mem.malloc_curstringpoolsz[i]; stringpool_lost += mem.malloc_stringpoolsz[i] - mem.malloc_curstringpoolsz[i]; if ((mem.malloc_stringpoolsz[i] <= 0) || (mem.malloc_stringpoolsz[i] > 16384) || (mem.malloc_curstringpoolsz[i] <= 0) || (mem.malloc_curstringpoolsz[i] > 16384)) { logError("Memory test failed: corrupted string pool block %d",i); return; } } logWrite("String pool usage: %d out of %d bytes (%.2f percent, lost %d bytes, %d entries used)", stringpool_used,stringpool_size,(100.0f*stringpool_used) / stringpool_size,stringpool_lost,mem.malloc_curstringpool+1); logWrite("Testing boundary overflow detection"); char* testPtr = (char*)mem.alloc(512); testPtr[600] = 0x10; mem.free(testPtr); logWrite("Reinitializing memory (and console variables, they are in mem too)..."); logWrite("You should see warning about memory leak"); Convar.Deinitialize(); Memory.Deinitialize(); logDisableDebugOutput = false; Memory.Initialize(); Convar.Initialize(); logWrite("Memory allocation test passed!\n"); }