void get_all()
{
    for (vector<ChannelGet::shared_pointer>::const_iterator i = channelGetList.begin();
         i != channelGetList.end();
         i++)
        (*i)->get();

    // we assume all channels are from the same provider
    if (bulkMode) provider->flush();
}
void runTest()
{
    reset();

    if (verbose)
        printf("%d channel(s) of double array size of %d element(s) (0==scalar), %d iteration(s) per run, %d run(s) (0==forever)\n", channels, arraySize, iterations, runs);

    /*
    StringArray fieldNames;
    fieldNames.push_back("strategy");
    FieldConstPtrArray fields;
    fields.push_back(getFieldCreate()->createScalar(pvInt));
    PVStructure::shared_pointer configuration =
        getPVDataCreate()->createPVStructure(getFieldCreate()->createStructure(fieldNames, fields));
    configuration->getIntField("strategy")->put(bulkMode ? USER_CONTROLED : DELAYED);
    provider->configure(configuration);
    */

    vector<string> channelNames;
    char buf[64];
    for (int i = 0; i < channels; i++)
    {
        if (arraySize > 0)
            sprintf(buf, "testArray%d_%d", arraySize, i);
        else
            sprintf(buf, "test%d", i);
        channelNames.push_back(buf);
    }

    vector<Channel::shared_pointer> channels;
    for (vector<string>::const_iterator i = channelNames.begin();
         i != channelNames.end();
         i++)
    {
        shared_ptr<ChannelRequesterImpl> channelRequesterImpl(
                        new ChannelRequesterImpl()
                    );
        Channel::shared_pointer channel = provider->createChannel(*i, channelRequesterImpl);
        channels.push_back(channel);
    }
    if (bulkMode) provider->flush();

    bool differentConnectionsWarningIssued = false;
    string theRemoteAddress;
    for (vector<Channel::shared_pointer>::iterator i = channels.begin();
         i != channels.end();
         i++)
    {
        Channel::shared_pointer channel = *i;
        shared_ptr<ChannelRequesterImpl> channelRequesterImpl =
                dynamic_pointer_cast<ChannelRequesterImpl>(channel->getChannelRequester());
        if (channelRequesterImpl->waitUntilConnected(5.0))
        {
            string remoteAddress = channel->getRemoteAddress();
            if (theRemoteAddress.empty())
            {
                theRemoteAddress = remoteAddress;
            }
            else if (theRemoteAddress != remoteAddress)
            {
                if (!differentConnectionsWarningIssued)
                {
                    std::cout << "not all channels are hosted by the same connection: " <<
                                 theRemoteAddress << " != " << remoteAddress << std::endl;
                    differentConnectionsWarningIssued = true;
                    // we assumes same connection (thread-safety)
                    exit(2);
                }
            }

            shared_ptr<ChannelGetRequesterImpl> getRequesterImpl(
                            new ChannelGetRequesterImpl(channel->getChannelName())
                        );
            ChannelGet::shared_pointer channelGet = channel->createChannelGet(getRequesterImpl, pvRequest);
            if (bulkMode) provider->flush();

            bool allOK = getRequesterImpl->waitUntilConnected(timeOut);

            if (!allOK)
            {
                std::cout << "[" << channel->getChannelName() << "] failed to get all the gets" << std::endl;
                exit(1);
            }

            channelGetList.push_back(channelGet);

        }
        else
        {
            std::cout << "[" << channel->getChannelName() << "] connection timeout" << std::endl;
            exit(1);
        }
    }
    if (verbose)
        std::cout << "all connected" << std::endl;

    {
        Lock guard(waitLoopPtrMutex);
        waitLoopEvent.reset(new Event());
    }
    epicsTimeGetCurrent(&startTime);
    get_all();
    
    waitLoopEvent->wait();
}