void ConcurrencyTest::execute()
{

    Obj *mX = d_collector_p; const Obj *MX = mX;

    balm::MetricRecord empty(MX->metricId());
    balm::MetricRecord r1(MX->metricId(), 1, 2, 3, 5);
    balm::MetricRecord r2(MX->metricId(), 7, 8, 9, 10);

    // Test simultaneous set and loads, verify values are set/loaded
    // atomically.
    d_barrier.wait();
    for(int i = 0; i < 10; ++i) {
        balm::MetricRecord  result;
        balm::MetricRecord *rec = (0 == i % 2) ? &r1 : &r2;
        mX->setCountTotalMinMax(rec->count(),
                                rec->total(),
                                rec->min(),
                                rec->max());
        MX->load(&result);
        ASSERT(r1 == result || r2 == result);

    }
    d_barrier.wait();

    mX->reset();

    // Test simultaneous accumulate and loads, verify values are
    // accumulated/loaded atomically.
    d_barrier.wait();
    for(int i = 0; i < 10; ++i) {
        balm::MetricRecord  result;
        mX->accumulateCountTotalMinMax(1, 1, -i, i);
        MX->load(&result);

        ASSERT(result.count() >= i);
        ASSERT(result.total() >= i);
        ASSERT(result.count() == result.total());
        ASSERT(result.min() <= -i);
        ASSERT(result.max() >= i);
        ASSERT(result.min() == -result.max());
    }
    d_barrier.wait();

    mX->reset();

    // Test simultaneous set and loadAndReset, verify values are loaded and
    // reset atomically.
    d_barrier.wait();
    for(int i = 0; i < 10; ++i) {
        balm::MetricRecord  result;
        mX->setCountTotalMinMax(r1.count(), r1.total(), r1.min(), r1.max());
        mX->loadAndReset(&result);

        ASSERT(result == r1 || result == empty);
    }
    d_barrier.wait();
}
 void
 check_remove ()
   {
     reg_->forget (o2);
     
     Iter13 i (reg_->candidates(q4));
     CHECK ( i.hasNext());
     CHECK ( *i == o1); ++i;    // ordered according to the degree of the queries
                                // but the o2 entries are missing
     CHECK ( *i == o3); ++i;
                                // o2 missing
                                // o2 missing
     CHECK ( *i == o1);
     CHECK (!i.hasNext());
     
     o3.reset(); // killing the only reference....
                //  expires the weak ref in the registry
     
     i = reg_->candidates(Q13 ("something"));
     CHECK ( i.hasNext());
     CHECK ( *i == o1); ++i;    // ordered according to the degree of the queries
                                // but now also the o3 entry is missing...
     CHECK ( *i == o1);
     CHECK (!i.hasNext());
     
     CHECK ( reg_->put (o1, q5));   // trying to register the same object at the same place
                                    // doesn't change anything (but counts as "success")
     i = reg_->candidates(q5);
     CHECK ( *i == o1); ++i; // direct match
     CHECK ( *i == o1); ++i;
     CHECK ( *i == o1); ++i;
     CHECK (!i.hasNext());
     
     CHECK (!reg_->put (o2, q5));   // trying to (re)register o2 with a existing query
                                    // counts as failure (nothing changes)
     i = reg_->candidates(q5);
     CHECK ( *i == o1); ++i; // direct match
     CHECK ( *i == o1); ++i;
     CHECK ( *i == o1); ++i;
     CHECK (!i.hasNext());
     
     CHECK ( reg_->put (o2, q2));   // trying to (re)register o2 with another query succeeds
     i = reg_->candidates(q2);
     CHECK ( *i == o2); ++i; // direct match
     CHECK ( *i == o1); ++i;
     CHECK ( *i == o2); ++i; // inserted here in the dataset, since q2 has degree 2
     CHECK ( *i == o1); ++i;
     CHECK (!i.hasNext());
     
     CHECK ( reg_->forget (o1));
     CHECK (!reg_->forget (o1)); // failure, because it's already removed
     CHECK ( reg_->forget (o2));
     
     o3 = fabricate<13>();    // another object is another object (it's irrelevant...)
     
     i = reg_->candidates(q2);
     CHECK (! (*i));  // empty
   }