<commit_before>// Copyright Steinwurf ApS 2011-2012.
// Distributed under the "STEINWURF RESEARCH LICENSE 1.0".
// See accompanying file LICENSE.rst or
// http://www.steinwurf.com/licensing

#include <ctime>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>  // for memset, memcmp

#include <vector>
#include <set>

#include <gauge/gauge.hpp>

extern "C"
{
#include <lib_common/of_openfec_api.h>
}

#include "../throughput_benchmark.hpp"

struct openfec_rs_encoder
{
    openfec_rs_encoder(uint32_t symbols, uint32_t symbol_size) :
        m_symbols(symbols), m_symbol_size(symbol_size)
    {
        k = m_symbols;
        m = m_symbols / 2;
        m_block_size = m_symbols * m_symbol_size;
        m_payload_count = m;

        int i;
        int vector_count = k + m;

        // Resize data vectors
        m_symbol_table.resize(vector_count);
        m_data.resize(vector_count);
        for (i = 0; i < vector_count; i++)
        {
            m_data[i].resize(m_symbol_size);
        }

        // Set pointers to point to the input symbols
        for (i = 0; i < k; i++)
        {
            // Fill source symbols with random data
            for (uint8_t &e : m_data[i])
            {
                e = rand() % 256;
            }
            m_symbol_table[i] = (char*)&(m_data[i][0]);
        }

        // Set pointers to point to the repair symbol buffers
        for (i = k; i < k + m; i++)
        {
            m_symbol_table[i] = (char*)&(m_data[i][0]);
        }
    }

    ~openfec_rs_encoder()
    {
    }

    void encode_all()
    {
        assert(m_payload_count == (uint32_t)m);

        of_session_t* ses;
        of_codec_id_t codec_id = OF_CODEC_REED_SOLOMON_GF_2_8_STABLE;
        of_codec_type_t codec_type = OF_ENCODER;

        // Create the codec instance and initialize it accordingly
        if (of_create_codec_instance(&ses, codec_id, codec_type,
            of_verbosity))
        {
            printf("of_create_codec_instance() failed\n");
        }

        of_rs_parameters_t params;
        params.nb_source_symbols = k;
        params.nb_repair_symbols = m;
        params.encoding_symbol_length = m_symbol_size;
        if (of_set_fec_parameters(ses, (of_parameters_t*)&params))
        {
            printf("of_set_fec_parameters() failed\n");
        }

        // Generate repair symbols
        for (int i = k; i < k + m; i++)
        {
            if (of_build_repair_symbol(ses, (void**)&m_symbol_table[0], i))
            {
                printf("of_build_repair_symbol() failed\n");
            }
        }

        // Release the FEC codec instance.
        if (of_release_codec_instance(ses))
        {
            printf("of_release_codec_instance() failed\n");
        }
    }

    uint32_t block_size() { return m_block_size; }
    uint32_t symbol_size() { return m_symbol_size; }
    uint32_t payload_size() { return m_symbol_size; }
    uint32_t payload_count() { return m_payload_count; }

protected:

    friend class openfec_rs_decoder;

    // Code parameters
    int k, m;

    // Number of symbols
    uint32_t m_symbols;
    // Size of k+m symbols
    uint32_t m_symbol_size;
    // Size of a full generation (k symbols)
    uint32_t m_block_size;
    // Number of generated payloads
    uint32_t m_payload_count;

    // Table of all symbols (source+repair) in sequential order
    std::vector<char*> m_symbol_table;

    // Storage for source and repair symbols
    std::vector<std::vector<uint8_t>> m_data;
};

struct openfec_rs_decoder
{
    openfec_rs_decoder(uint32_t symbols, uint32_t symbol_size) :
        m_symbols(symbols), m_symbol_size(symbol_size)
    {
        k = m_symbols;
        m = m_symbols / 2;

        m_block_size = m_symbols * m_symbol_size;
        m_decoding_result = -1;

        // Resize data vector to hold original symbols
        m_data.resize(m_symbols);
        for (uint32_t i = 0; i < m_symbols; i++)
        {
            m_data[i].resize(m_symbol_size);
        }

        // Simulate m erasures (erase some original symbols)
        // The symbols will be restored by processing the encoded symbols
        while (m_erased.size() < (uint32_t)m)
        {
            uint8_t random_symbol = rand() % k;
            auto ret = m_erased.insert(random_symbol);
            // Skip this symbol if it was already included in the erased set
            if (ret.second==false) continue;
        }
    }

    ~openfec_rs_decoder()
    {
    }

    static void* allocate_source_symbol(void* context, uint32_t size,
        uint32_t esi)
    {
        openfec_rs_decoder* self = (openfec_rs_decoder*)context;
        assert(size == self->m_symbol_size);
        return (void*)&(self->m_data[esi][0]);
    }

    void decode_all(std::shared_ptr<openfec_rs_encoder> encoder)
    {
        int payload_count = (int)encoder->payload_count();
        assert(payload_count == m);

        of_session_t* ses;
        of_codec_id_t codec_id = OF_CODEC_REED_SOLOMON_GF_2_8_STABLE;
        of_codec_type_t codec_type = OF_DECODER;

        // Create the codec instance and initialize it accordingly
        if (of_create_codec_instance(&ses, codec_id, codec_type,
            of_verbosity))
        {
            printf("of_create_codec_instance() failed\n");
        }

        of_rs_parameters_t params;
        params.nb_source_symbols = k;
        params.nb_repair_symbols = m;
        params.encoding_symbol_length = m_symbol_size;
        if (of_set_fec_parameters(ses, (of_parameters_t*)&params))
        {
            printf("of_set_fec_parameters() failed\n");
        }

        // The decoder uses pre-allocated data buffers to avoid unnecessary
        // copying after decoding
        of_set_callback_functions(ses,
            allocate_source_symbol, NULL, (void*)this);

        // Process original and repair symbols
        for (int i = 0; i < k; i++)
        {
            // Skip the erased original symbols
            //if (m_erased.count(i)) continue;
            if (of_decode_with_new_symbol(ses, &encoder->m_data[i][0], i) ==
                OF_STATUS_ERROR)
            {
                printf("of_decode_with_new_symbol() failed\n");
            }
        }

        if (of_is_decoding_complete(ses) == true)
            m_decoding_result = 0;

        // Release the FEC codec instance.
        if (of_release_codec_instance(ses))
        {
            printf("of_release_codec_instance() failed\n");
        }
    }

    bool verify_data(std::shared_ptr<openfec_rs_encoder> encoder)
    {
        assert(m_block_size == encoder->block_size());

        for (uint32_t i = 0; i < m_symbols; i++)
        {
            if (memcmp(&m_data[i][0], &(encoder->m_data[i][0]), m_symbol_size))
            {
                return false;
            }
        }

        return true;
    }

    bool is_complete() { return (m_decoding_result != -1); }

    uint32_t block_size() { return m_block_size; }
    uint32_t symbol_size() { return m_symbol_size; }
    uint32_t payload_size() { return m_symbol_size; }

protected:

    // Code parameters
    int k, m;

    // Number of symbols
    uint32_t m_symbols;
    // Size of k+m symbols
    uint32_t m_symbol_size;
    // Size of a full generation (k symbols)
    uint32_t m_block_size;
    // Set of erased symbols
    std::set<uint8_t> m_erased;

    int m_decoding_result;

    // Storage for source symbols
    std::vector<std::vector<uint8_t>> m_data;
};

BENCHMARK_OPTION(throughput_options)
{
    gauge::po::options_description options;

    std::vector<uint32_t> symbols;
    symbols.push_back(16);
    //     symbols.push_back(32);
    //     symbols.push_back(64);
    //     symbols.push_back(128);
    //     symbols.push_back(256);
    //     symbols.push_back(512);

    auto default_symbols =
        gauge::po::value<std::vector<uint32_t> >()->default_value(
            symbols, "")->multitoken();

    // Symbol size must be a multiple of 32
    std::vector<uint32_t> symbol_size;
    symbol_size.push_back(1000000);

    auto default_symbol_size =
        gauge::po::value<std::vector<uint32_t> >()->default_value(
            symbol_size, "")->multitoken();

    std::vector<std::string> types;
    types.push_back("encoder");
    types.push_back("decoder");

    auto default_types =
        gauge::po::value<std::vector<std::string> >()->default_value(
            types, "")->multitoken();

    options.add_options()
        ("symbols", default_symbols, "Set the number of symbols");

    options.add_options()
        ("symbol_size", default_symbol_size, "Set the symbol size in bytes");

    options.add_options()
        ("type", default_types, "Set type [encoder|decoder]");

    gauge::runner::instance().register_options(options);
}

//------------------------------------------------------------------
// OpenFEC Reed-Solomon codec
//------------------------------------------------------------------

typedef throughput_benchmark<openfec_rs_encoder, openfec_rs_decoder>
    openfec_rs_throughput;

BENCHMARK_F(openfec_rs_throughput, OpenFEC, ReedSolomon, 10)
{
    run_benchmark();
}

int main(int argc, const char* argv[])
{
    srand(static_cast<uint32_t>(time(0)));

    gauge::runner::add_default_printers();
    gauge::runner::run_benchmarks(argc, argv);

    return 0;
}
<commit_msg>Working on openfec.cpp<commit_after>// Copyright Steinwurf ApS 2011-2012.
// Distributed under the "STEINWURF RESEARCH LICENSE 1.0".
// See accompanying file LICENSE.rst or
// http://www.steinwurf.com/licensing

#include <ctime>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>  // for memset, memcmp

#include <vector>
#include <set>

#include <gauge/gauge.hpp>

extern "C"
{
#include <lib_common/of_openfec_api.h>
}

#include "../throughput_benchmark.hpp"

struct openfec_rs_encoder
{
    openfec_rs_encoder(uint32_t symbols, uint32_t symbol_size) :
        m_symbols(symbols), m_symbol_size(symbol_size)
    {
        k = m_symbols;
        m = m_symbols / 2;
        m_block_size = m_symbols * m_symbol_size;
        m_payload_count = m;

        int i;
        int vector_count = k + m;

        // Resize data vectors
        m_symbol_table.resize(vector_count);
        m_data.resize(vector_count);
        for (i = 0; i < vector_count; i++)
        {
            m_data[i].resize(m_symbol_size);
        }

        // Set pointers to point to the input symbols
        for (i = 0; i < k; i++)
        {
            // Fill source symbols with random data
            for (uint8_t &e : m_data[i])
            {
                e = rand() % 256;
            }
            m_symbol_table[i] = (char*)&(m_data[i][0]);
        }

        // Set pointers to point to the repair symbol buffers
        for (i = k; i < k + m; i++)
        {
            m_symbol_table[i] = (char*)&(m_data[i][0]);
        }
    }

