Skip to content

Instantly share code, notes, and snippets.

@greensea
Created September 22, 2015 07:40

Revisions

  1. greensea created this gist Sep 22, 2015.
    140 changes: 140 additions & 0 deletions context_switch_bench.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    #include <stdlib.h>
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <sys/eventfd.h>
    #include <sys/time.h>

    int g_loops = 0;
    int g_efd = 0;
    int g_stop = 0;

    pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

    void* consumer_cond(void* ptr) {
    pthread_mutex_lock(&cond_mutex);
    while (g_loops > 0) {
    g_loops--;
    pthread_cond_wait(&cond, &cond_mutex);
    }
    pthread_mutex_unlock(&cond_mutex);

    return NULL;
    }

    void* producer_cond(void* ptr) {
    while (1 && !g_stop) {
    pthread_mutex_lock(&cond_mutex);

    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&cond_mutex);
    }

    return NULL;
    }


    void* consumer_eventfd(void* ptr) {
    uint64_t buf;

    while (g_loops > 0) {
    g_loops--;
    read(g_efd, &buf, 8);
    }

    return NULL;
    }

    void* producer_eventfd(void* ptr) {
    uint64_t buf = 1;
    while (1 && !g_stop) {
    write(g_efd, &buf, 8);
    }

    return NULL;
    }





    void bench(int loops, int pcnt, int ccnt) {
    void* ret;
    int i;
    pthread_t tidc[ccnt], tidp[pcnt];
    struct timeval tv1, tv2;
    float elapse;

    g_efd = eventfd(0, EFD_SEMAPHORE);


    g_loops = loops;
    g_stop = 0;

    gettimeofday(&tv1, NULL);
    for (i = 0; i < ccnt; i++) {
    pthread_create(&tidc[i], NULL, consumer_cond, NULL);
    }
    for (i = 0; i < pcnt; i++) {
    pthread_create(&tidp[i], NULL, producer_cond, NULL);
    }

    for (i = 0; i < ccnt; i++) {
    pthread_join(tidc[i], &ret);
    }
    for (i = 0; i < pcnt; i++) {
    g_stop = 1;
    pthread_join(tidp[i], &ret);
    }
    gettimeofday(&tv2, NULL);


    elapse = (tv2.tv_sec - tv1.tv_sec) * 1000 * 1000 + (tv2.tv_usec - tv1.tv_usec);
    elapse /= 1000 * 1000;
    printf("pthread_cond 耗时 %f 秒\n", elapse);




    g_loops = loops;
    g_stop = 0;

    gettimeofday(&tv1, NULL);
    for (i = 0; i < ccnt; i++) {
    pthread_create(&tidc[i], NULL, consumer_eventfd, NULL);
    }
    for (i = 0; i < pcnt; i++) {
    pthread_create(&tidp[i], NULL, producer_eventfd, NULL);
    }

    for (i = 0; i < ccnt; i++) {
    pthread_join(tidc[i], &ret);
    }
    for (i = 0; i < pcnt; i++) {
    g_stop = 1;
    pthread_join(tidp[i], &ret);
    }
    gettimeofday(&tv2, NULL);


    elapse = (tv2.tv_sec - tv1.tv_sec) * 1000 * 1000 + (tv2.tv_usec - tv1.tv_usec);
    elapse /= 1000 * 1000;
    printf("pthread_eventfd 耗时 %f 秒\n", elapse);



    }


    int main() {
    int i;

    for (i = 1; i <= 100000; i *= 10) {
    printf("进行 %d 次循环测试\n", i);
    bench(i, 1, 1);
    printf("=============\n");
    }

    return 0;
    }