Esempio n. 1
0
DEFINEFN
void psyco_profile_threads(int start)
{
	PyInterpreterState* istate;
	PyThreadState* tstate;
	
	if (!profile_function)
		return;
	istate = PyThreadState_Get()->interp;
	for (tstate=istate->tstate_head; tstate; tstate=tstate->next) {
		ceval_events_t* cev;
		if (!measuring_state(tstate))
			continue;
		cev = get_cevents(tstate);
		if (start == !cev->current_hook) {
			stats_printf(("stats: %s hooks on thread %p\n",
				      start?"adding":"removing", tstate));
			profile_function(cev, start);
			if (!update_ceval_hooks(cev) && start) {
				/* cannot start, stop again */
				profile_function(cev, 0);
			}
		}
	}
}
Esempio n. 2
0
DEFINEFN
void psyco_stats_append(PyThreadState* tstate, PyFrameObject* f)
{
	double charge;
	float cs_charge;
	int bits;
	time_measure_t numticks;

	if (!measuring_state(tstate))
		return;
	numticks = get_measure(tstate);
	if (measure_is_zero(numticks) || f == NULL)
		return;  /* f==NULL must still make a get_measure() call */
	charge = ((double) charge_unit) * numticks;
	
	bits = c_random();
	while (1) {
		PyCodeStats* cs = PyCodeStats_Get(f->f_code);
		cs_charge = (float)(cs->st_charge + charge);
		cs->st_charge = cs_charge;
		charge_total += charge;
		if (cs_charge > charge_prelimit && charge_callback) {
			/* update charge_prelimit */
			charge_prelimit = (float)(charge_total * charge_watermark);
			if (cs_charge > charge_prelimit) {
				/* still over the up-to-date limit */
				cs->st_charge = 0.0f;
				break;
			}
		}
		if (bits >= 0)
			return;  /* triggers in about 50% of the cases */
		bits <<= 1;
		f = f->f_back;
		if (!f)
			return;
		charge *= charge_parent2;
	}

	/* charge limit reached, invoke callback */
	{
		PyObject* r;
		r = PyObject_CallFunction(charge_callback, "Of", f, cs_charge);
		if (r == NULL) {
			PyErr_WriteUnraisable((PyObject*) f);
		}
		else {
			Py_DECREF(r);
		}
	}
}