Ejemplo n.º 1
0
int name(int &mySum, Futex& f)
{
    while (true) {
        f.lock();
        if (ans >= MAX_ANS){
            f.unlock();
            break;
        }
        ++ans;
        ++mySum;
        f.unlock();
    }
    return 0;
}
Ejemplo n.º 2
0
void worker(int threadId,
            int targ_max,
            int &target,
            vector<int> &incrementsCounter,
            Futex &futex) {
    while(true) {
        futex.lock(threadId);
        if (target < targ_max) {
            target++;
            incrementsCounter[threadId]++;
            futex.unlock(threadId);
        } else {
            futex.unlock(threadId);
            break;
        }
    }
}
Ejemplo n.º 3
0
/**
 * @brief main will load test Futex miplementation
 *
 * it starts two threads: one producer and one consumer
 * Consumer will dequeue "work" from lock free queue and process it. If queue is
 * empty - consumer will call Futex::wait() to sleep on futex.
 *
 * Producer will batch create some "work" in lock free queue and Futex::notify(),
 * then wait for queue will become empty (trying to catch point when consumer
 * change from working mode to sleep mode), then enqueue some more work and
 * call Futex::notify() to wake up consumer. After that it checks that queue will
 * be processed by consumer (was it sleeping or going to sleep at notify()).
 * Producer and Consumer is running on different OS threads.
 *
 * The aim of this test is to check, that notify will always work (whether consumer waiting()
 * or not)
 *
 * @return 0 on success
 */
int main()
{
    std::cout << "main started\n";
    TestLockFreeQueue queue;
    Futex futex;
    std::cout << "main will create producers\n";
    std::thread producer1{producer_function, std::ref(futex), std::ref(queue)};
    std::cout << "main will create consumers\n";
    std::thread consumer1{consumer_function, std::ref(futex), std::ref(queue)};
    std::cout << "main will sleep\n";
    sleep( 100 );
    std::cout << "main will notify\n";
    stop_requested = true;
    futex.notify_all();
    std::cout << "main will join consumer\n";
    consumer1.join();
    std::cout << "main will join producers\n";
    producer1.join();
    std::cout << "main will finish\n";
    return 0;
}
Ejemplo n.º 4
0
void run(int thr_num=10, int targ_max=2*(1e7), bool print=true) {
    int target = 0;
    vector<int> incrementsCounter(thr_num, 0);
    vector<thread> threads;
    Futex futex;
    futex.initOwner();
    
    for (int i = 0; i < thr_num; ++i) {
        threads.push_back(thread(worker,
                                 i,
                                 targ_max,
                                 ref(target),
                                 ref(incrementsCounter),
                                 ref(futex)));
    }
    
    joinAll(threads);
    
    int incrementsSum = 0;
    
    for (int i = 0; i < thr_num; ++i) {
        if (print) {
            cout << "thread " << i << ": "
            << incrementsCounter[i] << " increments" << endl;
        }
        incrementsSum += incrementsCounter[i];
    }
    
    assert(target == incrementsSum && target == targ_max);
    
    if (print) {
        cout << "target: " << target << endl;
        cout << "incsum: " << incrementsSum << endl;
        cout << "wanted: " << targ_max << endl
        << "-------------------------------" << endl;
    }
}
Ejemplo n.º 5
0
void consumer_function( Futex& futex, TestLockFreeQueue& queue )
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET( 1, &cpuset);
    if( pthread_setaffinity_np(
                pthread_self(), sizeof(cpu_set_t), &cpuset) < 0 )
    {
        printf("error pthread_setaffinity_np() to 1's CPU, %s", strerror(errno));
        exit( EXIT_FAILURE );
    }
    std::cout << "consumer started\n";
    uint32_t q_value;
    while( !stop_requested )
    {
        if( (q_value = queue.dequeue()) == 0 )
        {
            futex.wait();
            continue;
        }
    }
}
Ejemplo n.º 6
0
void run_basic_thread(
    Futex<Atom>& f) {
  EXPECT_TRUE(f.futexWait(0));
}
Ejemplo n.º 7
0
void producer_function( Futex& futex, TestLockFreeQueue& queue )
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(0, &cpuset);
    if( pthread_setaffinity_np(
                pthread_self(), sizeof(cpu_set_t), &cpuset) < 0 )
    {
        printf("error pthread_setaffinity_np() to 0's CPU, %s", strerror(errno));
        exit( EXIT_FAILURE );
    }
    std::cout << "producer started\n";

    uint32_t q_value;
    while( !stop_requested )
    {
        if( (q_value = queue.enqueue(batch_size)) == 0 )
        {
            std::cout << "producer got 0 (queue is full)\n";
            usleep(100000);
            continue;
        }
        // std::cout << q_value << " after batch enqueue\n";
        futex.notify();
        usleep(1);
        uint32_t i = 0;
        while( !stop_requested && queue.enqueue() != 1 )
        {
            usleep(1);
            ++i;
        }
        futex.notify();
        if( i == 1 ) // increase batch_size if exhausted too quick
        {
            batch_size *= 2;
            std::cout << "New batch_size " << batch_size << std::endl;
        }
        if( i > 20 ) // decrease batch_size if it's too big
        {
            batch_size /= 2;
            std::cout << "New batch_size " << batch_size << std::endl;
        }
        while( (q_value = queue.enqueue(0) ) != 0 )
        {   // some data remain after last notify
            // consumer will wake up and exhaust it
            // if not - it's stalled
            for( int i = 0; i < 1000; ++i)
            {
                usleep(1);
                if( (q_value = queue.enqueue(0)) == 0 )
                    break;
            }
            if( q_value == 0 )
                break;
            if( stop_requested )
                break;
            std::cout << "after 1000 mks delay current q_value " << q_value << std::endl;
            usleep(100000);
        }
        // std::cout << i << " enqueue iterations for " << batch_size << " batch_size\n";
    }
}
Ejemplo n.º 8
0
void run_basic_thread(
    Futex<Atom>& f) {
  EXPECT_EQ(FutexResult::AWOKEN, f.futexWait(0));
}