    ~openfec_rs_encoder()
    {
    }

    void encode_all()
    {
        assert(m_payload_count == (uint32_t)m);

        of_session_t* ses;
        of_codec_id_t codec_id = OF_CODEC_REED_SOLOMON_GF_2_8_STABLE;
        of_codec_type_t codec_type = OF_ENCODER;

        // Create the codec instance and initialize it accordingly
        if (of_create_codec_instance(&ses, codec_id, codec_type,
            of_verbosity))
        {
            printf("of_create_codec_instance() failed\n");
        }

        of_rs_parameters_t params;
        params.nb_source_symbols = k;
        params.nb_repair_symbols = m;
        params.encoding_symbol_length = m_symbol_size;
        if (of_set_fec_parameters(ses, (of_parameters_t*)&params))
        {
            printf("of_set_fec_parameters() failed\n");
        }

        // Generate repair symbols
        for (int i = k; i < k + m; i++)
        {
            if (of_build_repair_symbol(ses, (void**)&m_symbol_table[0], i))
            {
                printf("of_build_repair_symbol() failed\n");
            }
        }

        // Release the FEC codec instance.
        if (of_release_codec_instance(ses))
        {
            printf("of_release_codec_instance() failed\n");
        }
    }

    uint32_t block_size() { return m_block_size; }
    uint32_t symbol_size() { return m_symbol_size; }
    uint32_t payload_size() { return m_symbol_size; }
    uint32_t payload_count() { return m_payload_count; }

protected:

    friend class openfec_rs_decoder;

    // Code parameters
    int k, m;

    // Number of symbols
    uint32_t m_symbols;
    // Size of k+m symbols
    uint32_t m_symbol_size;
    // Size of a full generation (k symbols)
    uint32_t m_block_size;
    // Number of generated payloads
    uint32_t m_payload_count;

    // Table of all symbols (source+repair) in sequential order
    std::vector<char*> m_symbol_table;

    // Storage for source and repair symbols
    std::vector<std::vector<uint8_t>> m_data;
};

struct openfec_rs_decoder
{
    openfec_rs_decoder(uint32_t symbols, uint32_t symbol_size) :
        m_symbols(symbols), m_symbol_size(symbol_size)
    {
        k = m_symbols;
        m = m_symbols / 2;

        m_block_size = m_symbols * m_symbol_size;
        m_decoding_result = -1;

        // Resize data vector to hold original symbols
        m_data.resize(m_symbols);
        for (uint32_t i = 0; i < m_symbols; i++)
        {
            m_data[i].resize(m_symbol_size);
        }

        // Simulate m erasures (erase some original symbols)
        // The symbols will be restored by processing the encoded symbols
        while (m_erased.size() < (uint32_t)m)
        {
            uint8_t random_symbol = rand() % k;
            auto ret = m_erased.insert(random_symbol);
            // Skip this symbol if it was already included in the erased set
            if (ret.second==false) continue;
        }
    }

    ~openfec_rs_decoder()
    {
    }

    static void* allocate_source_symbol(void* context, uint32_t size,
        uint32_t esi)
    {
        openfec_rs_decoder* self = (openfec_rs_decoder*)context;
        assert(size == self->m_symbol_size);
        return (void*)&(self->m_data[esi][0]);
    }

    void decode_all(std::shared_ptr<openfec_rs_encoder> encoder)
    {
        int payload_count = (int)encoder->payload_count();
        assert(payload_count == m);

        of_session_t* ses;
        of_codec_id_t codec_id = OF_CODEC_REED_SOLOMON_GF_2_8_STABLE;
        of_codec_type_t codec_type = OF_DECODER;

        // Create the codec instance and initialize it accordingly
        if (of_create_codec_instance(&ses, codec_id, codec_type,
            of_verbosity))
        {
            printf("of_create_codec_instance() failed\n");
        }

        of_rs_parameters_t params;
        params.nb_source_symbols = k;
        params.nb_repair_symbols = m;
        params.encoding_symbol_length = m_symbol_size;
        if (of_set_fec_parameters(ses, (of_parameters_t*)&params))
        {
            printf("of_set_fec_parameters() failed\n");
        }

        // The decoder uses pre-allocated data buffers to avoid unnecessary
        // copying after decoding
        of_set_callback_functions(ses,
            allocate_source_symbol, NULL, (void*)this);

        // Process original and repair symbols
        for (int i = 0; i < k + m; i++)
        {
            // Skip the erased original symbols
            if (m_erased.count(i)) continue;
            if (of_decode_with_new_symbol(ses, &encoder->m_data[i][0], i) ==
                OF_STATUS_ERROR)
            {
                printf("of_decode_with_new_symbol() failed\n");
            }
        }

        if (of_is_decoding_complete(ses) == true)
            m_decoding_result = 0;

        // Release the FEC codec instance.
        if (of_release_codec_instance(ses))
        {
            printf("of_release_codec_instance() failed\n");
        }
    }

    bool verify_data(std::shared_ptr<openfec_rs_encoder> encoder)
    {
        assert(m_block_size == encoder->block_size());

        // We only verify the erased symbols
        for (const uint8_t& e : erased)
        {
            if (memcmp(&m_data[e][0], &(encoder->m_data[e][0]), m_symbol_size))
            {
                return false;
            }
        }

        return true;
    }

    bool is_complete() { return (m_decoding_result != -1); }

    uint32_t block_size() { return m_block_size; }
    uint32_t symbol_size() { return m_symbol_size; }
    uint32_t payload_size() { return m_symbol_size; }

protected:

    // Code parameters
    int k, m;

    // Number of symbols
    uint32_t m_symbols;
    // Size of k+m symbols
    uint32_t m_symbol_size;
    // Size of a full generation (k symbols)
    uint32_t m_block_size;
    // Set of erased symbols
    std::set<uint8_t> m_erased;

    int m_decoding_result;

    // Storage for source symbols
    std::vector<std::vector<uint8_t>> m_data;
};

BENCHMARK_OPTION(throughput_options)
{
    gauge::po::options_description options;

    std::vector<uint32_t> symbols;
    symbols.push_back(16);
    //     symbols.push_back(32);
    //     symbols.push_back(64);
    //     symbols.push_back(128);
    //     symbols.push_back(256);
    //     symbols.push_back(512);

    auto default_symbols =
        gauge::po::value<std::vector<uint32_t> >()->default_value(
            symbols, "")->multitoken();

    // Symbol size must be a multiple of 32
    std::vector<uint32_t> symbol_size;
    symbol_size.push_back(1000000);

    auto default_symbol_size =
        gauge::po::value<std::vector<uint32_t> >()->default_value(
            symbol_size, "")->multitoken();

    std::vector<std::string> types;
    types.push_back("encoder");
    types.push_back("decoder");

    auto default_types =
        gauge::po::value<std::vector<std::string> >()->default_value(
            types, "")->multitoken();

    options.add_options()
        ("symbols", default_symbols, "Set the number of symbols");

    options.add_options()
        ("symbol_size", default_symbol_size, "Set the symbol size in bytes");

    options.add_options()
        ("type", default_types, "Set type [encoder|decoder]");

    gauge::runner::instance().register_options(options);
}

//------------------------------------------------------------------
// OpenFEC Reed-Solomon codec
//------------------------------------------------------------------

typedef throughput_benchmark<openfec_rs_encoder, openfec_rs_decoder>
    openfec_rs_throughput;

BENCHMARK_F(openfec_rs_throughput, OpenFEC, ReedSolomon, 10)
{
    run_benchmark();
}

