Exemple #1
0
static uint64_t
run_test(struct Test *test)
{
    unsigned i;
    const unsigned THREADS = 1;

    memset(test, 0, sizeof(*test));

    /* Generate producer threads */
    for (i=0; i<THREADS; i++) {
        pixie_begin_thread(test_producer_thread, 0, test);
    }

    /* Wait for threads to start */
    while (test->producer_started < THREADS)
        pixie_usleep(10);
    /* Now start consuming */
    pixie_begin_thread(test_consumer_thread, 0, test);

    /* Wait for producer threads to end */
    while (test->producer_done < THREADS)
        pixie_usleep(10);


    /* Tell consumer thread to end */
    test->not_active = 1;
    

    /* Wait for consumer thread to end */
    while (!test->consumer_done)
        pixie_usleep(10);

    return test->total_count;
}
Exemple #2
0
static void
thread_worker_start(struct Core *core)
{
    struct CoreWorkerThread *t;

    t = malloc(sizeof(*t));
    if (t == 0)
        return;
    memset(t, 0, sizeof(*t));

    t->core = core;
    t->index = core->workers_count;

    t->handle = pixie_begin_thread(thread_worker, 0, t);
    if (t->handle == 0) {
        LOG_ERR(C_GENERAL, "can't start worker thread %u\n", errno);
        free(t);
        return;
    }

    /*
     * Append to our list of worker threads
     */
    core->workers = REALLOC2(core->workers, core->workers_count + 1, sizeof(core->workers[0]));
    core->workers[core->workers_count] = t;
    core->workers_count++;
}
Exemple #3
0
int
perftest(int argc, char *argv[])
{
    struct PerfTest perftest[1];
	struct ZoneFileParser *parser;
    struct Catalog *db;
    size_t i;
    
    
    perftest->loop_count = 10000000;
    
    /*
     * Create a pseudo-network subsystem for generating packets
     */
    perftest->server.parent = perftest;
    perftest->server.adapter = adapter_create(
                                              perftest_alloc_packet, 
                                              perftest_server_to_client_response, 
                                              &perftest->server);
    adapter_add_ipv4(perftest->server.adapter, 0xC0A80101, 0xFFFFffff);
    
    
    /* create a catalog/database, this is where all the parsed zonefile
     * records will be put */
    perftest->db = catalog_create();
    perftest->thread->catalog = perftest->db;
    db = perftest->db;
    
    /* 
     * Parse a sample zone
     */
    parser = zonefile_begin(
                            example_origin, /* origin */
                            60,             /* TTL */
                            10000,          /* filesize */
                            "<perftest>",   /* filename */
                            zonefile_load,  /* callback */
                            db,             /* callback data */
                            0
                            );
    zonefile_set_singlestep(parser);
    for (i=0; perftest_zone[i]; i++) {
        zonefile_parse(parser,
                       (const unsigned char*)perftest_zone[i],
                       strlen(perftest_zone[i])
                       );
    }
    zonefile_end(parser);
    
    /*
     * Send packets. This creates one thread per CPU processing requests.
     */
    {
        unsigned threads_desired = pixie_cpu_get_count();
        uint64_t start, stop;
        double requests_per_second;
        
        fprintf(stderr, "running %u threads\n", threads_desired);
        
        start = pixie_gettime();
        for (i=0; i<threads_desired; i++) {
            __sync_fetch_and_add(&threads_running, 1);
            pixie_begin_thread((void(*)(void*))run_perf, 0, perftest);
        }
        while (threads_running)
            pixie_usleep(1000);
        stop = pixie_gettime();
        
        requests_per_second = 1000000.0 
                                * (1.0 * threads_desired * perftest->loop_count)
                                / (stop - start);
	fprintf(stderr, "queries = %u\n", (unsigned)(threads_desired * perftest->loop_count));
	fprintf(stderr, "seconds = %5.3f\n", (stop - start)/1000000.0);
        fprintf(stderr, "queries/second = %5.3f\n", requests_per_second);
    }
    
    exit(1);
    return 0;
}
Exemple #4
0
enum SuccessFailure
conf_zonefiles_parse(   struct Catalog *db_load,
                        struct Configuration *cfg,
                        uint64_t *out_total_files,
                        uint64_t *out_total_bytes)
{
    struct XParseThread p[16];
    size_t exit_code;
    size_t parse_thread_count = 4;
    size_t i;
    size_t start_index;
    enum SuccessFailure status = Success;
    size_t in_total_files;

    //LOG(2, "loading %llu zonefiles\n", conf->zonefiles.total_files);

    /*
     * Make sure we have some zonefiles to parse
     */
    in_total_files = cfg->zones_length + cfg->zonedirs_filecount;
    if (in_total_files == 0)
        return Failure; /* none found */

    /* The parser threads are heavy-weight, so therefore
     * we shouldn't have a lot of them unless we have
     * a lot of files to parse */
    if (in_total_files < 10)
        parse_thread_count = 1;
    else if (in_total_files < 5000)
        parse_thread_count = 2;
    else
        parse_thread_count = 4;
    

    /*
     * Divide the list of names into equal sized chunks,
     * and launch a parsing thread for each one. The primary 
     * optimization that's happening here is that that each
     * of the threads will stall waiting for file I/O, during
     * which time other threads can be active. Each individual
     * file can be parsed with only a single thread, of course,
     * because zonefiles are stateful. However, two unrelated
     * files can be parsed at the same time.
     */
    start_index = 0;
    for (i=0; i<parse_thread_count; i++) {
        size_t end_index;

        if (start_index >= in_total_files) {
            parse_thread_count = i;
            break;
        }

        /*
         * Figure out the index
         */
        end_index = start_index + in_total_files/parse_thread_count;

        p[i].db_load = db_load;
        p[i].start_index = start_index;
        p[i].end_index = end_index;
        p[i].cfg = cfg;
        p[i].total_bytes = 0;
        p[i].total_files = 0;

        if (parse_thread_count > 1) {
            p[i].thread_handle = pixie_begin_thread(conf_zonefiles_parse_thread, 0, &p[i]);
        } else {
            p[i].thread_handle = 0;
            conf_zonefiles_parse_thread(p);
        }

        start_index = end_index;
    }

    /*
     * Wait for them all to end, and collect statistics.
     */
    for (i=0; i<parse_thread_count; i++) {
        pixie_join(p[i].thread_handle, &exit_code);
        *out_total_bytes += p[i].total_bytes;
        *out_total_files = p[i].total_files;
        if (p[i].status != Success)
            status = Failure;
    }

    return status;
}