Esempio n. 1
0
static void delay_delta(PERF_RTdata_delay *dDelay, PERF_Private *perf)
{
    if (dDelay->n < 0)
    {
        dDelay->n++;
    }
    else
    {
        delay_add(dDelay, TIME_DELTA(perf->time, dDelay->last_timestamp));
    }
    TIME_COPY(dDelay->last_timestamp, perf->time);
}
Esempio n. 2
0
static rlm_rcode_t CC_HINT(nonnull) mod_delay(void *instance, UNUSED void *thread, REQUEST *request)
{
	rlm_delay_t const	*inst = instance;
	struct timeval		delay, resume_at, *yielded_at;

	if (inst->delay) {
		if (tmpl_aexpand(request, &delay, request, inst->delay, NULL, NULL) < 0) return RLM_MODULE_FAIL;
	} else {
		memset(&delay, 0, sizeof(delay));
	}

	/*
	 *	Record the time that we yielded the request
	 */
	MEM(yielded_at = talloc(request, struct timeval));
	if (gettimeofday(yielded_at, NULL) < 0) {
		REDEBUG("Failed getting current time: %s", fr_syserror(errno));
		return RLM_MODULE_FAIL;
	}

	/*
	 *	Setup the delay for this request
	 */
	if (delay_add(request, &resume_at, yielded_at, &delay, inst->force_reschedule, inst->delay) != 0) {
		return RLM_MODULE_NOOP;
	}

	RDEBUG3("Current time %pV, resume time %pV", fr_box_timeval(*yielded_at), fr_box_timeval(resume_at));

	if (unlang_event_module_timeout_add(request, _delay_done, yielded_at, &resume_at) < 0) {
		RPEDEBUG("Adding event failed");
		return RLM_MODULE_FAIL;
	}

	return unlang_module_yield(request, mod_delay_return, mod_delay_cancel, yielded_at);
}
Esempio n. 3
0
void __rt_Buffer(PERF_Private *perf,
                 unsigned long ulAddress1,
                 unsigned long ulAddress2,
                 unsigned long ulSize,
                 PERF_MODULETYPE eModuleAndFlags)
{
    /* get real-time private structure */
    PERF_RT_Private *me = perf->cip.pRT;

    /* see if we care about this buffer in the rate calculation */
    unsigned long module = eModuleAndFlags & PERF_ModuleMask;

    /* ------------------------ RATE METRICS ------------------------ */

    /* change HLMM to LLMM for detailed = 0 and 1 */
    if (me->detailed < 2 && module == PERF_ModuleHLMM)
    {
        module = PERF_ModuleLLMM;
    }

    int rate = (me->detailed == 2) ||
               (me->detailed == 0 &&
                (eModuleAndFlags == me->only_moduleandflags && ulSize >= 8)) ||
               (me->detailed == 1 &&
                ((module == PERF_ModuleHardware || module == PERF_ModuleLLMM)));

    if (rate && me->dRate && (!me->needSteadyState || me->steadyState))
    {
        /* change encoded filled frame sizes to 0xBEEFED, as they tend to
           have varying sizes and thus not be counted */
        unsigned long sending = PERF_GetXferSendRecv(eModuleAndFlags);
        unsigned long size = ulSize;
        if ((me->encoder || me->decoder) && !PERF_IsXfering(sending))
        {
            /* reverse sending direction to common layer or socket node */
            if (module >= PERF_ModuleCommonLayer &&
                    module <= PERF_ModuleSocketNode)
            {
                sending ^= PERF_FlagSending;
            }

            if ((me->encoder && (sending == PERF_FlagSending)) ||
                    (me->decoder && (sending == PERF_FlagReceived)))
            {
                size = size ? 0xBEEFED : 0;
            }
        }

        /* see if we are tracking this buffer size */
        int i, j = -1;  /* j is one of the lest used indexes */
        for (i=0; i < me->nDRate; i++)
        {
            if (me->dRate[i].modulesAndFlags == eModuleAndFlags &&
                    me->dRate[i].size == size) break;
            if (j < 0 || me->dRate[i].n < me->dRate[j].n)
            {
                j = i;
            }
        }

        /* if we are not yet tracking this buffer, see if we can track
           it. */
        if (i == me->nDRate)
        {
            /* we have space to track it */
            if (i < me->maxDRate)
            {
                me->nDRate++;
            }
            /* if we cannot replace another rate, we don't track it */
            else if (j < 0 || me->dRate[j].n < 2)
            {
                i = me->maxDRate;
            }
            else
            {
                i = j;
            }

            /* start tracking */
            if (i < me->maxDRate)
            {
                me->dRate[i].modulesAndFlags = eModuleAndFlags;
                me->dRate[i].size = size;
                me->dRate[i].xx = me->dRate[i].x = me->dRate[i].n = 0;
                me->dRate[i].txx = me->dRate[i].tx = me->dRate[i].tn = me->dRate[i].tn0 = 0;
                me->dRate[i].axx = me->dRate[i].ax = me->dRate[i].an = 0;
                me->dRate[i].skip = me->needSteadyState ? 0 : 4;
                TIME_COPY(me->dRate[i].last_timestamp, perf->time);
                TIME_COPY(me->dRate[i].last_reporting, perf->time);
            }
        }
        else
        {
            if (me->dRate[i].skip == 0)
            {
                /* see if we passed our granularity */
                int steps = TIME_DELTA(perf->time, me->dRate[i].last_reporting);
                if (steps >= me->granularity)
                {
                    steps /= me->granularity;

                    /* unless debug bit 4 is set, ignore temporal statistics if
                       we passed the last time by more than a second, and less than
                       the minimul frames were processed in this burst so far, and
                       the last fps was less than 1. */
                    if (!(me->debug & 4) &&
                            (me->dRate[i].tn0 < MIN_FRAMES_FOR_RATE) &&
                            (me->dRate[i].tn < me->granularity * steps))
                    {
                        if (me->debug & 256)
                        {
                            fprintf(me->fRt, "rtPERF: [%ld] IGNORED (steps=%d, tn0=%ld, tn=%ld)\n",
                                    TIME_DELTA(me->dRate[i].last_reporting, me->first_time)/1000000,
                                    steps, me->dRate[i].tn0, me->dRate[i].tn);
                        }
                        me->dRate[i].txx = me->dRate[i].tx = me->dRate[i].tn = me->dRate[i].tn0 = 0;

                        TIME_INCREASE(me->dRate[i].last_reporting, me->granularity * steps);
                        steps = 0;
                    }
                    else if (me->debug & 256)
                    {
                        fprintf(me->fRt, "rtPERF: [%ld] not-ignored (steps=%d, tn0=%ld, tn=%ld)\n",
                                TIME_DELTA(me->dRate[i].last_reporting, me->first_time)/1000000,
                                steps, me->dRate[i].tn0, me->dRate[i].tn);
                    }

                    /* see if we surpassed our granularity.  if yes, calculate
                       temporal statistics */
                    while (steps)
                    {
                        /* count temporal rate */
                        count_temporal_rate(perf->ulID, me, me->dRate + i);

                        TIME_INCREASE(me->dRate[i].last_reporting, me->granularity);
                        steps--;
                    }
                }

                /* rate is */
                unsigned long delta = TIME_DELTA(perf->time, me->dRate[i].last_timestamp);
                me->dRate[i].x   += delta;
                me->dRate[i].tx  += delta;
                me->dRate[i].xx  += delta * (double) delta;
                me->dRate[i].txx += delta * (double) delta;
                me->dRate[i].n   ++;
                me->dRate[i].tn  ++;
                me->dRate[i].tn0 ++;
            }
            else
            {
                me->dRate[i].skip--;
                if (me->dRate[i].skip == 0)
                {
                    TIME_COPY(me->dRate[i].last_reporting, perf->time);
                    me->dRate[i].txx = me->dRate[i].tx = me->dRate[i].tn = 0;
                }
            }

            TIME_COPY(me->dRate[i].last_timestamp, perf->time);
        }
    }

    /* ------------------------ SHOT-TO-SHOT METRICS ------------------------ */
    if (me->dSTS)
    {
        if (eModuleAndFlags == (PERF_FlagSending | PERF_FlagFrame | PERF_ModuleHardware))
        {
            /* queueing buffers to camera */

            /* see if resolution has changed */
            if (ulSize < me->dSTS->size_min ||
                    ulSize > me->dSTS->size_max)
            {
                /* report burst rate if we have any */
                if (me->debug)
                {
                    if (me->dSTS->dBurst2.n > 0)
                    {
                        count_delay(me, "Modified burst shot-to-shot", &me->dSTS->dBurst2, 0);
                    }
                    if (me->dSTS->dBurst.n > 0)
                    {
                        count_delay(me, "Raw burst shot-to-shot", &me->dSTS->dBurst, -1);
                    }
                }

                me->dSTS->dBurst.n = -1;
                me->dSTS->dBurst2.n = 0;

                /* set new size */
                me->dSTS->size_min = ulSize > 2048 ? ulSize - 2048 : 0;
                me->dSTS->size_max = ulSize;

                /* if more than D1-PAL, we assume it is an image, not a preview */
                if (ulSize > 0x119000)
                {
                    /* new burst mode start */
                    me->dSTS->capturing = 1;
                }
                else
                {
                    /* preview start */
                    me->dSTS->capturing = 0;
                }
            }
        }
        else if (eModuleAndFlags == (PERF_FlagReceived | PERF_FlagFrame | PERF_ModuleHardware))
        {
            /* gotten buffers from camera */
            if (me->dSTS->capturing &&
                    ulSize >= me->dSTS->size_min &&
                    ulSize <= me->dSTS->size_max)
            {
                /* see if we have a capture already (we ignore the first) to
                   count into the modified capture */
                if (me->dSTS->dBurst.n > 1)
                {
                    /* count last time delta */
                    if (me->dSTS->dBurst.n > 2)
                    {
                        delay_add(&me->dSTS->dBurst2, me->dSTS->last_burst);
                        delay_add(&me->dSTS->dABurst2, me->dSTS->last_burst);
                        if (me->debug)
                        {
                            fprintf(me->fRt, "rtPERF: [%ld] Modified burst shot-to-shot[0x%lX]: %.3g s\n",
                                    me->dSTS->dBurst2.n, me->dSTS->size_min, 1e-6 * me->dSTS->last_burst);
                        }
                    }
                    me->dSTS->last_burst = TIME_DELTA(perf->time, me->dSTS->dBurst.last_timestamp);
                }
                else if (me->dSTS->dBurst.n < 0)
                {
                    /* if this is the first shot in the burst sequence */
                    /* calculate single shot-to-shot delay */
                    if (me->dSTS->dSingle.n >= 0)
                    {
                        if (me->debug)
                        {
                            fprintf(me->fRt, "rtPERF: [#%ld] Single shot-to-shot[0x%lX]: %.3g s\n",
                                    me->dSTS->dSingle.n + 1, me->dSTS->size_min, 1e-6 * TIME_DELTA(perf->time, me->dSTS->dSingle.last_timestamp));
                        }
                        delay_delta(&me->dSTS->dSingle, perf);
                    }
                }

                if (me->dSTS->dBurst.n >= 0)
                {
                    if (me->debug)
                    {
                        fprintf(me->fRt, "rtPERF: [#%ld] Raw burst shot-to-shot[0x%lX]: %.3g s\n",
                                me->dSTS->dBurst.n + 1, me->dSTS->size_min, 1e-6 * TIME_DELTA(perf->time, me->dSTS->dBurst.last_timestamp));
                    }
                    delay_add(&me->dSTS->dABurst, TIME_DELTA(perf->time, me->dSTS->dBurst.last_timestamp));
                }
                delay_delta(&me->dSTS->dBurst, perf);

                /* keep last captured image time stamp for single shot-to-shot */
                TIME_COPY(me->dSTS->dSingle.last_timestamp, perf->time);
                if (me->dSTS->dSingle.n < 0)
                {
                    me->dSTS->dSingle.n = 0;  /* captured first time stamp */
                }
            }
        }
    }

    /* ------------------------ UPTIME METRICS ------------------------ */
    if (0 && me->dUptime && me->dUptime->measuring)
    {
        /* see if we passed our granularity.  if yes, calculate uptime */
        int steps = TIME_DELTA(perf->time, me->dUptime->last_reporting);
        if (steps >= me->granularity)
        {
            steps /= me->granularity;

            double uptime, idletime, load = 0;

            /* calculate MHz load */
            get_uptime(&uptime, &idletime);
            if (uptime > 0 && me->dUptime->success)
            {
                me->dUptime->last_idletime = idletime - me->dUptime->last_idletime;
                me->dUptime->last_uptime = uptime - me->dUptime->last_uptime;
                if (me->dUptime->last_uptime > 0)
                {
                    load = 100. * ((me->dUptime->last_uptime - me->dUptime->last_idletime) /
                                   me->dUptime->last_uptime);

                    me->dUptime->n += steps;
                    me->dUptime->x += load * steps;
                    me->dUptime->xx += load * load * steps;
                }
            }

            TIME_INCREASE(me->dUptime->last_reporting, steps * me->granularity);

            if (uptime > 0 && me->dUptime->success)
            {
                me->dUptime->last_uptime = uptime;
                me->dUptime->last_idletime = idletime;
                if (me->debug)
                {
                    fprintf(me->fRt, "rtPERF: [%ld] ARM CPU-load is %.3g%%\n",
                            TIME_DELTA(perf->time, me->first_time)/1000000,
                            load);
                }
            }
            else
            {
                me->dUptime->success = 0;
            }
        }
    }
}
Esempio n. 4
0
static xlat_action_t xlat_delay(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out,
				REQUEST *request, void const *xlat_inst, UNUSED void *xlat_thread_inst,
				fr_value_box_t **in)
{
	rlm_delay_t const	*inst;
	void			*instance;
	struct timeval		resume_at, delay, *yielded_at;

	memcpy(&instance, xlat_inst, sizeof(instance));	/* Stupid const issues */

	inst = talloc_get_type_abort(instance, rlm_delay_t);

	/*
	 *	Record the time that we yielded the request
	 */
	MEM(yielded_at = talloc(request, struct timeval));
	if (gettimeofday(yielded_at, NULL) < 0) {
		REDEBUG("Failed getting current time: %s", fr_syserror(errno));
		return XLAT_ACTION_FAIL;
	}

	/*
	 *	If there's no input delay, just yield and
	 *	immediately re-enqueue the request.
	 *	This is very useful for testing.
	 */
	if (!*in) {
		memset(&delay, 0, sizeof(delay));
		if (!fr_cond_assert(delay_add(request, &resume_at, yielded_at, &delay, true, true) == 0)) {
			return XLAT_ACTION_FAIL;
		}
		goto yield;
	}

	if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
		RPEDEBUG("Failed concatenating input");
		talloc_free(yielded_at);
		return XLAT_ACTION_FAIL;
	}

	if (fr_timeval_from_str(&delay, (*in)->vb_strvalue) < 0) {
		RPEDEBUG("Failed parsing delay time");
		talloc_free(yielded_at);
		return XLAT_ACTION_FAIL;
	}

	if (delay_add(request, &resume_at, yielded_at, &delay, inst->force_reschedule, inst->relative) != 0) {
		RDEBUG2("Not adding delay");
		talloc_free(yielded_at);
		return XLAT_ACTION_DONE;
	}

yield:
	RDEBUG3("Current time %pV, resume time %pV", fr_box_timeval(*yielded_at), fr_box_timeval(resume_at));

	if (unlang_xlat_event_timeout_add(request, _delay_done, yielded_at, &resume_at) < 0) {
		RPEDEBUG("Adding event failed");
		return XLAT_ACTION_FAIL;
	}

	return unlang_xlat_yield(request, xlat_delay_resume, xlat_delay_cancel, yielded_at);
}