예제 #1
0
void Step::
        finishTask(Step::ptr step, int taskid, pBuffer result)
{
    Interval result_interval;
    if (result)
        result_interval = result->getInterval ();

    TASKINFO TaskInfo ti(format("Step::finishTask %2% on %1%")
              % step.raw ()->operation_name()
              % result_interval);

    if (result) {
        // Result must have the same number of channels and sample rate as previous cache.
        // Call deprecateCache(Interval::Interval_ALL) to erase the cache when chainging number of channels or sample rate.
        step.raw ()->cache_->put (result);
    }

    auto self = step.write ();
    int matched_task = self->running_tasks.count (taskid);
    if (1 != matched_task) {
        Log("C = %d, taskid = %x on %s") % matched_task % taskid % self->operation_name ();
        EXCEPTION_ASSERT_EQUALS( 1, matched_task );
    }

    Intervals expected_output = self->running_tasks[ taskid ];

    Intervals update_miss = expected_output - result_interval;
    self->not_started_ |= update_miss;

    if (!result) {
        TASKINFO TaskInfo(format("The task was cancelled. Restoring %1% for %2%")
                 % update_miss
                 % self->operation_name());
    } else {
        if (update_miss) {
            TaskInfo(format("These samples were supposed to be updated by the task but missed: %1% by %2%")
                     % update_miss
                     % self->operation_name());
        }
        if (result_interval - expected_output) {
            // These samples were not supposed to be updated by the task but were calculated anyway
            TaskInfo(format("Unexpected extras: %1% = (%2%) - (%3%) from %4%")
                     % (result_interval - expected_output)
                     % result_interval
                     % expected_output
                     % self->operation_name());

            // The samples are still marked as invalid. Would need to remove the
            // extra calculated samples from not_started_ but that would fail
            // in a situation where deprecatedCache is called after the task has
            // been created. So not_started_ can't be modified here (unless calls
            // to deprecatedCache were tracked).
        }
    }

    self->running_tasks.erase ( taskid );
    self.unlock ();

    step.raw ()->wait_for_tasks_.notify_all ();
}
예제 #2
0
void Step::
        test()
{
    // It should keep a cache for a signal processing step (defined by an OpertionDesc).
    //
    // The cache description should contain information about what's out_of_date
    // and what's currently being updated.
    {
        // Create an OperationDesc
        pBuffer b(new Buffer(Interval(60,70), 40, 7));
        for (unsigned c=0; c<b->number_of_channels (); ++c)
        {
            float *p = b->getChannel (c)->waveform_data ()->getCpuMemory ();
            for (int i=0; i<b->number_of_samples (); ++i)
                p[i] = c + 1+i/(float)b->number_of_samples ();
        }

        // Create a Step
        Step::ptr s2( new Step(OperationDesc::ptr()));

        shared_state<Step>::weak_ptr ws = s2;
        Step::ptr s = ws.lock ();

        // It should contain information about what's out_of_date and what's currently being updated.
        int taskid = s->registerTask(b->getInterval ());
        EXCEPTION_ASSERT_EQUALS(s->not_started (), ~Intervals(b->getInterval ()));
        EXCEPTION_ASSERT_EQUALS(s->out_of_date(), Intervals::Intervals_ALL);
        Step::finishTask(s, taskid, b);
        EXCEPTION_ASSERT_EQUALS(s->out_of_date(), ~Intervals(b->getInterval ()));

        EXCEPTION_ASSERT( *b == *Step::readFixedLengthFromCache (s, b->getInterval ()) );
    }

    // A crashed signal processing step should behave as a transparent operation.
    {
        OperationDesc::ptr silence(new Signal::OperationSetSilent(Signal::Interval(2,3)));
        Step s(silence);
        EXCEPTION_ASSERT(!s.get_crashed ());
        EXCEPTION_ASSERT(s.operation_desc ());
        EXCEPTION_ASSERT(s.operation_desc ().read ()->createOperation (0));
        EXCEPTION_ASSERT(!dynamic_cast<Test::TransparentOperationDesc*>(s.operation_desc ().raw ()));
        EXCEPTION_ASSERT(!dynamic_cast<Test::TransparentOperation*>(s.operation_desc ().read ()->createOperation (0).get ()));
        s.mark_as_crashed_and_get_invalidator ();
        EXCEPTION_ASSERT(s.get_crashed ());
        EXCEPTION_ASSERT(s.operation_desc ());
        EXCEPTION_ASSERT(s.operation_desc ().read ()->createOperation (0));
        EXCEPTION_ASSERT(dynamic_cast<Test::TransparentOperationDesc*>(s.operation_desc ().raw ()));
        EXCEPTION_ASSERT(dynamic_cast<Test::TransparentOperation*>(s.operation_desc ().read ()->createOperation (0).get ()));
    }
}
예제 #3
0
void GraphInvalidator::
        deprecateCache(const Dag& dag, Step::ptr step, Signal::Intervals what)
{
    // Invalidate the source first
    what = step.write ()->deprecateCache(what);

    // Invalidate the targets afterwards
    // Otherwise the scheduler might start working on data that isn't ready yet
    for (Step::ptr ts: dag.targetSteps(step))
        deprecateCache(dag, ts, what);
}