int main(int argc, const char* argv[])
{
    srand(static_cast<uint32_t>(time(0)));

    gauge::runner::add_default_printers();
    gauge::runner::run_benchmarks(argc, argv);

    return 0;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <forestclaw2d.h>
#include <fclaw_options.h>

#include <fclaw2d_clawpack.H>
#include <fclaw2d_map.h>
#include <fclaw2d_map_query.h>

#include <amr_forestclaw.H>
#include <amr_utils.H>
#include <fclaw_options.h>

#include <p4est_connectivity.h>

#include "torus_user.H"

typedef struct user_options
{
    int example;
    double alpha;
    double beta;

    const char* latitude_string;
    double *latitude;

    const char* longitude_string;
    double *longitude;

    int is_registered;

} user_options_t;

static void *
options_register_user (fclaw_app_t * app, void *package, sc_options_t * opt)
{
    sc_options_t* options;
    user_options_t* user = (user_options_t*) package;

    options = fclaw_app_get_options (app);

    /* [main] User options in */
    sc_options_add_int (options, 0, "main:example", &user->example, 0,
                        "[main] 1 = cart; 2 = torus; 3 = lat-long; 4 = annulus [2]");

    sc_options_add_double (options, 0, "main:alpha", &user->alpha, 0.4,
                           "[main] Ratio r/R, r=outer radius, R=inner radius " \
                           "(used for torus) [0.4]");

    fclaw_options_add_double_array(options, 0, "main:latitude", &user->latitude_string,
                                   "-50 50", &user->latitude, 2,
                                   "[main] Latitude range (degrees) [-50 50]");

    fclaw_options_add_double_array(options, 0, "main:longitude", &user->longitude_string,
                                   "0 360", &user->longitude, 2,
                                   "[main] Longitude range (degrees) [0 360]");

    sc_options_add_double (options, 0, "main:beta", &user->beta, 0.4,
                           "[main] Inner radius of annulus [0.4]");

    user->is_registered = 1;
    return NULL;
}

static fclaw_exit_type_t
options_postprocess_user (fclaw_app_t * a, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;

    if (user->example == 3)
    {
        fclaw_options_convert_double_array (user->latitude_string, &user->latitude,2);
        fclaw_options_convert_double_array (user->longitude_string, &user->longitude,2);
    }
    return FCLAW_NOEXIT;
}

fclaw_exit_type_t
options_check_user (fclaw_app_t * app, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;
    if (user->example < 1 || user->example > 4) {
        fclaw_global_essentialf ("Option --main:example must be 1, 2, 3 or 4\n");
        return FCLAW_EXIT_QUIET;
    }
    return FCLAW_NOEXIT;
}

static void
options_destroy_user (fclaw_app_t * a, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;
    /* Destroy arrays used in options  */
    if (user->example == 3)
    {
        fclaw_options_destroy_array((void*) user->latitude);
        fclaw_options_destroy_array((void*) user->longitude);
    }
}

static const fclaw_app_options_vtable_t options_vtable_user = {
    options_register_user,
    options_postprocess_user,
    options_check_user,
    options_destroy_user
};

void fclaw_app_options_register_user (fclaw_app_t * app,
                                      const char *configfile,
                                      user_options_t* user)
{

    FCLAW_ASSERT (app != NULL);

    /* sneaking the version string into the package pointer */
    /* when there are more parameters to pass, create a structure to pass */
    fclaw_app_options_register (app,"main", configfile, &options_vtable_user,
                                user);

}

void run_program(fclaw_app_t* app, amr_options_t* gparms,
                 fclaw2d_clawpack_parms_t* clawpack_parms,
                 user_options_t* user)
{
    sc_MPI_Comm            mpicomm;
    p4est_connectivity_t   *conn = NULL;
    fclaw2d_domain_t	   *domain;

    /* Mapping  */
    fclaw2d_map_context_t    *cont = NULL, *brick = NULL;

    /* Used locally */
    double pi = M_PI;
    double rotate[2];
    int mi, mj, a,b;

    mpicomm = fclaw_app_get_mpi_size_rank (app, NULL, NULL);

    /* ---------------------------------------------------------------
       Mapping geometry
       --------------------------------------------------------------- */
    mi = gparms->mi;
    mj = gparms->mj;
    rotate[0] = pi*gparms->theta/180.0;
    rotate[1] = pi*gparms->phi/180.0;
    a = gparms->periodic_x;
    b = gparms->periodic_y;

    switch (user->example)
    {
    case 1:
        conn = p4est_connectivity_new_brick(mi,mj,a,b);
        brick = fclaw2d_map_new_brick(conn,mi,mj);
        cont = fclaw2d_map_new_cart(brick,gparms->scale,gparms->shift,rotate);
        break;
    case 2:
        conn = p4est_connectivity_new_brick(mi,mj,a,b);
        brick = fclaw2d_map_new_brick(conn,mi,mj);
        cont = fclaw2d_map_new_torus(brick,gparms->scale,gparms->shift,rotate,user->alpha);
        break;
    case 3:
        /* Lat-long example */
        conn = p4est_connectivity_new_brick(mi,mj,a,b);
        brick = fclaw2d_map_new_brick(conn,mi,mj);
        cont = fclaw2d_map_new_latlong(brick,gparms->scale,gparms->shift,
                                       rotate,user->latitude,user->longitude,a,b);
        break;
    case 4:
        /* Annulus */
        conn = p4est_connectivity_new_brick(mi,mj,a,b);
        brick = fclaw2d_map_new_brick(conn,mi,mj);
        cont = fclaw2d_map_new_annulus(brick,gparms->scale,gparms->shift,
                                       rotate,user->beta);
        break;

    default:
        SC_ABORT_NOT_REACHED (); /* must be checked in torus_checkparms */
    }

    domain = fclaw2d_domain_new_conn_map (mpicomm, gparms->minlevel, conn, cont);

    fclaw2d_domain_list_levels(domain, FCLAW_VERBOSITY_PRODUCTION);
    fclaw2d_domain_list_neighbors(domain, FCLAW_VERBOSITY_PRODUCTION);

    /* ---------------------------------------------------------------
       Set domain data.
       --------------------------------------------------------------- */
    init_domain_data(domain);

    set_domain_parms(domain,gparms);
    set_clawpack_parms(domain,clawpack_parms);

    link_problem_setup(domain,torus_problem_setup);

    torus_link_solvers(domain);

    link_regrid_functions(domain,
                          torus_patch_tag4refinement,
                          torus_patch_tag4coarsening);
    amrinit(&domain);
    amrrun(&domain);
    amrreset(&domain);

    fclaw2d_map_destroy(cont);
}

int
main (int argc, char **argv)
{
  fclaw_app_t *app;
  int first_arg;
  fclaw_exit_type_t vexit;

  sc_options_t             *options;

  /* Options */
  amr_options_t             samr_options, *gparms = &samr_options;
  fclaw2d_clawpack_parms_t  sclawpack_parms, *clawpack_parms = &sclawpack_parms;
  user_options_t            suser_options, *user = &suser_options;

  int retval;

  /* -------------------------------------------------------------
     - Initialize application
     ------------------------------------------------------------- */
  app = fclaw_app_new (&argc, &argv, user);
  options = fclaw_app_get_options (app);

  /*  Register options for each package */
  fclaw_app_options_register_general (app, "fclaw_options.ini", gparms);
  fclaw_app_options_register_user (app, "fclaw_options.ini", user);

  /* [clawpack46] Add solver options */
  clawpack46_options_add(options,clawpack_parms);

  /* Read configuration file(s) */
  retval = fclaw_options_read_from_file(options);

  /* Parse command line, post-process and check parameter values */
  vexit =  fclaw_app_options_parse (app, &first_arg,"fclaw_options.ini.used");

  clawpack46_postprocess_parms(clawpack_parms);

  /* retval = retval || fclaw_options_check (options, gparms); */
  retval = retval || clawpack46_checkparms(options,clawpack_parms,gparms);
  /* -------------------------------------------------------------
     - Run program
     ------------------------------------------------------------- */
  if (!retval & !vexit)
  {
      run_program(app, gparms, clawpack_parms,user);
  }

  /* Which of these do I still need? */
  fclaw2d_clawpack_parms_delete(clawpack_parms);

  fclaw_app_destroy (app);

  return 0;
}
<commit_msg>Fixed up user options<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <forestclaw2d.h>
#include <fclaw_options.h>

#include <fclaw2d_clawpack.H>
#include <fclaw2d_map.h>
#include <fclaw2d_map_query.h>

#include <amr_forestclaw.H>
#include <amr_utils.H>
#include <fclaw_options.h>

#include <p4est_connectivity.h>

#include "torus_user.H"

typedef struct user_options
{
    int example;
    double alpha;
    double beta;

    const char* latitude_string;
    double *latitude;

    const char* longitude_string;
    double *longitude;

    int is_registered;

} user_options_t;

static void *
options_register_user (fclaw_app_t * app, void *package, sc_options_t * opt)
{
    user_options_t* user = (user_options_t*) package;

    /* [main] User options in */
    sc_options_add_int (opt, 0, "example", &user->example, 0,
                        "[main] 1 = cart; 2 = torus; 3 = lat-long; 4 = annulus [2]");

    sc_options_add_double (opt, 0, "alpha", &user->alpha, 0.4,
                           "[main] Ratio r/R, r=outer radius, R=inner radius " \
                           "(used for torus) [0.4]");

    fclaw_options_add_double_array(opt, 0, "latitude", &user->latitude_string,
                                   "-50 50", &user->latitude, 2,
                                   "[main] Latitude range (degrees) [-50 50]");

    fclaw_options_add_double_array(opt, 0, "longitude", &user->longitude_string,
                                   "0 360", &user->longitude, 2,
                                   "[main] Longitude range (degrees) [0 360]");

    sc_options_add_double (opt, 0, "beta", &user->beta, 0.4,
                           "[main] Inner radius of annulus [0.4]");

    user->is_registered = 1;
    return NULL;
}

static fclaw_exit_type_t
options_postprocess_user (fclaw_app_t * a, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;

    if (user->example == 3)
    {
        fclaw_options_convert_double_array (user->latitude_string, &user->latitude,2);
        fclaw_options_convert_double_array (user->longitude_string, &user->longitude,2);
    }
    return FCLAW_NOEXIT;
}

fclaw_exit_type_t
options_check_user (fclaw_app_t * app, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;
    if (user->example < 1 || user->example > 4) {
        fclaw_global_essentialf ("Option --main:example must be 1, 2, 3 or 4\n");
        return FCLAW_EXIT_QUIET;
    }
    return FCLAW_NOEXIT;
}

static void
options_destroy_user (fclaw_app_t * a, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;
    /* Destroy arrays used in options  */
    if (user->example == 3)
    {
        fclaw_options_destroy_array((void*) user->latitude);
        fclaw_options_destroy_array((void*) user->longitude);
    }
}

static const fclaw_app_options_vtable_t options_vtable_user = {
    options_register_user,
    options_postprocess_user,
    options_check_user,
    options_destroy_user
};

void fclaw_app_options_register_user (fclaw_app_t * app,
                                      const char *configfile,
                                      user_options_t* user)
{

    FCLAW_ASSERT (app != NULL);

    /* sneaking the version string into the package pointer */
    /* when there are more parameters to pass, create a structure to pass */
    fclaw_app_options_register (app,"user", configfile, &options_vtable_user,
                                user);

}

void run_program(fclaw_app_t* app, amr_options_t* gparms,
                 fclaw2d_clawpack_parms_t* clawpack_parms,
                 user_options_t* user)
{
    sc_MPI_Comm            mpicomm;
    p4est_connectivity_t   *conn = NULL;
    fclaw2d_domain_t	   *domain;

    /* Mapping  */
    fclaw2d_map_context_t    *cont = NULL, *brick = NULL;

    /* Used locally */
    double pi = M_PI;
    double rotate[2];
    int mi, mj, a,b;

    mpicomm = fclaw_app_get_mpi_size_rank (app, NULL, NULL);

    /* ---------------------------------------------------------------
       Mapping geometry
       --------------------------------------------------------------- */
    mi = gparms->mi;
    mj = gparms->mj;
    rotate[0] = pi*gparms->theta/180.0;
    rotate[1] = pi*gparms->phi/180.0;
    a = gparms->periodic_x;
    b = gparms->periodic_y;

    switch (user->example)
    {
    case 1:
        conn = p4est_connectivity_new_brick(mi,mj,a,b);
        brick = fclaw2d_map_new_brick(conn,mi,mj);
        cont = fclaw2d_map_new_cart(brick,gparms->scale,gparms->shift,rotate);
        break;
    case 2:
        conn = p4est_connectivity_new_brick(mi,mj,a,b);
        brick = fclaw2d_map_new_brick(conn,mi,mj);
        cont = fclaw2d_map_new_torus(brick,gparms->scale,gparms->shift,rotate,user->alpha);
        break;
    case 3:
        /* Lat-long example */
        conn = p4est_connectivity_new_brick(mi,mj,a,b);
        brick = fclaw2d_map_new_brick(conn,mi,mj);
        cont = fclaw2d_map_new_latlong(brick,gparms->scale,gparms->shift,
                                       rotate,user->latitude,user->longitude,a,b);
        break;
    case 4:
        /* Annulus */
        conn = p4est_connectivity_new_brick(mi,mj,a,b);
        brick = fclaw2d_map_new_brick(conn,mi,mj);
        cont = fclaw2d_map_new_annulus(brick,gparms->scale,gparms->shift,
                                       rotate,user->beta);
        break;

    default:
        SC_ABORT_NOT_REACHED (); /* must be checked in torus_checkparms */
    }

    domain = fclaw2d_domain_new_conn_map (mpicomm, gparms->minlevel, conn, cont);

    fclaw2d_domain_list_levels(domain, FCLAW_VERBOSITY_PRODUCTION);
    fclaw2d_domain_list_neighbors(domain, FCLAW_VERBOSITY_PRODUCTION);

    /* ---------------------------------------------------------------
       Set domain data.
       --------------------------------------------------------------- */
    init_domain_data(domain);

    set_domain_parms(domain,gparms);
    set_clawpack_parms(domain,clawpack_parms);

    link_problem_setup(domain,torus_problem_setup);

    torus_link_solvers(domain);

    link_regrid_functions(domain,
                          torus_patch_tag4refinement,
                          torus_patch_tag4coarsening);
    amrinit(&domain);
    amrrun(&domain);
    amrreset(&domain);

    fclaw2d_map_destroy(cont);
}

int
main (int argc, char **argv)
{
  fclaw_app_t *app;
  int first_arg;
  fclaw_exit_type_t vexit;

  sc_options_t             *options;

  /* Options */
  amr_options_t             samr_options, *gparms = &samr_options;
  fclaw2d_clawpack_parms_t  sclawpack_parms, *clawpack_parms = &sclawpack_parms;
  user_options_t            suser_options, *user = &suser_options;

  int retval;

  /* -------------------------------------------------------------
     - Initialize application
     ------------------------------------------------------------- */
  app = fclaw_app_new (&argc, &argv, user);
  options = fclaw_app_get_options (app);

  /*  Register options for each package */
  fclaw_app_options_register_general (app, "fclaw_options.ini", gparms);
  fclaw_app_options_register_user (app, "fclaw_options.ini", user);

  /* [clawpack46] Add solver options */
  clawpack46_options_add(options,clawpack_parms);

  /* Read configuration file(s) */
  retval = fclaw_options_read_from_file(options);

  /* Parse command line, post-process and check parameter values */
  vexit =  fclaw_app_options_parse (app, &first_arg,"fclaw_options.ini.used");

  clawpack46_postprocess_parms(clawpack_parms);

  /* retval = retval || fclaw_options_check (options, gparms); */
  retval = retval || clawpack46_checkparms(options,clawpack_parms,gparms);
  /* -------------------------------------------------------------
     - Run program
     ------------------------------------------------------------- */
  if (!retval & !vexit)
  {
      run_program(app, gparms, clawpack_parms,user);
  }

  /* Which of these do I still need? */
  fclaw2d_clawpack_parms_delete(clawpack_parms);

  fclaw_app_destroy (app);

  return 0;
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP
#define STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP

#include <stan/math/memory/stack_alloc.hpp>
#include <vector>

namespace stan {
namespace math {

template <typename ChainableT, typename ChainableAllocT>
struct AutodiffStackStorage {
  static std::vector<ChainableT*> var_stack_;
  static std::vector<ChainableT*> var_nochain_stack_;
  static std::vector<ChainableAllocT*> var_alloc_stack_;
  static stack_alloc memalloc_;

  // nested positions
  static std::vector<size_t> nested_var_stack_sizes_;
  static std::vector<size_t> nested_var_nochain_stack_sizes_;
  static std::vector<size_t> nested_var_alloc_stack_starts_;
};

template <typename ChainableT, typename ChainableAllocT>
std::vector<ChainableT*>
    AutodiffStackStorage<ChainableT, ChainableAllocT>::var_stack_;

template <typename ChainableT, typename ChainableAllocT>
std::vector<ChainableT*>
    AutodiffStackStorage<ChainableT, ChainableAllocT>::var_nochain_stack_;

template <typename ChainableT, typename ChainableAllocT>
std::vector<ChainableAllocT*>
    AutodiffStackStorage<ChainableT, ChainableAllocT>::var_alloc_stack_;

template <typename ChainableT, typename ChainableAllocT>
stack_alloc AutodiffStackStorage<ChainableT, ChainableAllocT>::memalloc_;

template <typename ChainableT, typename ChainableAllocT>
std::vector<size_t>
    AutodiffStackStorage<ChainableT, ChainableAllocT>::nested_var_stack_sizes_;

template <typename ChainableT, typename ChainableAllocT>
std::vector<size_t> AutodiffStackStorage<
    ChainableT, ChainableAllocT>::nested_var_nochain_stack_sizes_;

template <typename ChainableT, typename ChainableAllocT>
std::vector<size_t> AutodiffStackStorage<
    ChainableT, ChainableAllocT>::nested_var_alloc_stack_starts_;

}  // namespace math
}  // namespace stan
#endif
<commit_msg>make AD stack thread_local<commit_after>#ifndef STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP
#define STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP

#include <stan/math/memory/stack_alloc.hpp>
#include <vector>

namespace stan {
namespace math {

template <typename ChainableT, typename ChainableAllocT>
struct AutodiffStackStorage {
  thread_local static std::vector<ChainableT*> var_stack_;
  thread_local static std::vector<ChainableT*> var_nochain_stack_;
  thread_local static std::vector<ChainableAllocT*> var_alloc_stack_;
  thread_local static stack_alloc memalloc_;

  // nested positions
  thread_local static std::vector<size_t> nested_var_stack_sizes_;
  thread_local static std::vector<size_t> nested_var_nochain_stack_sizes_;
  thread_local static std::vector<size_t> nested_var_alloc_stack_starts_;
};

template <typename ChainableT, typename ChainableAllocT>
thread_local
std::vector<ChainableT*>
    AutodiffStackStorage<ChainableT, ChainableAllocT>::var_stack_;

template <typename ChainableT, typename ChainableAllocT>
thread_local
std::vector<ChainableT*>
    AutodiffStackStorage<ChainableT, ChainableAllocT>::var_nochain_stack_;

template <typename ChainableT, typename ChainableAllocT>
thread_local
std::vector<ChainableAllocT*>
    AutodiffStackStorage<ChainableT, ChainableAllocT>::var_alloc_stack_;

template <typename ChainableT, typename ChainableAllocT>
thread_local
stack_alloc AutodiffStackStorage<ChainableT, ChainableAllocT>::memalloc_;

template <typename ChainableT, typename ChainableAllocT>
thread_local
std::vector<size_t>
    AutodiffStackStorage<ChainableT, ChainableAllocT>::nested_var_stack_sizes_;

template <typename ChainableT, typename ChainableAllocT>
thread_local
std::vector<size_t> AutodiffStackStorage<
    ChainableT, ChainableAllocT>::nested_var_nochain_stack_sizes_;

template <typename ChainableT, typename ChainableAllocT>
thread_local
std::vector<size_t> AutodiffStackStorage<
    ChainableT, ChainableAllocT>::nested_var_alloc_stack_starts_;

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP
#define STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP

#include <stan/math/memory/stack_alloc.hpp>
#include <vector>

namespace stan {
namespace math {

template <typename ChainableT, typename ChainableAllocT>
struct AutodiffStackStorage {
  std::vector<ChainableT*> var_stack_;
  std::vector<ChainableT*> var_nochain_stack_;
  std::vector<ChainableAllocT*> var_alloc_stack_;
  stack_alloc memalloc_;

  // nested positions
  std::vector<size_t> nested_var_stack_sizes_;
  std::vector<size_t> nested_var_nochain_stack_sizes_;
  std::vector<size_t> nested_var_alloc_stack_starts_;
};

/**
 * Provides a thread_local singleton. Read warnings below!
 * This is useful in a pretty limited set of circumstances, not just because
 * it's thread_local, but also because of "the static init order fiasco"[0].
 * Anywhere this is used, we must be absolutely positive that it doesn't matter
 * when the singleton will get initialized relative to other static variables. In
 * exchange, we get a much more performant singleton pattern than is available
 * with the standard C++11 singleton pattern relying on a function wrapping a
 * static local variable. There has been some discussion on this; see [1] and
 * [2] and the discussions those PRs link to as well.
 *
 * These are thread_local only if the user asks for it with -DSTAN_THREADS. This
 * is because Apple clang compilers before 2016 don't support thread_local. We
 * have proposed removing support for those[3], and will remove this ifdef at
 * that time.
 *
 * [0] https://isocpp.org/wiki/faq/ctors#static-init-order
 * [1] https://github.com/stan-dev/math/pull/840
 * [2] https://github.com/stan-dev/math/pull/826
 * [3]
 * http://discourse.mc-stan.org/t/potentially-dropping-support-for-older-versions-of-apples-version-of-clang/3780/
 */
template <typename ChainableT, typename ChainableAllocT>
struct AutodiffStackSingleton {
#ifdef STAN_THREADS
  thread_local
#endif
      static AutodiffStackStorage<ChainableT, ChainableAllocT>
          instance_;
};

template <typename ChainableT, typename ChainableAllocT>
#ifdef STAN_THREADS
thread_local
#endif
    AutodiffStackStorage<ChainableT, ChainableAllocT>
        AutodiffStackSingleton<ChainableT, ChainableAllocT>::instance_;

}  // namespace math
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/stable/2017-11-14)<commit_after>#ifndef STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP
#define STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP

#include <stan/math/memory/stack_alloc.hpp>
#include <vector>

namespace stan {
namespace math {

template <typename ChainableT, typename ChainableAllocT>
struct AutodiffStackStorage {
  std::vector<ChainableT*> var_stack_;
  std::vector<ChainableT*> var_nochain_stack_;
  std::vector<ChainableAllocT*> var_alloc_stack_;
  stack_alloc memalloc_;

  // nested positions
  std::vector<size_t> nested_var_stack_sizes_;
  std::vector<size_t> nested_var_nochain_stack_sizes_;
  std::vector<size_t> nested_var_alloc_stack_starts_;
};

/**
 * Provides a thread_local singleton. Read warnings below!
 * This is useful in a pretty limited set of circumstances, not just because
 * it's thread_local, but also because of "the static init order fiasco"[0].
 * Anywhere this is used, we must be absolutely positive that it doesn't matter
 * when the singleton will get initialized relative to other static variables.
 * In exchange, we get a much more performant singleton pattern than is
 * available with the standard C++11 singleton pattern relying on a function
 * wrapping a static local variable. There has been some discussion on this; see
 * [1] and [2] and the discussions those PRs link to as well.
 *
 * These are thread_local only if the user asks for it with -DSTAN_THREADS. This
 * is because Apple clang compilers before 2016 don't support thread_local. We
 * have proposed removing support for those[3], and will remove this ifdef at
 * that time.
 *
 * [0] https://isocpp.org/wiki/faq/ctors#static-init-order
 * [1] https://github.com/stan-dev/math/pull/840
 * [2] https://github.com/stan-dev/math/pull/826
 * [3]
 * http://discourse.mc-stan.org/t/potentially-dropping-support-for-older-versions-of-apples-version-of-clang/3780/
 */
template <typename ChainableT, typename ChainableAllocT>
struct AutodiffStackSingleton {
#ifdef STAN_THREADS
  thread_local
#endif
      static AutodiffStackStorage<ChainableT, ChainableAllocT>
          instance_;
};

template <typename ChainableT, typename ChainableAllocT>
#ifdef STAN_THREADS
thread_local
#endif
    AutodiffStackStorage<ChainableT, ChainableAllocT>
        AutodiffStackSingleton<ChainableT, ChainableAllocT>::instance_;

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/gui/MouseOperations.h>
#include <sofa/gui/PickHandler.h>
#include <sofa/component/collision/InteractionPerformer.h>

#include <sofa/component/collision/ComponentMouseInteraction.h>
#include <sofa/component/collision/AttachBodyPerformer.h>
#include <sofa/component/collision/FixParticlePerformer.h>
#include <sofa/component/collision/RemovePrimitivePerformer.h>
#include <sofa/component/collision/InciseAlongPathPerformer.h>
#include <sofa/component/collision/AddFramePerformer.h>
#include <sofa/component/collision/SuturePointPerformer.h>

namespace sofa
{

using namespace component::collision;

#ifdef WIN32
#ifndef SOFA_DOUBLE
helper::Creator<InteractionPerformer::InteractionPerformerFactory, AttachBodyPerformer<defaulttype::Vec3fTypes> >  AttachBodyPerformerVec3fClass("AttachBody",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, AddFramePerformer<defaulttype::Vec3fTypes> >  AddFramePerformerVec3fClass("AddFrame",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, FixParticlePerformer<defaulttype::Vec3fTypes> >  FixParticlePerformerVec3fClass("FixParticle",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, RemovePrimitivePerformer<defaulttype::Vec3fTypes> >  RemovePrimitivePerformerVec3fClass("RemovePrimitive",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, SuturePointPerformer<defaulttype::Vec3fTypes> >  SuturePointPerformerVec3fClass("SuturePoints",true);
#endif
#ifndef SOFA_FLOAT
helper::Creator<InteractionPerformer::InteractionPerformerFactory, AttachBodyPerformer<defaulttype::Vec3dTypes> >  AttachBodyPerformerVec3dClass("AttachBody",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, AddFramePerformer<defaulttype::Vec3dTypes> >  AddFramePerformerVec3dClass("AddFrame",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, FixParticlePerformer<defaulttype::Vec3dTypes> >  FixParticlePerformerVec3dClass("FixParticle",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, RemovePrimitivePerformer<defaulttype::Vec3dTypes> >  RemovePrimitivePerformerVec3dClass("RemovePrimitive",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, SuturePointPerformer<defaulttype::Vec3dTypes> >  SuturePointPerformerVec3dClass("SuturePoints",true);
#endif
helper::Creator<InteractionPerformer::InteractionPerformerFactory, InciseAlongPathPerformer>  InciseAlongPathPerformerClass("InciseAlongPath");
helper::Creator<InteractionPerformer::InteractionPerformerFactory, PotentialInjectionPerformer> PotentialInjectionPerformerClass("SetActionPotential");
#endif

namespace gui
{

AttachOperation::AttachOperation():stiffness(1000.0)
{
};
//*******************************************************************************************
void AttachOperation::start()
{
    if (!performer)
    {
        //Creation
        performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("AttachBody", pickHandle->getInteraction()->mouseInteractor);
        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);
        //Configuration
        component::collision::AttachBodyPerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::AttachBodyPerformerConfiguration*>(performer);
        performerConfiguration->setStiffness(getStiffness());
        performerConfiguration->setArrowSize(getArrowSize());
        //Start
        performer->start();
    }
}

void AttachOperation::execution()
{
    //do nothing
}

void AttachOperation::end()
{
    pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
    delete performer; performer=0;
}

void AttachOperation::endOperation()
{
    pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
}

//*******************************************************************************************
void FixOperation::start()
{
    //Creation
    performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("FixParticle", pickHandle->getInteraction()->mouseInteractor);
    pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

    //Configuration
    component::collision::FixParticlePerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::FixParticlePerformerConfiguration*>(performer);
    performerConfiguration->setStiffness(getStiffness());
    //Start
    performer->start();
}

void FixOperation::execution()
{
}

void FixOperation::end()
{
    //do nothing
}

//*******************************************************************************************
void TopologyOperation::start()
{
    //std::cout <<"TopologyOperation::start()"<< std::endl;

    if (getTopologicalOperation() == 0)  // Remove one element
    {
        performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("RemovePrimitive", pickHandle->getInteraction()->mouseInteractor);
        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

        performer->start();
    }
    else if (getTopologicalOperation() == 1)
    {
        if (firstClick)
        {
            performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("RemovePrimitive", pickHandle->getInteraction()->mouseInteractor);
            pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

            component::collision::RemovePrimitivePerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::RemovePrimitivePerformerConfiguration*>(performer);

            performerConfiguration->setTopologicalOperation( getTopologicalOperation() );
            performerConfiguration->setVolumicMesh( getVolumicMesh() );
            performerConfiguration->setScale( getScale() );

            performer->start();
            firstClick = false;
        }
        else
        {
            performer->start();
            firstClick = true;
        }
    }
}

void TopologyOperation::execution()
{
//       performer->execute();
}

void TopologyOperation::end()
{
    if (getTopologicalOperation() == 0 || (getTopologicalOperation() == 1 && firstClick))
    {
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
        delete performer; performer=0;
    }

}

void TopologyOperation::endOperation()
{
    if (performer)
    {
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
        delete performer; performer=0;
        firstClick = true;
    }
}

//*******************************************************************************************
void InciseOperation::start()
{
    int currentMethod = getIncisionMethod();

    if (!startPerformer)
    {
        startPerformer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("InciseAlongPath", pickHandle->getInteraction()->mouseInteractor);
        component::collision::InciseAlongPathPerformerConfiguration *performerConfigurationStart=dynamic_cast<component::collision::InciseAlongPathPerformerConfiguration*>(startPerformer);
        performerConfigurationStart->setIncisionMethod(getIncisionMethod());
        performerConfigurationStart->setSnapingBorderValue(getSnapingBorderValue());
        performerConfigurationStart->setSnapingValue(getSnapingValue());

        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(startPerformer);
        startPerformer->setPerformerFreeze();
        startPerformer->start();
    }

    if (currentMethod == 0) // incision clic by clic.
    {
        if (cpt == 0) // First clic => initialisation
        {
            performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("InciseAlongPath", pickHandle->getInteraction()->mouseInteractor);

            component::collision::InciseAlongPathPerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::InciseAlongPathPerformerConfiguration*>(performer);
            performerConfiguration->setIncisionMethod(getIncisionMethod());
            performerConfiguration->setSnapingBorderValue(getSnapingBorderValue());
            performerConfiguration->setSnapingValue(getSnapingValue());
            performerConfiguration->setCompleteIncision(getCompleteIncision());
            performerConfiguration->setKeepPoint(getKeepPoint());

            pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);
            performer->start();
            cpt++;
        }
        else // Second clic(s) only perform start() method
        {
            performer->start();
            startPerformer->start();
        }
    }
    else
    {
        if (cpt != 0)
        {
            pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
            delete performer; performer=0;
        }
        performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("InciseAlongPath", pickHandle->getInteraction()->mouseInteractor);

        component::collision::InciseAlongPathPerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::InciseAlongPathPerformerConfiguration*>(performer);
        performerConfiguration->setIncisionMethod(getIncisionMethod());
        performerConfiguration->setSnapingBorderValue(getSnapingBorderValue());
        performerConfiguration->setSnapingValue(getSnapingValue());

        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);
        performer->start();
        cpt++;
    }
}

void InciseOperation::execution()
{
}

void InciseOperation::end()
{
}

void InciseOperation::endOperation()
{
    // On fini la coupure ici!
    if (getCompleteIncision() && startPerformer)
    {
        startPerformer->setPerformerFreeze();

        //Remove startPerformer
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(startPerformer);
        delete startPerformer; startPerformer=0;
    }

    if (!getKeepPoint())
    {
        cpt = 0; //reinitialization
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
        delete performer; performer=0;
    }
}

InciseOperation::~InciseOperation()
{
    if (performer)
    {
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
        delete performer; performer=0;
    }
}

void AddFrameOperation::start()
{
    //Creation
    performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("AddFrame", pickHandle->getInteraction()->mouseInteractor);
    pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);
    //Start
    performer->start();
}

//*******************************************************************************************
void AddSutureOperation::start()
{
    //Creation
    if (!performer) //first clic
    {
        performer = component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("SuturePoints", pickHandle->getInteraction()->mouseInteractor);
        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

        //configuration
        component::collision::SuturePointPerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::SuturePointPerformerConfiguration*>(performer);
        performerConfiguration->setStiffness(getStiffness());
        performerConfiguration->setDamping(getDamping());
    }

    //Start
    performer->start();
}

void AddSutureOperation::endOperation()
{
    pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
    delete performer; performer=0;
}
}
}
<commit_msg>r6878/sofa-dev : FIX: vc2008. <commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/gui/MouseOperations.h>
#include <sofa/gui/PickHandler.h>
#include <sofa/component/collision/InteractionPerformer.h>

#include <sofa/component/collision/ComponentMouseInteraction.h>
#include <sofa/component/collision/AttachBodyPerformer.h>
#include <sofa/component/collision/FixParticlePerformer.h>
#include <sofa/component/collision/RemovePrimitivePerformer.h>
#include <sofa/component/collision/InciseAlongPathPerformer.h>
#include <sofa/component/collision/AddFramePerformer.h>
#include <sofa/component/collision/SuturePointPerformer.h>

namespace sofa
{

using namespace component::collision;

#ifdef WIN32
#ifndef SOFA_DOUBLE
helper::Creator<InteractionPerformer::InteractionPerformerFactory, AttachBodyPerformer<defaulttype::Vec3fTypes> >  AttachBodyPerformerVec3fClass("AttachBody",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, AddFramePerformer<defaulttype::Vec3fTypes> >  AddFramePerformerVec3fClass("AddFrame",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, FixParticlePerformer<defaulttype::Vec3fTypes> >  FixParticlePerformerVec3fClass("FixParticle",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, RemovePrimitivePerformer<defaulttype::Vec3fTypes> >  RemovePrimitivePerformerVec3fClass("RemovePrimitive",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, SuturePointPerformer<defaulttype::Vec3fTypes> >  SuturePointPerformerVec3fClass("SuturePoints",true);
#endif
#ifndef SOFA_FLOAT
helper::Creator<InteractionPerformer::InteractionPerformerFactory, AttachBodyPerformer<defaulttype::Vec3dTypes> >  AttachBodyPerformerVec3dClass("AttachBody",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, AddFramePerformer<defaulttype::Vec3dTypes> >  AddFramePerformerVec3dClass("AddFrame",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, FixParticlePerformer<defaulttype::Vec3dTypes> >  FixParticlePerformerVec3dClass("FixParticle",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, RemovePrimitivePerformer<defaulttype::Vec3dTypes> >  RemovePrimitivePerformerVec3dClass("RemovePrimitive",true);
helper::Creator<InteractionPerformer::InteractionPerformerFactory, SuturePointPerformer<defaulttype::Vec3dTypes> >  SuturePointPerformerVec3dClass("SuturePoints",true);
#endif
helper::Creator<InteractionPerformer::InteractionPerformerFactory, InciseAlongPathPerformer>  InciseAlongPathPerformerClass("InciseAlongPath");
#endif

namespace gui
{

AttachOperation::AttachOperation():stiffness(1000.0)
{
};
//*******************************************************************************************
void AttachOperation::start()
{
    if (!performer)
    {
        //Creation
        performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("AttachBody", pickHandle->getInteraction()->mouseInteractor);
        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);
        //Configuration
        component::collision::AttachBodyPerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::AttachBodyPerformerConfiguration*>(performer);
        performerConfiguration->setStiffness(getStiffness());
        performerConfiguration->setArrowSize(getArrowSize());
        //Start
        performer->start();
    }
}

void AttachOperation::execution()
{
    //do nothing
}

void AttachOperation::end()
{
    pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
    delete performer; performer=0;
}

void AttachOperation::endOperation()
{
    pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
}

//*******************************************************************************************
void FixOperation::start()
{
    //Creation
    performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("FixParticle", pickHandle->getInteraction()->mouseInteractor);
    pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

    //Configuration
    component::collision::FixParticlePerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::FixParticlePerformerConfiguration*>(performer);
    performerConfiguration->setStiffness(getStiffness());
    //Start
    performer->start();
}

void FixOperation::execution()
{
}

void FixOperation::end()
{
    //do nothing
}

//*******************************************************************************************
void TopologyOperation::start()
{
    //std::cout <<"TopologyOperation::start()"<< std::endl;

    if (getTopologicalOperation() == 0)  // Remove one element
    {
        performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("RemovePrimitive", pickHandle->getInteraction()->mouseInteractor);
        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

        performer->start();
    }
    else if (getTopologicalOperation() == 1)
    {
        if (firstClick)
        {
            performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("RemovePrimitive", pickHandle->getInteraction()->mouseInteractor);
            pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

            component::collision::RemovePrimitivePerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::RemovePrimitivePerformerConfiguration*>(performer);

            performerConfiguration->setTopologicalOperation( getTopologicalOperation() );
            performerConfiguration->setVolumicMesh( getVolumicMesh() );
            performerConfiguration->setScale( getScale() );

            performer->start();
            firstClick = false;
        }
        else
        {
            performer->start();
            firstClick = true;
        }
    }
}

void TopologyOperation::execution()
{
//       performer->execute();
}

void TopologyOperation::end()
{
    if (getTopologicalOperation() == 0 || (getTopologicalOperation() == 1 && firstClick))
    {
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
        delete performer; performer=0;
    }

}

void TopologyOperation::endOperation()
{
    if (performer)
    {
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
        delete performer; performer=0;
        firstClick = true;
    }
}

//*******************************************************************************************
void InciseOperation::start()
{
    int currentMethod = getIncisionMethod();

    if (!startPerformer)
    {
        startPerformer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("InciseAlongPath", pickHandle->getInteraction()->mouseInteractor);
        component::collision::InciseAlongPathPerformerConfiguration *performerConfigurationStart=dynamic_cast<component::collision::InciseAlongPathPerformerConfiguration*>(startPerformer);
        performerConfigurationStart->setIncisionMethod(getIncisionMethod());
        performerConfigurationStart->setSnapingBorderValue(getSnapingBorderValue());
        performerConfigurationStart->setSnapingValue(getSnapingValue());

        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(startPerformer);
        startPerformer->setPerformerFreeze();
        startPerformer->start();
    }

    if (currentMethod == 0) // incision clic by clic.
    {
        if (cpt == 0) // First clic => initialisation
        {
            performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("InciseAlongPath", pickHandle->getInteraction()->mouseInteractor);

            component::collision::InciseAlongPathPerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::InciseAlongPathPerformerConfiguration*>(performer);
            performerConfiguration->setIncisionMethod(getIncisionMethod());
            performerConfiguration->setSnapingBorderValue(getSnapingBorderValue());
            performerConfiguration->setSnapingValue(getSnapingValue());
            performerConfiguration->setCompleteIncision(getCompleteIncision());
            performerConfiguration->setKeepPoint(getKeepPoint());

            pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);
            performer->start();
            cpt++;
        }
        else // Second clic(s) only perform start() method
        {
            performer->start();
            startPerformer->start();
        }
    }
    else
    {
        if (cpt != 0)
        {
            pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
            delete performer; performer=0;
        }
        performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("InciseAlongPath", pickHandle->getInteraction()->mouseInteractor);

        component::collision::InciseAlongPathPerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::InciseAlongPathPerformerConfiguration*>(performer);
        performerConfiguration->setIncisionMethod(getIncisionMethod());
        performerConfiguration->setSnapingBorderValue(getSnapingBorderValue());
        performerConfiguration->setSnapingValue(getSnapingValue());

        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);
        performer->start();
        cpt++;
    }
}

void InciseOperation::execution()
{
}

void InciseOperation::end()
{
}

void InciseOperation::endOperation()
{
    // On fini la coupure ici!
    if (getCompleteIncision() && startPerformer)
    {
        startPerformer->setPerformerFreeze();

        //Remove startPerformer
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(startPerformer);
        delete startPerformer; startPerformer=0;
    }

    if (!getKeepPoint())
    {
        cpt = 0; //reinitialization
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
        delete performer; performer=0;
    }
}

InciseOperation::~InciseOperation()
{
    if (performer)
    {
        pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
        delete performer; performer=0;
    }
}

void AddFrameOperation::start()
{
    //Creation
    performer=component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("AddFrame", pickHandle->getInteraction()->mouseInteractor);
    pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);
    //Start
    performer->start();
}

//*******************************************************************************************
void AddSutureOperation::start()
{
    //Creation
    if (!performer) //first clic
    {
        performer = component::collision::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("SuturePoints", pickHandle->getInteraction()->mouseInteractor);
        pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

        //configuration
        component::collision::SuturePointPerformerConfiguration *performerConfiguration=dynamic_cast<component::collision::SuturePointPerformerConfiguration*>(performer);
        performerConfiguration->setStiffness(getStiffness());
        performerConfiguration->setDamping(getDamping());
    }

    //Start
    performer->start();
}

void AddSutureOperation::endOperation()
{
    pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
    delete performer; performer=0;
}
}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2018-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <folly/Benchmark.h>
#include <folly/io/async/EventBase.h>
#include <folly/synchronization/Baton.h>
#include <condition_variable>
#include <mutex>
#include <thread>

using namespace folly;

static size_t constexpr kMaxRead = 20;

void runTest(int iters, int numThreads) {
  BenchmarkSuspender susp;
  EventBase evb;
  evb.setMaxReadAtOnce(kMaxRead);

  std::mutex m;
  std::condition_variable cv;
  int numRunning = 0;
  int numProcessed = 0;
  int numTotal = iters * numThreads;

  std::vector<std::thread> threads;
  for (int i = 0; i < numThreads; i++) {
    threads.push_back(std::thread([&]() mutable {
      // wait for all the threads to start up
      bool notifyAll = false;
      {
        std::lock_guard<std::mutex> lk(m);
        if (++numRunning == numThreads) {
          notifyAll = true;
          susp.dismiss();
        }
      }

      if (notifyAll) {
        cv.notify_all();
      } else {
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, [&]() { return numRunning == numThreads; });
      }

      for (auto j = 0; j < iters; j++) {
        evb.runInEventBaseThread([&]() mutable {
          if (++numProcessed == numTotal) {
            evb.terminateLoopSoon();
            ;
          }
        });
      }
    }));
  }

  evb.loopForever();
  susp.rehire();

  for (auto& t : threads) {
    t.join();
  }
}

BENCHMARK_PARAM(runTest, 1)
BENCHMARK_PARAM(runTest, 2)
BENCHMARK_PARAM(runTest, 4)
BENCHMARK_PARAM(runTest, 8)
BENCHMARK_PARAM(runTest, 16)
BENCHMARK_PARAM(runTest, 32)

int main(int argc, char* argv[]) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  folly::runBenchmarks();

  return 0;
}
<commit_msg>NotificationQueueBenchmark add zero congestion benchmarks<commit_after>/*
 * Copyright 2018-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <folly/Benchmark.h>
#include <folly/io/async/EventBase.h>
#include <folly/io/async/NotificationQueue.h>
#include <folly/synchronization/Baton.h>
#include <condition_variable>
#include <mutex>
#include <thread>

using namespace folly;

static size_t constexpr kMaxRead = 20;

class MockConsumer : public NotificationQueue<Func>::Consumer {
 public:
  void messageAvailable(Func&& message) noexcept override {
    message();
  }
};

void runTest(int iters, int numThreads) {
  BenchmarkSuspender susp;
  EventBase evb;
  evb.setMaxReadAtOnce(kMaxRead);

  std::mutex m;
  std::condition_variable cv;
  int numRunning = 0;
  int numProcessed = 0;
  int numTotal = iters * numThreads;

  std::vector<std::thread> threads;
  for (int i = 0; i < numThreads; i++) {
    threads.push_back(std::thread([&]() mutable {
      // wait for all the threads to start up
      bool notifyAll = false;
      {
        std::lock_guard<std::mutex> lk(m);
        if (++numRunning == numThreads) {
          notifyAll = true;
          susp.dismiss();
        }
      }

      if (notifyAll) {
        cv.notify_all();
      } else {
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, [&]() { return numRunning == numThreads; });
      }

      for (auto j = 0; j < iters; j++) {
        evb.runInEventBaseThread([&]() mutable {
          if (++numProcessed == numTotal) {
            evb.terminateLoopSoon();
            ;
          }
        });
      }
    }));
  }

  evb.loopForever();
  susp.rehire();

  for (auto& t : threads) {
    t.join();
  }
}

BENCHMARK(EnqueueBenchmark, n) {
  BenchmarkSuspender suspender;
  NotificationQueue<Func> queue;
  suspender.dismiss();
  for (unsigned int i = 0; i < n; ++i) {
    queue.putMessage(Func());
  }
  suspender.rehire();
}

BENCHMARK(DequeueBenchmark, n) {
  BenchmarkSuspender suspender;
  NotificationQueue<Func> queue;
  EventBase base;
  MockConsumer consumer;
  consumer.setMaxReadAtOnce(kMaxRead);
  consumer.startConsumingInternal(&base, &queue);
  for (unsigned int i = 0; i < n; ++i) {
    queue.putMessage([]() {});
  }
  suspender.dismiss();
  for (unsigned int i = 0; i <= (n / kMaxRead); ++i) {
    consumer.handlerReady(0);
  }
  suspender.rehire();
  if (queue.size() > 0) {
    throw std::logic_error("This should not happen batching might be broken");
  }
  consumer.stopConsuming();
}

BENCHMARK_PARAM(runTest, 1)
BENCHMARK_PARAM(runTest, 2)
BENCHMARK_PARAM(runTest, 4)
BENCHMARK_PARAM(runTest, 8)
BENCHMARK_PARAM(runTest, 16)
BENCHMARK_PARAM(runTest, 32)

int main(int argc, char* argv[]) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  folly::runBenchmarks();

  return 0;
}
<|endoftext|>


<commit_before>/*
 * This file is part of cryptopp-bindings-api.
 *
 * (c) Stephen Berquet <stephen.berquet@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "src/exception/api_exception.h"
#include "src/padding/api_padding_pkcs7.h"
#include "src/utils/api_hex_utils.h"
#include "tests/test_api_assertions.h"
#include <gtest/gtest.h>
#include <string>

TEST(PaddingPkcs7Test, inheritance) {
    CryptoppApi::PaddingPkcs7 padding;

    EXPECT_TRUE(0 != dynamic_cast<CryptoppApi::PaddingInterface*>(&padding));
}

TEST(PaddingPkcs7Test, pad) {
    CryptoppApi::PaddingPkcs7 padding;

    // build expected data
    byte *expected1         = NULL;
    byte *expected2         = NULL;
    byte *expected3         = NULL;
    byte *expected4         = NULL;
    size_t expected1Length  = 0;
    size_t expected2Length  = 0;
    size_t expected3Length  = 0;
    size_t expected4Length  = 0;
    CryptoppApi::HexUtils::hex2bin("060606060606", 12, &expected1, expected1Length);
    CryptoppApi::HexUtils::hex2bin("617a65727479060606060606", 24, &expected2, expected2Length);
    CryptoppApi::HexUtils::hex2bin("7177657274790202", 16, &expected3, expected3Length);
    CryptoppApi::HexUtils::hex2bin("77786376626e0202", 16, &expected4, expected4Length);

    // build actual data
    std::string input2Str("azerty");
    std::string input3Str("qwerty");
    std::string input4Str("wxcvbn");
    const byte *input2 = reinterpret_cast<const byte*>(input2Str.c_str());
    const byte *input3 = reinterpret_cast<const byte*>(input3Str.c_str());
    const byte *input4 = reinterpret_cast<const byte*>(input4Str.c_str());

    byte *output1;
    byte *output2;
    byte *output3;
    byte *output4;
    size_t output1Length = 0;
    size_t output2Length = 0;
    size_t output3Length = 0;
    size_t output4Length = 0;
    padding.pad(6, NULL, 0, &output1, output1Length);
    padding.pad(6, input2, input2Str.length(), &output2, output2Length);
    padding.pad(8, input3, input3Str.length(), &output3, output3Length);
    padding.pad(4, input4, input4Str.length(), &output4, output4Length);

    // test data
    EXPECT_BYTE_ARRAY_EQ(expected1, expected1Length, output1, output1Length);
    EXPECT_BYTE_ARRAY_EQ(expected2, expected2Length, output2, output2Length);
    EXPECT_BYTE_ARRAY_EQ(expected3, expected3Length, output3, output3Length);
    EXPECT_BYTE_ARRAY_EQ(expected4, expected4Length, output4, output4Length);

    delete[] expected1;
    delete[] expected2;
    delete[] expected3;
    delete[] expected4;
    delete[] output1;
    delete[] output2;
    delete[] output3;
    delete[] output4;
}

TEST(PaddingPkcs7Test, unpad) {
    CryptoppApi::PaddingPkcs7 padding;

    // build expected data
    std::string expected2Str("azerty");
    std::string expected3Str("qwerty");
    std::string expected4Str("wxcvbn");
    const byte *expected1   = NULL;
    const byte *expected2   = reinterpret_cast<const byte*>(expected2Str.c_str());
    const byte *expected3   = reinterpret_cast<const byte*>(expected3Str.c_str());
    const byte *expected4   = reinterpret_cast<const byte*>(expected4Str.c_str());
    size_t expected1Length  = 0;
    size_t expected2Length  = expected2Str.length();
    size_t expected3Length  = expected3Str.length();
    size_t expected4Length  = expected4Str.length();

    // build actual data
    byte *input1        = NULL;
    byte *input2        = NULL;
    byte *input3        = NULL;
    byte *input4        = NULL;
    size_t input1Length = 0;
    size_t input2Length = 0;
    size_t input3Length = 0;
    size_t input4Length = 0;
    CryptoppApi::HexUtils::hex2bin("060606060606", 12, &input1, input1Length);
    CryptoppApi::HexUtils::hex2bin("617a65727479060606060606", 24, &input2, input2Length);
    CryptoppApi::HexUtils::hex2bin("7177657274790202", 16, &input3, input3Length);
    CryptoppApi::HexUtils::hex2bin("77786376626e0202", 16, &input4, input4Length);

    byte *output1;
    byte *output2;
    byte *output3;
    byte *output4;
    size_t output1Length = 0;
    size_t output2Length = 0;
    size_t output3Length = 0;
    size_t output4Length = 0;
    padding.unpad(6, input1, input1Length, &output1, output1Length);
    padding.unpad(6, input2, input2Length, &output2, output2Length);
    padding.unpad(8, input3, input3Length, &output3, output3Length);
    padding.unpad(4, input4, input4Length, &output4, output4Length);

    // test data
    EXPECT_BYTE_ARRAY_EQ(expected1, expected1Length, output1, output1Length);
    EXPECT_BYTE_ARRAY_EQ(expected2, expected2Length, output2, output2Length);
    EXPECT_BYTE_ARRAY_EQ(expected3, expected3Length, output3, output3Length);
    EXPECT_BYTE_ARRAY_EQ(expected4, expected4Length, output4, output4Length);

    delete[] input1;
    delete[] input2;
    delete[] input3;
    delete[] input4;
    delete[] output1;
    delete[] output2;
    delete[] output3;
    delete[] output4;
}

TEST(PaddingPkcs7Test, can) {
    CryptoppApi::PaddingPkcs7 padding;
    EXPECT_TRUE(padding.canPad());
    EXPECT_TRUE(padding.canUnpad());
}

TEST(PaddingPkcs7Test, largeData) {
    CryptoppApi::PaddingPkcs7 padding;
    size_t input1Length     = 10485760;
    size_t input2Length     = input1Length + 16;
    byte *input1            = new byte[input1Length];
    byte *input2            = new byte[input2Length];
    byte *output1;
    byte *output2;
    size_t output1Length    = 0;
    size_t output2Length    = 0;

    memset(input2 + input1Length, 16, 16);
    padding.pad(16, input1, input1Length, &output1, output1Length);
    padding.unpad(16, input2, input2Length, &output2, output2Length);

    EXPECT_EQ(input2Length, output1Length);
    EXPECT_EQ(input1Length, output2Length);

    delete[] input1;
    delete[] input2;
    delete[] output1;
    delete[] output2;
}

TEST(PaddingPkcs7Test, padErrors) {
    CryptoppApi::PaddingPkcs7 padding;
    byte *output;
    size_t outputLength = 0;

    EXPECT_THROW_MSG(padding.pad(0, NULL, 0, &output, outputLength), CryptoppApi::Exception, "block size cannot be lower than 1, 0 given");
    EXPECT_THROW_MSG(padding.pad(257, NULL, 0, &output, outputLength), CryptoppApi::Exception, "PKCS #7 padding does not handle block sizes higher than 256");
}

TEST(PaddingPkcs7Test, unpadErrors) {
    CryptoppApi::PaddingPkcs7 padding;
    byte *output;
    size_t outputLength = 0;

    EXPECT_THROW_MSG(padding.unpad(0, NULL, 0, &output, outputLength), CryptoppApi::Exception, "block size cannot be lower than 1, 0 given");
    EXPECT_THROW_MSG(padding.unpad(257, NULL, 0, &output, outputLength), CryptoppApi::Exception, "PKCS #7 padding does not handle block sizes higher than 256");

    std::string input1  = "123";
    std::string input2  = "1234";
    byte *input3        = NULL;
    size_t input1Length = 0;
    CryptoppApi::HexUtils::hex2bin("04040304", 4, &input3, input1Length);

    EXPECT_THROW_MSG(padding.unpad(4, reinterpret_cast<const byte*>(input1.c_str()), input1.length(), &output, outputLength), CryptoppApi::Exception, "data length is not a multiple of block size (block size is 4, data size is 3)");
    EXPECT_THROW_MSG(padding.unpad(4, reinterpret_cast<const byte*>(input2.c_str()), input2.length(), &output, outputLength), CryptoppApi::Exception, "invalid PKCS #7 block padding found");
    EXPECT_THROW_MSG(padding.unpad(4, input3, 4, &output, outputLength), CryptoppApi::Exception, "invalid PKCS #7 block padding found");
}
<commit_msg>fixed pkcs7 unit test<commit_after>/*
 * This file is part of cryptopp-bindings-api.
 *
 * (c) Stephen Berquet <stephen.berquet@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "src/exception/api_exception.h"
#include "src/padding/api_padding_pkcs7.h"
#include "src/utils/api_hex_utils.h"
#include "tests/test_api_assertions.h"
#include <gtest/gtest.h>
#include <string>

TEST(PaddingPkcs7Test, inheritance) {
    CryptoppApi::PaddingPkcs7 padding;

    EXPECT_TRUE(0 != dynamic_cast<CryptoppApi::PaddingInterface*>(&padding));
}

TEST(PaddingPkcs7Test, pad) {
    CryptoppApi::PaddingPkcs7 padding;

    // build expected data
    byte *expected1         = NULL;
    byte *expected2         = NULL;
    byte *expected3         = NULL;
    byte *expected4         = NULL;
    size_t expected1Length  = 0;
    size_t expected2Length  = 0;
    size_t expected3Length  = 0;
    size_t expected4Length  = 0;
    CryptoppApi::HexUtils::hex2bin("060606060606", 12, &expected1, expected1Length);
    CryptoppApi::HexUtils::hex2bin("617a65727479060606060606", 24, &expected2, expected2Length);
    CryptoppApi::HexUtils::hex2bin("7177657274790202", 16, &expected3, expected3Length);
    CryptoppApi::HexUtils::hex2bin("77786376626e0202", 16, &expected4, expected4Length);

    // build actual data
    std::string input2Str("azerty");
    std::string input3Str("qwerty");
    std::string input4Str("wxcvbn");
    const byte *input2 = reinterpret_cast<const byte*>(input2Str.c_str());
    const byte *input3 = reinterpret_cast<const byte*>(input3Str.c_str());
    const byte *input4 = reinterpret_cast<const byte*>(input4Str.c_str());

    byte *output1;
    byte *output2;
    byte *output3;
    byte *output4;
    size_t output1Length = 0;
    size_t output2Length = 0;
    size_t output3Length = 0;
    size_t output4Length = 0;
    padding.pad(6, NULL, 0, &output1, output1Length);
    padding.pad(6, input2, input2Str.length(), &output2, output2Length);
    padding.pad(8, input3, input3Str.length(), &output3, output3Length);
    padding.pad(4, input4, input4Str.length(), &output4, output4Length);

    // test data
    EXPECT_BYTE_ARRAY_EQ(expected1, expected1Length, output1, output1Length);
    EXPECT_BYTE_ARRAY_EQ(expected2, expected2Length, output2, output2Length);
    EXPECT_BYTE_ARRAY_EQ(expected3, expected3Length, output3, output3Length);
    EXPECT_BYTE_ARRAY_EQ(expected4, expected4Length, output4, output4Length);

    delete[] expected1;
    delete[] expected2;
    delete[] expected3;
    delete[] expected4;
    delete[] output1;
    delete[] output2;
    delete[] output3;
    delete[] output4;
}

TEST(PaddingPkcs7Test, unpad) {
    CryptoppApi::PaddingPkcs7 padding;

    // build expected data
    std::string expected2Str("azerty");
    std::string expected3Str("qwerty");
    std::string expected4Str("wxcvbn");
    const byte *expected1   = NULL;
    const byte *expected2   = reinterpret_cast<const byte*>(expected2Str.c_str());
    const byte *expected3   = reinterpret_cast<const byte*>(expected3Str.c_str());
    const byte *expected4   = reinterpret_cast<const byte*>(expected4Str.c_str());
    size_t expected1Length  = 0;
    size_t expected2Length  = expected2Str.length();
    size_t expected3Length  = expected3Str.length();
    size_t expected4Length  = expected4Str.length();

    // build actual data
    byte *input1        = NULL;
    byte *input2        = NULL;
    byte *input3        = NULL;
    byte *input4        = NULL;
    size_t input1Length = 0;
    size_t input2Length = 0;
    size_t input3Length = 0;
    size_t input4Length = 0;
    CryptoppApi::HexUtils::hex2bin("060606060606", 12, &input1, input1Length);
    CryptoppApi::HexUtils::hex2bin("617a65727479060606060606", 24, &input2, input2Length);
    CryptoppApi::HexUtils::hex2bin("7177657274790202", 16, &input3, input3Length);
    CryptoppApi::HexUtils::hex2bin("77786376626e0202", 16, &input4, input4Length);

    byte *output1;
    byte *output2;
    byte *output3;
    byte *output4;
    size_t output1Length = 0;
    size_t output2Length = 0;
    size_t output3Length = 0;
    size_t output4Length = 0;
    padding.unpad(6, input1, input1Length, &output1, output1Length);
    padding.unpad(6, input2, input2Length, &output2, output2Length);
    padding.unpad(8, input3, input3Length, &output3, output3Length);
    padding.unpad(4, input4, input4Length, &output4, output4Length);

    // test data
    EXPECT_BYTE_ARRAY_EQ(expected1, expected1Length, output1, output1Length);
    EXPECT_BYTE_ARRAY_EQ(expected2, expected2Length, output2, output2Length);
    EXPECT_BYTE_ARRAY_EQ(expected3, expected3Length, output3, output3Length);
    EXPECT_BYTE_ARRAY_EQ(expected4, expected4Length, output4, output4Length);

    delete[] input1;
    delete[] input2;
    delete[] input3;
    delete[] input4;
    delete[] output1;
    delete[] output2;
    delete[] output3;
    delete[] output4;
}

TEST(PaddingPkcs7Test, can) {
    CryptoppApi::PaddingPkcs7 padding;
    EXPECT_TRUE(padding.canPad());
    EXPECT_TRUE(padding.canUnpad());
}

TEST(PaddingPkcs7Test, largeData) {
    CryptoppApi::PaddingPkcs7 padding;
    size_t input1Length     = 10485760;
    size_t input2Length     = input1Length + 16;
    byte *input1            = new byte[input1Length];
    byte *input2            = new byte[input2Length];
    byte *output1;
    byte *output2;
    size_t output1Length    = 0;
    size_t output2Length    = 0;

    memset(input2 + input1Length, 16, 16);
    padding.pad(16, input1, input1Length, &output1, output1Length);
    padding.unpad(16, input2, input2Length, &output2, output2Length);

    EXPECT_EQ(input2Length, output1Length);
    EXPECT_EQ(input1Length, output2Length);

    delete[] input1;
    delete[] input2;
    delete[] output1;
    delete[] output2;
}

TEST(PaddingPkcs7Test, padErrors) {
    CryptoppApi::PaddingPkcs7 padding;
    byte *output;
    size_t outputLength = 0;

    EXPECT_THROW_MSG(padding.pad(0, NULL, 0, &output, outputLength), CryptoppApi::Exception, "block size cannot be lower than 1, 0 given");
    EXPECT_THROW_MSG(padding.pad(257, NULL, 0, &output, outputLength), CryptoppApi::Exception, "PKCS #7 padding does not handle block sizes higher than 256");
}

TEST(PaddingPkcs7Test, unpadErrors) {
    CryptoppApi::PaddingPkcs7 padding;
    byte *output;
    size_t outputLength = 0;

    EXPECT_THROW_MSG(padding.unpad(0, NULL, 0, &output, outputLength), CryptoppApi::Exception, "block size cannot be lower than 1, 0 given");
    EXPECT_THROW_MSG(padding.unpad(257, NULL, 0, &output, outputLength), CryptoppApi::Exception, "PKCS #7 padding does not handle block sizes higher than 256");

    std::string input1  = "123";
    std::string input2  = "1234";
    byte *input3        = NULL;
    size_t input1Length = 0;
    CryptoppApi::HexUtils::hex2bin("04040304", 8, &input3, input1Length);

    EXPECT_THROW_MSG(padding.unpad(4, reinterpret_cast<const byte*>(input1.c_str()), input1.length(), &output, outputLength), CryptoppApi::Exception, "data length is not a multiple of block size (block size is 4, data size is 3)");
    EXPECT_THROW_MSG(padding.unpad(4, reinterpret_cast<const byte*>(input2.c_str()), input2.length(), &output, outputLength), CryptoppApi::Exception, "invalid PKCS #7 block padding found");
    EXPECT_THROW_MSG(padding.unpad(4, input3, 4, &output, outputLength), CryptoppApi::Exception, "invalid PKCS #7 block padding found");

    delete[] input3;
}
<|endoftext|>