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;
}
Esempio n. 2
0
/* 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));
}
Esempio n. 3
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);
}