Particle *ParticleManager::getFreeParticle(Emitter *emitter) { BBGE_PROF(ParticleManager_getFreeParticle); if (size == 0) return 0; Particle *p = 0; p = &particles[free]; if (p->active) { p = stomp(); } else { endParticle(p); p->index = free; nextFree(spread); } /* static int lpstep = 0; if (c > lpstep) lpstep = c; std::ostringstream os; os << "psteps: " << c << " largest: " << lpstep; debugLog(os.str()); */ /* p = &particles[free]; nextFree(); */ if (emitter) { p->emitter = emitter; emitter->addParticle(p); } return p; }
/* Try to stomp the tile under the sprite. */ void stompUnderSprite(uint8_t slot) { if (!(stomp(getSpriteTileX(slot,0),getSpriteTileY(slot,-8)))) stomp(getSpriteTileX(slot,0),getSpriteTileY(slot,0)); }
void pebs_init(int nRecords, uint64_t *counter, uint64_t *reset_val ){ // 1. Set up the precise event buffering utilities. // a. Place values in the // i. precise event buffer base, // ii. precise event index // iii. precise event absolute maximum, // iv. precise event interrupt threshold, // v. and precise event counter reset fields // of the DS buffer management area. // // 2. Enable PEBS. Set the Enable PEBS on PMC0 flag // (bit 0) in IA32_PEBS_ENABLE_MSR. // // 3. Set up the IA32_PMC0 performance counter and // IA32_PERFEVTSEL0 for an event listed in Table // 18-10. // IA32_DS_AREA points to 0x58 bytes of memory. // (11 entries * 8 bytes each = 88 bytes.) // Each PEBS record is 0xB0 byes long. int pagesize = getpagesize(); init_stomp(); // I think we can only have one mapping per process, so put the // pds_area on the first page and the pebs records on the second // and successive pages. pds_area = mmap( NULL, // let kernel choose address pagesize + (pagesize*(((sizeof(struct pebs)*nRecords)/pagesize)+1)), // keep ds and records separate. PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_LOCKED | MAP_PRIVATE, -1, // dummy file descriptor 0); // offset (ignored). if(pds_area == (void*)-1){ perror("mmap for pds_area failed."); assert(0); } struct pebs *ppebs = (struct pebs*) ( (uint64_t)pds_area + pagesize ); pds_area->bts_buffer_base = 0; pds_area->bts_index = 0; pds_area->bts_absolute_maximum = 0; pds_area->bts_interrupt_threshold = 0; pds_area->pebs_buffer_base = ppebs; pds_area->pebs_index = ppebs; pds_area->pebs_absolute_maximum = ppebs + (nRecords-1) * sizeof(struct pebs); pds_area->pebs_interrupt_threshold = ppebs + (nRecords+1) * sizeof(struct pebs); pds_area->pebs_counter0_reset = reset_val[0]; pds_area->pebs_counter1_reset = reset_val[1]; pds_area->pebs_counter2_reset = reset_val[2]; pds_area->pebs_counter3_reset = reset_val[3]; pds_area->reserved = 0; write_msr(0, PERF_GLOBAL_CTRL, 0); // known good state. write_msr(0, IA32_DS_AREA, (uint64_t)pds_area); write_msr(0, IA32_PEBS_ENABLE, 0xf | ((uint64_t)0xf << 32) ); // Figure 18-14. write_msr(0, PMC0, reset_val[0]); write_msr(1, PMC1, reset_val[1]); write_msr(2, PMC2, reset_val[2]); write_msr(3, PMC3, reset_val[3]); write_msr(0, IA32_PERFEVTSEL0, 0x410000 | counter[0]); write_msr(0, IA32_PERFEVTSEL1, 0x410000 | counter[1]); write_msr(0, IA32_PERFEVTSEL2, 0x410000 | counter[2]); write_msr(0, IA32_PERFEVTSEL3, 0x410000 | counter[3]); write_msr(0, PERF_GLOBAL_CTRL, 0xf); stomp(); write_msr(0, PERF_GLOBAL_CTRL, 0x0); }