<commit_before>/**
* Copyright (C) Mellanox Technologies Ltd. 2001-2014.  ALL RIGHTS RESERVED.
* Copyright (C) UT-Battelle, LLC. 2015. ALL RIGHTS RESERVED.
*
* See file LICENSE for terms.
*/

#include "test_ucp_tag.h"

#include <common/test_helpers.h>

class test_ucp_tag_probe : public test_ucp_tag {
public:
    using test_ucp_tag::get_ctx_params;

    /* The parameters mean the following:
     *  - s_size and r_size: send and recv buffer sizes.
     *    Can be different for checking message transaction error
     *  - is_sync: specifies the type of send function to be used
     *    (sync or not)
     *  - is_recv_msg: specifies whether probe function needs to remove
     *    matched message. If yes, then ucp_tag_msg_recv_nb is used for
     *    receive
     * */
    void test_send_probe (size_t s_size, size_t r_size, bool is_sync,
                          int is_recv_msg) {
        ucp_tag_recv_info info;
        ucp_tag_message_h message;
        request *send_req = NULL, *recv_req = NULL;

        std::vector<char> sendbuf(s_size, 0);
        std::vector<char> recvbuf(r_size, 0);

        ucs::fill_random(sendbuf.begin(), sendbuf.end());

        message = ucp_tag_probe_nb(receiver().worker(), 0x1337, 0xffff,
                                   is_recv_msg, &info);
        EXPECT_TRUE(message == NULL);

        if (is_sync) {
            send_req = send_sync_nb(&sendbuf[0], sendbuf.size(), DATATYPE,
                                    0x111337);

        } else {
            send_b(&sendbuf[0], sendbuf.size(), DATATYPE, 0x111337);
        }

        do {
            progress();
            message = ucp_tag_probe_nb(receiver().worker(), 0x1337, 0xffff,
                                       is_recv_msg, &info);
        } while (message == NULL);

        EXPECT_EQ(sendbuf.size(),      info.length);
        EXPECT_EQ((ucp_tag_t)0x111337, info.sender_tag);

        if (is_recv_msg == 0) {
            recv_req = recv_nb(&recvbuf[0], recvbuf.size(), DATATYPE,
                               0x1337, 0xffff);
        } else {
            recv_req = (request*)ucp_tag_msg_recv_nb(receiver().worker(),
                                                     &recvbuf[0],recvbuf.size(),
                                                     DATATYPE, message, recv_callback);
            ASSERT_TRUE(!UCS_PTR_IS_ERR(recv_req));
        }

        wait(recv_req);
        EXPECT_TRUE(recv_req->completed);
        if (s_size != r_size) {
            /* Test for correct msg transaction handling */
            EXPECT_EQ(UCS_ERR_MESSAGE_TRUNCATED, recv_req->status);
        } else {
            /* Everything should be received correctly */
            EXPECT_EQ(UCS_OK,              recv_req->status);
            EXPECT_EQ(sendbuf.size(),      recv_req->info.length);
            EXPECT_EQ((ucp_tag_t)0x111337, recv_req->info.sender_tag);
            EXPECT_EQ(sendbuf, recvbuf);
        }
        request_release(recv_req);

        if (is_sync) {
            wait(send_req);
            EXPECT_TRUE(send_req->completed);
            EXPECT_EQ(UCS_OK, send_req->status);
            request_release(send_req);
        }
    }

    int probe_all(std::string &recvbuf)
    {
        ucp_tag_message_h message;
        ucp_tag_recv_info_t info;
        request *req;

        int count = 0;
        for (;;) {
             message = ucp_tag_probe_nb(receiver().worker(), 0, 0, 1, &info);
             if (message == NULL) {
                 return count;
             }

             req = (request*)ucp_tag_msg_recv_nb(receiver().worker(),
                                                 &recvbuf[0], recvbuf.size(),
                                                 DATATYPE, message, recv_callback);
             wait(req);
             request_release(req);
             ++count;
        }
    }

};

UCS_TEST_P(test_ucp_tag_probe, send_probe) {
    test_send_probe (8, 8, false, 0);
    test_send_probe (8, 8, true,  0);
}

UCS_TEST_P(test_ucp_tag_probe, send_medium_msg_probe) {
    test_send_probe (50000, 50000, false, 1);
    test_send_probe (50000, 50000, true,  1);
}

UCS_TEST_P(test_ucp_tag_probe, send_medium_msg_probe_truncated) {
    test_send_probe (50000, 0, false, 1);
    test_send_probe (50000, 0, true,  1);
}

UCS_TEST_P(test_ucp_tag_probe, send_rndv_msg_probe, "RNDV_THRESH=1048576") {
    static const size_t size = 1148576;
    ucp_tag_recv_info info;
    ucp_tag_message_h message;
    request *my_send_req, *my_recv_req;

    if (&sender() == &receiver()) {
        UCS_TEST_SKIP_R("loop-back unsupported");
    }

    std::vector<char> sendbuf(size, 0);
    std::vector<char> recvbuf(size, 0);

    ucs::fill_random(sendbuf.begin(), sendbuf.end());

    message = ucp_tag_probe_nb(receiver().worker(), 0x1337, 0xffff, 1, &info);
    EXPECT_TRUE(message == NULL);

    /* sender - send the RTS */
    my_send_req = send_nb(&sendbuf[0], sendbuf.size(), DATATYPE, 0x111337);
    ASSERT_TRUE(!UCS_PTR_IS_ERR(my_send_req));
    EXPECT_FALSE(my_send_req->completed);

    /* receiver - get the RTS and put it into unexpected */
    short_progress_loop();

    /* receiver - match the rts, remove it from unexpected and return it */
    message = ucp_tag_probe_nb(receiver().worker(), 0x1337, 0xffff, 1, &info);
    /* make sure that there was a match (RTS) */
    ASSERT_TRUE(message != NULL);
    EXPECT_EQ(sendbuf.size(),      info.length);
    EXPECT_EQ((ucp_tag_t)0x111337, info.sender_tag);

    /* receiver - process the rts and schedule a get operation */
    my_recv_req = (request*)ucp_tag_msg_recv_nb(receiver().worker(), &recvbuf[0],
                                                recvbuf.size(), DATATYPE, message,
                                                recv_callback);
    ASSERT_TRUE(!UCS_PTR_IS_ERR(my_recv_req));

    /* receiver - perform rndv get and send the ATS */
    wait(my_recv_req);
    EXPECT_TRUE(my_recv_req->completed);

    /* sender - get the ATS and set send request to completed */
    short_progress_loop();

    EXPECT_EQ(UCS_OK,              my_recv_req->status);
    EXPECT_EQ(sendbuf.size(),      my_recv_req->info.length);
    EXPECT_EQ((ucp_tag_t)0x111337, my_recv_req->info.sender_tag);
    EXPECT_EQ(sendbuf, recvbuf);

    EXPECT_TRUE(my_send_req->completed);
    EXPECT_EQ(UCS_OK, my_send_req->status);

    request_release(my_send_req);
    request_release(my_recv_req);
}

UCS_TEST_P(test_ucp_tag_probe, limited_probe_size) {
    static const int COUNT = 1000;
    std::string sendbuf, recvbuf;
    std::vector<request*> reqs;
    ucp_tag_recv_info_t info;
    request *req;
    int recvd;

    if (&sender() == &receiver()) {
        UCS_TEST_SKIP_R("loop-back unsupported");
    }

    sendbuf.resize(100, '1');
    recvbuf.resize(100, '0');

    send_b(&sendbuf[0], sendbuf.size(), DATATYPE, 0x111337);
    recv_b(&recvbuf[0], recvbuf.size(), DATATYPE, 0x111337, 0xffffff, &info);

    /* send 1000 messages without calling progress */
    for (int i = 0; i < COUNT; ++i) {
        req = send_nb(&sendbuf[0], sendbuf.size(), DATATYPE, 0x111337);
        if (req != NULL) {
            reqs.push_back(req);
        }

        sender().progress(); /* progress only the sender */
    }

    for (int i = 0; i < 1000; ++i) {
        ucs::safe_usleep(1000);
        sender().progress();
    }

    /* progress once */
    ucp_worker_progress(receiver().worker());

    /* probe should not have too many messages here because we poll once */
    recvd = probe_all(recvbuf);
    EXPECT_LE(recvd, 32);

    /* receive all the rest */
    while (recvd < COUNT) {
        progress();
        recvd += probe_all(recvbuf);
    }

    while (!reqs.empty()) {
        wait(reqs.back());
        request_release(reqs.back());
        reqs.pop_back();
    }
}
UCP_INSTANTIATE_TEST_CASE(test_ucp_tag_probe)
<commit_msg>GTEST: don't use rndv in the probe test which uses a blocking send.<commit_after>/**
* Copyright (C) Mellanox Technologies Ltd. 2001-2014.  ALL RIGHTS RESERVED.
* Copyright (C) UT-Battelle, LLC. 2015. ALL RIGHTS RESERVED.
*
* See file LICENSE for terms.
*/

#include "test_ucp_tag.h"

#include <common/test_helpers.h>

class test_ucp_tag_probe : public test_ucp_tag {
public:
    using test_ucp_tag::get_ctx_params;

    /* The parameters mean the following:
     *  - s_size and r_size: send and recv buffer sizes.
     *    Can be different for checking message transaction error
     *  - is_sync: specifies the type of send function to be used
     *    (sync or not)
     *  - is_recv_msg: specifies whether probe function needs to remove
     *    matched message. If yes, then ucp_tag_msg_recv_nb is used for
     *    receive
     * */
    void test_send_probe (size_t s_size, size_t r_size, bool is_sync,
                          int is_recv_msg) {
        ucp_tag_recv_info info;
        ucp_tag_message_h message;
        request *send_req = NULL, *recv_req = NULL;

        std::vector<char> sendbuf(s_size, 0);
        std::vector<char> recvbuf(r_size, 0);

        ucs::fill_random(sendbuf.begin(), sendbuf.end());

        message = ucp_tag_probe_nb(receiver().worker(), 0x1337, 0xffff,
                                   is_recv_msg, &info);
        EXPECT_TRUE(message == NULL);

        if (is_sync) {
            send_req = send_sync_nb(&sendbuf[0], sendbuf.size(), DATATYPE,
                                    0x111337);

        } else {
            send_b(&sendbuf[0], sendbuf.size(), DATATYPE, 0x111337);
        }

        do {
            progress();
            message = ucp_tag_probe_nb(receiver().worker(), 0x1337, 0xffff,
                                       is_recv_msg, &info);
        } while (message == NULL);

        EXPECT_EQ(sendbuf.size(),      info.length);
        EXPECT_EQ((ucp_tag_t)0x111337, info.sender_tag);

        if (is_recv_msg == 0) {
            recv_req = recv_nb(&recvbuf[0], recvbuf.size(), DATATYPE,
                               0x1337, 0xffff);
        } else {
            recv_req = (request*)ucp_tag_msg_recv_nb(receiver().worker(),
                                                     &recvbuf[0],recvbuf.size(),
                                                     DATATYPE, message, recv_callback);
            ASSERT_TRUE(!UCS_PTR_IS_ERR(recv_req));
        }

        wait(recv_req);
        EXPECT_TRUE(recv_req->completed);
        if (s_size != r_size) {
            /* Test for correct msg transaction handling */
            EXPECT_EQ(UCS_ERR_MESSAGE_TRUNCATED, recv_req->status);
        } else {
            /* Everything should be received correctly */
            EXPECT_EQ(UCS_OK,              recv_req->status);
            EXPECT_EQ(sendbuf.size(),      recv_req->info.length);
            EXPECT_EQ((ucp_tag_t)0x111337, recv_req->info.sender_tag);
            EXPECT_EQ(sendbuf, recvbuf);
        }
        request_release(recv_req);

        if (is_sync) {
            wait(send_req);
            EXPECT_TRUE(send_req->completed);
            EXPECT_EQ(UCS_OK, send_req->status);
            request_release(send_req);
        }
    }

    int probe_all(std::string &recvbuf)
    {
        ucp_tag_message_h message;
        ucp_tag_recv_info_t info;
        request *req;

        int count = 0;
        for (;;) {
             message = ucp_tag_probe_nb(receiver().worker(), 0, 0, 1, &info);
             if (message == NULL) {
                 return count;
             }

             req = (request*)ucp_tag_msg_recv_nb(receiver().worker(),
                                                 &recvbuf[0], recvbuf.size(),
                                                 DATATYPE, message, recv_callback);
             wait(req);
             request_release(req);
             ++count;
        }
    }

};

UCS_TEST_P(test_ucp_tag_probe, send_probe) {
    test_send_probe (8, 8, false, 0);
    test_send_probe (8, 8, true,  0);
}

UCS_TEST_P(test_ucp_tag_probe, send_medium_msg_probe, "RNDV_THRESH=1048576") {
    test_send_probe (50000, 50000, false, 1);
    test_send_probe (50000, 50000, true,  1);
}

UCS_TEST_P(test_ucp_tag_probe, send_medium_msg_probe_truncated, "RNDV_THRESH=1048576") {
    test_send_probe (50000, 0, false, 1);
    test_send_probe (50000, 0, true,  1);
}

UCS_TEST_P(test_ucp_tag_probe, send_rndv_msg_probe, "RNDV_THRESH=1048576") {
    static const size_t size = 1148576;
    ucp_tag_recv_info info;
    ucp_tag_message_h message;
    request *my_send_req, *my_recv_req;

    if (&sender() == &receiver()) {
        UCS_TEST_SKIP_R("loop-back unsupported");
    }

    std::vector<char> sendbuf(size, 0);
    std::vector<char> recvbuf(size, 0);

    ucs::fill_random(sendbuf.begin(), sendbuf.end());

    message = ucp_tag_probe_nb(receiver().worker(), 0x1337, 0xffff, 1, &info);
    EXPECT_TRUE(message == NULL);

    /* sender - send the RTS */
    my_send_req = send_nb(&sendbuf[0], sendbuf.size(), DATATYPE, 0x111337);
    ASSERT_TRUE(!UCS_PTR_IS_ERR(my_send_req));
    EXPECT_FALSE(my_send_req->completed);

    /* receiver - get the RTS and put it into unexpected */
    short_progress_loop();

    /* receiver - match the rts, remove it from unexpected and return it */
    message = ucp_tag_probe_nb(receiver().worker(), 0x1337, 0xffff, 1, &info);
    /* make sure that there was a match (RTS) */
    ASSERT_TRUE(message != NULL);
    EXPECT_EQ(sendbuf.size(),      info.length);
    EXPECT_EQ((ucp_tag_t)0x111337, info.sender_tag);

    /* receiver - process the rts and schedule a get operation */
    my_recv_req = (request*)ucp_tag_msg_recv_nb(receiver().worker(), &recvbuf[0],
                                                recvbuf.size(), DATATYPE, message,
                                                recv_callback);
    ASSERT_TRUE(!UCS_PTR_IS_ERR(my_recv_req));

    /* receiver - perform rndv get and send the ATS */
    wait(my_recv_req);
    EXPECT_TRUE(my_recv_req->completed);

    /* sender - get the ATS and set send request to completed */
    short_progress_loop();

    EXPECT_EQ(UCS_OK,              my_recv_req->status);
    EXPECT_EQ(sendbuf.size(),      my_recv_req->info.length);
    EXPECT_EQ((ucp_tag_t)0x111337, my_recv_req->info.sender_tag);
    EXPECT_EQ(sendbuf, recvbuf);

    EXPECT_TRUE(my_send_req->completed);
    EXPECT_EQ(UCS_OK, my_send_req->status);

    request_release(my_send_req);
    request_release(my_recv_req);
}

UCS_TEST_P(test_ucp_tag_probe, limited_probe_size) {
    static const int COUNT = 1000;
    std::string sendbuf, recvbuf;
    std::vector<request*> reqs;
    ucp_tag_recv_info_t info;
    request *req;
    int recvd;

    if (&sender() == &receiver()) {
        UCS_TEST_SKIP_R("loop-back unsupported");
    }

    sendbuf.resize(100, '1');
    recvbuf.resize(100, '0');

    send_b(&sendbuf[0], sendbuf.size(), DATATYPE, 0x111337);
    recv_b(&recvbuf[0], recvbuf.size(), DATATYPE, 0x111337, 0xffffff, &info);

    /* send 1000 messages without calling progress */
    for (int i = 0; i < COUNT; ++i) {
        req = send_nb(&sendbuf[0], sendbuf.size(), DATATYPE, 0x111337);
        if (req != NULL) {
            reqs.push_back(req);
        }

        sender().progress(); /* progress only the sender */
    }

    for (int i = 0; i < 1000; ++i) {
        ucs::safe_usleep(1000);
        sender().progress();
    }

    /* progress once */
    ucp_worker_progress(receiver().worker());

    /* probe should not have too many messages here because we poll once */
    recvd = probe_all(recvbuf);
    EXPECT_LE(recvd, 32);

    /* receive all the rest */
    while (recvd < COUNT) {
        progress();
        recvd += probe_all(recvbuf);
    }

    while (!reqs.empty()) {
        wait(reqs.back());
        request_release(reqs.back());
        reqs.pop_back();
    }
}
UCP_INSTANTIATE_TEST_CASE(test_ucp_tag_probe)
<|endoftext|>


<commit_before><commit_msg>gui: use placed iterms and bterms to determine dbNet bounding box<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/at_exit.h"
#include "base/logging.h"
#include "gpu/demos/framework/window.h"

#if defined(OS_LINUX)
#include <gtk/gtk.h>
#endif  // OS_LINUX

namespace {
static const int kWindowWidth = 512;
static const int kWindowHeight = 512;
}  // namespace.

int main(int argc, char *argv[]) {
#if defined(OS_LINUX)
  gtk_init(&argc, &argv);
#endif  // OS_LINUX

  // AtExitManager is used by singleton classes to delete themselves when
  // the program terminates.
  base::AtExitManager at_exit_manager_;

  gpu::demos::Window window;
  CHECK(window.Init(kWindowWidth, kWindowHeight));

  window.MainLoop();
  return EXIT_SUCCESS;
}

<commit_msg>Fixed standalone command buffer demos.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "app/gfx/gl/gl_context.h"
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "gpu/demos/framework/window.h"

#if defined(OS_LINUX)
#include <gtk/gtk.h>
#endif  // OS_LINUX

namespace {
static const int kWindowWidth = 512;
static const int kWindowHeight = 512;
}  // namespace.

int main(int argc, char** argv) {
#if defined(OS_LINUX)
  gtk_init(&argc, &argv);
#endif  // OS_LINUX

  // AtExitManager is used by singleton classes to delete themselves when
  // the program terminates.
  base::AtExitManager at_exit_manager_;

  CommandLine::Init(argc, argv);

  gfx::GLContext::InitializeOneOff();

  gpu::demos::Window window;
  CHECK(window.Init(kWindowWidth, kWindowHeight));

  window.MainLoop();
  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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.
**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
**     of its contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** 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
** OWNER 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/

//! [1]
#ifdef Q_WS_MAC
    CFURLRef appUrlRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef,
                                           kCFURLPOSIXPathStyle);
    const char *pathPtr = CFStringGetCStringPtr(macPath,
                                           CFStringGetSystemEncoding());
    qDebug("Path = %s", pathPtr);
    CFRelease(appUrlRef);
    CFRelease(macPath);
#endif
//! [1]
<commit_msg>Use Q_OS_MAC, not Q_WS_MAC<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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.
**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
**     of its contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** 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
** OWNER 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/

//! [1]
#ifdef Q_OS_MAC
    CFURLRef appUrlRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef,
                                           kCFURLPOSIXPathStyle);
    const char *pathPtr = CFStringGetCStringPtr(macPath,
                                           CFStringGetSystemEncoding());
    qDebug("Path = %s", pathPtr);
    CFRelease(appUrlRef);
    CFRelease(macPath);
#endif
//! [1]
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, Elm Library Project
// 3-clause BSD License
//
//M*/
#include "elm/layers/layerfactory.h"

#include <boost/assign/list_of.hpp>

#include "elm/core/registor.h"

/** Whenever a new layer is imeplemented:
 *  1. include its header below
 *  2. Add it to the initialization of g_layerRegistry map.
 */
#include "elm/layers/attentionwindow.h"
#include "elm/layers/icp.h"
#include "elm/encoding/populationcode.h"
#include "elm/layers/saliencyitti.h"
#include "elm/layers/triangulation.h"
#include "elm/layers/weightedsum.h"

using boost::assign::map_list_of;

typedef Registor_<base_Layer> LayerRegistor;
typedef Registor_<base_Layer>::Registry LayerRegistry;

/** Macros for creating individual registry pair items
 *  credit: J. Turcot, T. Senechal, http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c
 */
#define REGISTRY_PAIR(Registor, NewInstance) (#NewInstance, &Registor::DerivedInstance<NewInstance>)
#define LAYER_REGISTRY_PAIR(NewInstance) REGISTRY_PAIR(LayerRegistor, NewInstance)

LayerRegistry g_layerRegistry = map_list_of
        LAYER_REGISTRY_PAIR( AttentionWindow )
        LAYER_REGISTRY_PAIR( ICP )
        LAYER_REGISTRY_PAIR( MutexPopulationCode )
        LAYER_REGISTRY_PAIR( SaliencyItti )
        LAYER_REGISTRY_PAIR( Triangulation )
        LAYER_REGISTRY_PAIR( WeightedSum )
        ; ///< <-- add new layer to registry here

LayerFactory::LayerFactory()
{
}

LayerRegistor::RegisteredTypeSharedPtr LayerFactory::CreateShared(const LayerType &type)
{
    return LayerRegistor::CreatePtrShared(g_layerRegistry, type);
}

LayerRegistor::RegisteredTypeSharedPtr LayerFactory::CreateShared(const LayerType &type,
                                                                          const LayerConfig &config,
                                                                          const LayerIONames &io)
{
    LayerRegistor::RegisteredTypeSharedPtr ptr = LayerFactory::CreateShared(type);
    ptr->Reset(config);
    ptr->IONames(io);
    return ptr;
}
<commit_msg>restore layer y to main layer factory<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, Elm Library Project
// 3-clause BSD License
//
//M*/
#include "elm/layers/layerfactory.h"

#include <boost/assign/list_of.hpp>

#include "elm/core/registor.h"

/** Whenever a new layer is imeplemented:
 *  1. include its header below
 *  2. Add it to the initialization of g_layerRegistry map.
 */
#include "elm/layers/attentionwindow.h"
#include "elm/layers/icp.h"
#include "elm/layers/layer_y.h"
#include "elm/encoding/populationcode.h"
#include "elm/layers/saliencyitti.h"
#include "elm/layers/triangulation.h"
#include "elm/layers/weightedsum.h"

using boost::assign::map_list_of;

typedef Registor_<base_Layer> LayerRegistor;
typedef Registor_<base_Layer>::Registry LayerRegistry;

/** Macros for creating individual registry pair items
 *  credit: J. Turcot, T. Senechal, http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c
 */
#define REGISTRY_PAIR(Registor, NewInstance) (#NewInstance, &Registor::DerivedInstance<NewInstance>)
#define LAYER_REGISTRY_PAIR(NewInstance) REGISTRY_PAIR(LayerRegistor, NewInstance)

LayerRegistry g_layerRegistry = map_list_of
        LAYER_REGISTRY_PAIR( AttentionWindow )
        LAYER_REGISTRY_PAIR( ICP )
        LAYER_REGISTRY_PAIR( LayerY )
        LAYER_REGISTRY_PAIR( MutexPopulationCode )
        LAYER_REGISTRY_PAIR( SaliencyItti )
        LAYER_REGISTRY_PAIR( Triangulation )
        LAYER_REGISTRY_PAIR( WeightedSum )
        ; ///< <-- add new layer to registry here

LayerFactory::LayerFactory()
{
}

LayerRegistor::RegisteredTypeSharedPtr LayerFactory::CreateShared(const LayerType &type)
{
    return LayerRegistor::CreatePtrShared(g_layerRegistry, type);
}

LayerRegistor::RegisteredTypeSharedPtr LayerFactory::CreateShared(const LayerType &type,
                                                                          const LayerConfig &config,
                                                                          const LayerIONames &io)
{
    LayerRegistor::RegisteredTypeSharedPtr ptr = LayerFactory::CreateShared(type);
    ptr->Reset(config);
    ptr->IONames(io);
    return ptr;
}
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, Elm Library Project
// 3-clause BSD License
//
//M*/
#include "elm/layers/layerfactory.h"

#include <boost/assign/list_of.hpp>

#include "elm/core/registor.h"

/** Whenever a new layer is imeplemented:
 *  1. include its header below
 *  2. Add it to the initialization of g_layerRegistry map.
 */
#include "elm/layers/attentionwindow.h"
#include "elm/layers/icp.h"
#include "elm/layers/layer_y.h"
#include "elm/encoding/populationcode.h"
#include "elm/layers/saliencyitti.h"
#include "elm/layers/triangulation.h"
#include "elm/layers/weightedsum.h"

using boost::assign::map_list_of;

typedef Registor_<base_Layer> LayerRegistor;
typedef Registor_<base_Layer>::Registry LayerRegistry;

/** Macros for creating individual registry pair items
 *  credit: J. Turcot, T. Senechal, http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c
 */
#define REGISTRY_PAIR(Registor, NewInstance) (#NewInstance, &Registor::DerivedInstance<NewInstance>)
#define LAYER_REGISTRY_PAIR(NewInstance) REGISTRY_PAIR(LayerRegistor, NewInstance)

LayerRegistry g_layerRegistry = map_list_of
        LAYER_REGISTRY_PAIR( AttentionWindow )
        LAYER_REGISTRY_PAIR( ICP )
        LAYER_REGISTRY_PAIR( LayerY )
        LAYER_REGISTRY_PAIR( MutexPopulationCode )
        LAYER_REGISTRY_PAIR( SaliencyItti )
        LAYER_REGISTRY_PAIR( Triangulation )
        LAYER_REGISTRY_PAIR( WeightedSum )
        ; ///< <-- add new layer to registry here

LayerFactory::LayerFactory()
{
}

LayerRegistor::RegisteredTypeSharedPtr LayerFactory::CreateShared(const LayerType &type)
{
    return LayerRegistor::CreatePtrShared(g_layerRegistry, type);
}

LayerRegistor::RegisteredTypeSharedPtr LayerFactory::CreateShared(const LayerType &type,
                                                                          const LayerConfig &config,
                                                                          const LayerIONames &io)
{
    LayerRegistor::RegisteredTypeSharedPtr ptr = LayerFactory::CreateShared(type);
    ptr->Reset(config);
    ptr->IONames(io);
    return ptr;
}
<commit_msg>register grad assign. layer with main layer factory<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, Elm Library Project
// 3-clause BSD License
//
//M*/
#include "elm/layers/layerfactory.h"

#include <boost/assign/list_of.hpp>

#include "elm/core/registor.h"

/** Whenever a new layer is imeplemented:
 *  1. include its header below
 *  2. Add it to the initialization of g_layerRegistry map.
 */
#include "elm/layers/attentionwindow.h"
#include "elm/layers/gradassignment.h"
#include "elm/layers/icp.h"
#include "elm/layers/layer_y.h"
#include "elm/encoding/populationcode.h"
#include "elm/layers/saliencyitti.h"
#include "elm/layers/triangulation.h"
#include "elm/layers/weightedsum.h"

using boost::assign::map_list_of;
using namespace elm;

typedef Registor_<base_Layer> LayerRegistor;
typedef Registor_<base_Layer>::Registry LayerRegistry;

/** Macros for creating individual registry pair items
 *  credit: J. Turcot, T. Senechal, http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c
 */
#define REGISTRY_PAIR(Registor, NewInstance) (#NewInstance, &Registor::DerivedInstance<NewInstance>)
#define LAYER_REGISTRY_PAIR(NewInstance) REGISTRY_PAIR(LayerRegistor, NewInstance)

LayerRegistry g_layerRegistry = map_list_of
        LAYER_REGISTRY_PAIR( AttentionWindow )
        LAYER_REGISTRY_PAIR( GradAssignment )
        LAYER_REGISTRY_PAIR( ICP )
        LAYER_REGISTRY_PAIR( LayerY )
        LAYER_REGISTRY_PAIR( MutexPopulationCode )
        LAYER_REGISTRY_PAIR( SaliencyItti )
        LAYER_REGISTRY_PAIR( Triangulation )
        LAYER_REGISTRY_PAIR( WeightedSum )
        ; ///< <-- add new layer to registry here

LayerFactory::LayerFactory()
{
}

LayerRegistor::RegisteredTypeSharedPtr LayerFactory::CreateShared(const LayerType &type)
{
    return LayerRegistor::CreatePtrShared(g_layerRegistry, type);
}

LayerRegistor::RegisteredTypeSharedPtr LayerFactory::CreateShared(const LayerType &type,
                                                                          const LayerConfig &config,
                                                                          const LayerIONames &io)
{
    LayerRegistor::RegisteredTypeSharedPtr ptr = LayerFactory::CreateShared(type);
    ptr->Reset(config);
    ptr->IONames(io);
    return ptr;
}
<|endoftext|>


<commit_before>#include <cybozu/benchmark.hpp>
#include <cybozu/option.hpp>
#include <cybozu/xorshift.hpp>
#include <mcl/fp.hpp>
#include <mcl/conversion.hpp>
#include <mcl/ecparam.hpp>

typedef mcl::FpT<> Fp;
typedef mcl::FpT<mcl::ZnTag> Zn;
typedef mcl::EcT<Fp> Ec;

void benchFpSub(const char *pStr, const char *xStr, const char *yStr, mcl::fp::Mode mode)
{
	const char *s = mcl::fp::ModeToStr(mode);
	Fp::init(pStr, mode);
	Fp x(xStr);
	Fp y(yStr);

	double addT, subT, mulT, sqrT, invT;
	CYBOZU_BENCH_T(addT, Fp::add, x, x, x);
	CYBOZU_BENCH_T(subT, Fp::sub, x, x, y);
	CYBOZU_BENCH_T(mulT, Fp::mul, x, x, x);
	CYBOZU_BENCH_T(sqrT, Fp::sqr, x, x);
	CYBOZU_BENCH_T(invT, x += y;Fp::inv, x, x); // avoid same jmp
	printf("%10s bit % 3d add %8.2f sub %8.2f mul %8.2f sqr %8.2f inv %8.2f\n", s, (int)Fp::getBitSize(), addT, subT, mulT, sqrT, invT);
}

void benchFp(size_t bitSize, int mode)
{
	const struct {
		size_t bitSize;
		const char *p;
		const char *x;
		const char *y;
	} tbl[] = {
		{
			192,
			"0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d",
			"0x148094810948190412345678901234567900342423332197",
			"0x7fffffffffffffffffffffe26f2fc170f69466a74defd8d",
		},
		{
			256,
			"0x2523648240000001ba344d80000000086121000000000013a700000000000013",
			"0x1480948109481904123456789234234242423424201234567900342423332197",
			"0x151342342342341517fffffffffffffffffffffe26f2fc170f69466a74defd8d",
		},
		{
			384,
			"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
			"0x19481084109481094820948209482094820984290482212345678901234567900342308472047204720422423332197",
			"0x209348209481094820984209842094820948204204243123456789012345679003423084720472047204224233321972",

		},
		{
			521,
			"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
			"0x2908209582095820941098410948109482094820984209840294829049240294242498540975555312345678901234567900342308472047204720422423332197",
			"0x3948384209834029834092384204920349820948205872380573205782385729385729385723985837ffffffffffffffffffffffe26f2fc170f69466a74defd8d",

		},
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		if (bitSize != 0 && tbl[i].bitSize != bitSize) continue;
		if (mode & 1) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_GMP);
		if (mode & 2) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_GMP_MONT);
#ifdef MCL_USE_LLVM
		if (mode & 4) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_LLVM);
		if (mode & 8) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_LLVM_MONT);
#endif
#ifdef MCL_X64_ASM
		if (mode & 16) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_XBYAK);
#endif
	}
}

void benchEcSub(const mcl::EcParam& para, mcl::fp::Mode mode, mcl::ec::Mode ecMode)
{
	Ec P;
	mcl::initCurve<Ec, Zn>(para.curveType, &P, mode, ecMode);
	Ec P2; Ec::add(P2, P, P);
	Ec Q = P + P + P;
	double addT, add2T, subT, dblT, mulT, mulCTT, mulRandT, mulCTRandT, normT;
	CYBOZU_BENCH_T(addT, P = P2; Ec::add, Q, P, Q);
	P.normalize();
	CYBOZU_BENCH_T(add2T, Ec::add, Q, P, Q);
	CYBOZU_BENCH_T(subT, Ec::sub, Q, P, Q);
	CYBOZU_BENCH_T(dblT, Ec::dbl, P, P);
	Zn z("3");
	CYBOZU_BENCH_T(mulT, Ec::mul, Q, P, z);
	CYBOZU_BENCH_T(mulCTT, Ec::mulCT, Q, P, z);
	cybozu::XorShift rg;
	z.setRand(rg);
	CYBOZU_BENCH_T(mulRandT, Ec::mul, Q, P, z);
	CYBOZU_BENCH_T(mulCTRandT, Ec::mulCT, Q, P, z);
	CYBOZU_BENCH_T(normT, Q = P; Q.normalize);
	printf("%10s %10s add %8.2f add2 %8.2f sub %8.2f dbl %8.2f mul(3) %8.2f mulCT(3) %8.2f mul(rand) %8.2f mulCT(rand) %8.2f norm %8.2f\n", para.name, mcl::fp::ModeToStr(mode), addT, add2T, subT, dblT, mulT, mulCTT, mulRandT, mulCTRandT, normT);

}
void benchEc(size_t bitSize, int mode, mcl::ec::Mode ecMode)
{
	const struct mcl::EcParam tbl[] = {
		mcl::ecparam::p160_1,
		mcl::ecparam::secp160k1,
		mcl::ecparam::secp192k1,
		mcl::ecparam::NIST_P192,
		mcl::ecparam::secp224k1,
		mcl::ecparam::secp256k1,
		mcl::ecparam::NIST_P224,
		mcl::ecparam::NIST_P256,
//		mcl::ecparam::secp384r1,
		mcl::ecparam::NIST_P384,
//		mcl::ecparam::secp521r1,
		mcl::ecparam::NIST_P521,
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		if (bitSize != 0 && tbl[i].bitSize != bitSize) continue;
		benchEcSub(tbl[i], mcl::fp::FP_AUTO, ecMode);
		if (mode & 1) benchEcSub(tbl[i], mcl::fp::FP_GMP, ecMode);
		if (mode & 2) benchEcSub(tbl[i], mcl::fp::FP_GMP_MONT, ecMode);
#ifdef MCL_USE_LLVM
		if (mode & 4) benchEcSub(tbl[i], mcl::fp::FP_LLVM, ecMode);
		if (mode & 8) benchEcSub(tbl[i], mcl::fp::FP_LLVM_MONT, ecMode);
#endif
#ifdef MCL_X64_ASM
		if (mode & 16) benchEcSub(tbl[i], mcl::fp::FP_XBYAK, ecMode);
#endif
	}
}

void benchToStr16()
{
	puts("benchToStr16");
	const char *tbl[] = {
		"0x0",
		"0x5",
		"0x123",
		"0x123456789012345679adbc",
		"0xffffffff26f2fc170f69466a74defd8d",
		"0x100000000000000000000000000000033",
		"0x11ee12312312940000000000000000000000000002342343"
	};
	Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13");
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		char buf[128];
		std::string str;
		Fp x(tbl[i]);
		CYBOZU_BENCH("fp::arrayToHex", mcl::fp::arrayToHex, buf, sizeof(buf), x.getUnit(), x.getUnitSize(), true);
		mpz_class y(tbl[i]);
		CYBOZU_BENCH("gmp:getStr ", mcl::gmp::getStr, str, y, 16);
	}
}

void benchFromStr16()
{
	puts("benchFromStr16");
	const char *tbl[] = {
		"0",
		"5",
		"123",
		"123456789012345679adbc",
		"ffffffff26f2fc170f69466a74defd8d",
		"100000000000000000000000000000033",
		"11ee12312312940000000000000000000000000002342343"
	};
	Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13");
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		std::string str = tbl[i];
		Fp x;
		const size_t N = 64;
		mcl::fp::Unit buf[N];
		CYBOZU_BENCH("fp:hexToArray", mcl::fp::hexToArray, buf, N, str.c_str(), str.size());

		mpz_class y;
		CYBOZU_BENCH("gmp:setStr  ", mcl::gmp::setStr, y, str, 16);
	}
}

int main(int argc, char *argv[])
	try
{
	size_t bitSize;
	int mode;
	bool ecOnly;
	bool fpOnly;
	bool misc;
	mcl::ec::Mode ecMode;
	std::string ecModeStr;
	cybozu::Option opt;
	opt.appendOpt(&bitSize, 0, "s", ": bitSize");
	opt.appendOpt(&mode, 0, "m", ": mode(0:all, sum of 1:gmp, 2:gmp+mont, 4:llvm, 8:llvm+mont, 16:xbyak");
	opt.appendBoolOpt(&ecOnly, "ec", ": ec only");
	opt.appendBoolOpt(&fpOnly, "fp", ": fp only");
	opt.appendBoolOpt(&misc, "misc", ": other benchmark");
	opt.appendOpt(&ecModeStr, "jacobi", "ecmode", ": jacobi or proj");
	opt.appendHelp("h", ": show this message");
	if (!opt.parse(argc, argv)) {
		opt.usage();
		return 1;
	}
	if (ecModeStr == "jacobi") {
		ecMode = mcl::ec::Jacobi;
	} else if (ecModeStr == "proj") {
		ecMode = mcl::ec::Proj;
	} else {
		printf("bad ecstr %s\n", ecModeStr.c_str());
		opt.usage();
		return 1;
	}
	if (mode < 0 || mode > 31) {
		printf("bad mode %d\n", mode);
		opt.usage();
		return 1;
	}
	if (mode == 0) mode = 31;
	if (misc) {
		benchToStr16();
		benchFromStr16();
	} else {
		if (!ecOnly) benchFp(bitSize, mode);
		if (!fpOnly) {
			printf("ecMode=%s\n", ecModeStr.c_str());
			benchEc(bitSize, mode, ecMode);
		}
	}
} catch (std::exception& e) {
	printf("ERR %s\n", e.what());
}

<commit_msg>check MCL_MAX_BIT_SIZE in sample/bench.cpp<commit_after>#include <cybozu/benchmark.hpp>
#include <cybozu/option.hpp>
#include <cybozu/xorshift.hpp>
#include <mcl/fp.hpp>
#include <mcl/conversion.hpp>
#include <mcl/ecparam.hpp>

typedef mcl::FpT<> Fp;
typedef mcl::FpT<mcl::ZnTag> Zn;
typedef mcl::EcT<Fp> Ec;

void benchFpSub(const char *pStr, const char *xStr, const char *yStr, mcl::fp::Mode mode)
{
	const char *s = mcl::fp::ModeToStr(mode);
	Fp::init(pStr, mode);
	Fp x(xStr);
	Fp y(yStr);

	double addT, subT, mulT, sqrT, invT;
	CYBOZU_BENCH_T(addT, Fp::add, x, x, x);
	CYBOZU_BENCH_T(subT, Fp::sub, x, x, y);
	CYBOZU_BENCH_T(mulT, Fp::mul, x, x, x);
	CYBOZU_BENCH_T(sqrT, Fp::sqr, x, x);
	CYBOZU_BENCH_T(invT, x += y;Fp::inv, x, x); // avoid same jmp
	printf("%10s bit % 3d add %8.2f sub %8.2f mul %8.2f sqr %8.2f inv %8.2f\n", s, (int)Fp::getBitSize(), addT, subT, mulT, sqrT, invT);
}

void benchFp(size_t bitSize, int mode)
{
	const struct {
		size_t bitSize;
		const char *p;
		const char *x;
		const char *y;
	} tbl[] = {
		{
			192,
			"0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d",
			"0x148094810948190412345678901234567900342423332197",
			"0x7fffffffffffffffffffffe26f2fc170f69466a74defd8d",
		},
		{
			256,
			"0x2523648240000001ba344d80000000086121000000000013a700000000000013",
			"0x1480948109481904123456789234234242423424201234567900342423332197",
			"0x151342342342341517fffffffffffffffffffffe26f2fc170f69466a74defd8d",
		},
		{
			384,
			"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
			"0x19481084109481094820948209482094820984290482212345678901234567900342308472047204720422423332197",
			"0x209348209481094820984209842094820948204204243123456789012345679003423084720472047204224233321972",

		},
#if MCL_MAX_BIT_SIZE >= 521
		{
			521,
			"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
			"0x2908209582095820941098410948109482094820984209840294829049240294242498540975555312345678901234567900342308472047204720422423332197",
			"0x3948384209834029834092384204920349820948205872380573205782385729385729385723985837ffffffffffffffffffffffe26f2fc170f69466a74defd8d",

		},
#endif
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		if (bitSize != 0 && tbl[i].bitSize != bitSize) continue;
		if (mode & 1) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_GMP);
		if (mode & 2) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_GMP_MONT);
#ifdef MCL_USE_LLVM
		if (mode & 4) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_LLVM);
		if (mode & 8) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_LLVM_MONT);
#endif
#ifdef MCL_X64_ASM
		if (mode & 16) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_XBYAK);
#endif
	}
}

void benchEcSub(const mcl::EcParam& para, mcl::fp::Mode mode, mcl::ec::Mode ecMode)
{
	Ec P;
	mcl::initCurve<Ec, Zn>(para.curveType, &P, mode, ecMode);
	Ec P2; Ec::add(P2, P, P);
	Ec Q = P + P + P;
	double addT, add2T, subT, dblT, mulT, mulCTT, mulRandT, mulCTRandT, normT;
	CYBOZU_BENCH_T(addT, P = P2; Ec::add, Q, P, Q);
	P.normalize();
	CYBOZU_BENCH_T(add2T, Ec::add, Q, P, Q);
	CYBOZU_BENCH_T(subT, Ec::sub, Q, P, Q);
	CYBOZU_BENCH_T(dblT, Ec::dbl, P, P);
	Zn z("3");
	CYBOZU_BENCH_T(mulT, Ec::mul, Q, P, z);
	CYBOZU_BENCH_T(mulCTT, Ec::mulCT, Q, P, z);
	cybozu::XorShift rg;
	z.setRand(rg);
	CYBOZU_BENCH_T(mulRandT, Ec::mul, Q, P, z);
	CYBOZU_BENCH_T(mulCTRandT, Ec::mulCT, Q, P, z);
	CYBOZU_BENCH_T(normT, Q = P; Q.normalize);
	printf("%10s %10s add %8.2f add2 %8.2f sub %8.2f dbl %8.2f mul(3) %8.2f mulCT(3) %8.2f mul(rand) %8.2f mulCT(rand) %8.2f norm %8.2f\n", para.name, mcl::fp::ModeToStr(mode), addT, add2T, subT, dblT, mulT, mulCTT, mulRandT, mulCTRandT, normT);

}
void benchEc(size_t bitSize, int mode, mcl::ec::Mode ecMode)
{
	const struct mcl::EcParam tbl[] = {
		mcl::ecparam::p160_1,
		mcl::ecparam::secp160k1,
		mcl::ecparam::secp192k1,
		mcl::ecparam::NIST_P192,
		mcl::ecparam::secp224k1,
		mcl::ecparam::secp256k1,
		mcl::ecparam::NIST_P224,
		mcl::ecparam::NIST_P256,
//		mcl::ecparam::secp384r1,
		mcl::ecparam::NIST_P384,
#if MCL_MAX_BIT_SIZE >= 521
//		mcl::ecparam::secp521r1,
		mcl::ecparam::NIST_P521,
#endif
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		if (bitSize != 0 && tbl[i].bitSize != bitSize) continue;
		benchEcSub(tbl[i], mcl::fp::FP_AUTO, ecMode);
		if (mode & 1) benchEcSub(tbl[i], mcl::fp::FP_GMP, ecMode);
		if (mode & 2) benchEcSub(tbl[i], mcl::fp::FP_GMP_MONT, ecMode);
#ifdef MCL_USE_LLVM
		if (mode & 4) benchEcSub(tbl[i], mcl::fp::FP_LLVM, ecMode);
		if (mode & 8) benchEcSub(tbl[i], mcl::fp::FP_LLVM_MONT, ecMode);
#endif
#ifdef MCL_X64_ASM
		if (mode & 16) benchEcSub(tbl[i], mcl::fp::FP_XBYAK, ecMode);
#endif
	}
}

void benchToStr16()
{
	puts("benchToStr16");
	const char *tbl[] = {
		"0x0",
		"0x5",
		"0x123",
		"0x123456789012345679adbc",
		"0xffffffff26f2fc170f69466a74defd8d",
		"0x100000000000000000000000000000033",
		"0x11ee12312312940000000000000000000000000002342343"
	};
	Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13");
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		char buf[128];
		std::string str;
		Fp x(tbl[i]);
		CYBOZU_BENCH("fp::arrayToHex", mcl::fp::arrayToHex, buf, sizeof(buf), x.getUnit(), x.getUnitSize(), true);
		mpz_class y(tbl[i]);
		CYBOZU_BENCH("gmp:getStr ", mcl::gmp::getStr, str, y, 16);
	}
}

void benchFromStr16()
{
	puts("benchFromStr16");
	const char *tbl[] = {
		"0",
		"5",
		"123",
		"123456789012345679adbc",
		"ffffffff26f2fc170f69466a74defd8d",
		"100000000000000000000000000000033",
		"11ee12312312940000000000000000000000000002342343"
	};
	Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13");
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		std::string str = tbl[i];
		Fp x;
		const size_t N = 64;
		mcl::fp::Unit buf[N];
		CYBOZU_BENCH("fp:hexToArray", mcl::fp::hexToArray, buf, N, str.c_str(), str.size());

		mpz_class y;
		CYBOZU_BENCH("gmp:setStr  ", mcl::gmp::setStr, y, str, 16);
	}
}

int main(int argc, char *argv[])
	try
{
	size_t bitSize;
	int mode;
	bool ecOnly;
	bool fpOnly;
	bool misc;
	mcl::ec::Mode ecMode;
	std::string ecModeStr;
	cybozu::Option opt;
	opt.appendOpt(&bitSize, 0, "s", ": bitSize");
	opt.appendOpt(&mode, 0, "m", ": mode(0:all, sum of 1:gmp, 2:gmp+mont, 4:llvm, 8:llvm+mont, 16:xbyak");
	opt.appendBoolOpt(&ecOnly, "ec", ": ec only");
	opt.appendBoolOpt(&fpOnly, "fp", ": fp only");
	opt.appendBoolOpt(&misc, "misc", ": other benchmark");
	opt.appendOpt(&ecModeStr, "jacobi", "ecmode", ": jacobi or proj");
	opt.appendHelp("h", ": show this message");
	if (!opt.parse(argc, argv)) {
		opt.usage();
		return 1;
	}
	if (ecModeStr == "jacobi") {
		ecMode = mcl::ec::Jacobi;
	} else if (ecModeStr == "proj") {
		ecMode = mcl::ec::Proj;
	} else {
		printf("bad ecstr %s\n", ecModeStr.c_str());
		opt.usage();
		return 1;
	}
	if (mode < 0 || mode > 31) {
		printf("bad mode %d\n", mode);
		opt.usage();
		return 1;
	}
	if (mode == 0) mode = 31;
	if (misc) {
		benchToStr16();
		benchFromStr16();
	} else {
		if (!ecOnly) benchFp(bitSize, mode);
		if (!fpOnly) {
			printf("ecMode=%s\n", ecModeStr.c_str());
			benchEc(bitSize, mode, ecMode);
		}
	}
} catch (std::exception& e) {
	printf("ERR %s\n", e.what());
}

<|endoftext|>


<commit_before>#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

void init() __attribute__((constructor));
void fini() __attribute__((destructor));

static void panic(...) __attribute__((noreturn));

#define assert xassert
#define xassert(e) if (e); else panic(#e)

/**
 * These are adapted to be stored internally in whatever data we have.
 */
struct pairing_ptr_heap
{
	typedef pairing_ptr_heap T;
	typedef pairing_ptr_heap* Tp;

	/**
	 * down,right: first child and right sibling of this page in pairing heap
	 * of pages with free space.
	 */
	pairing_ptr_heap* down;
	pairing_ptr_heap* right;

	Tp delete_min()
	{
		assert(!right);
		Tp l = down;
		down = NULL;
		return mergePairs(l);
	}

	static Tp mergePairs(Tp l)
	{
		if (!l || !l->right) return l;

		Tp r = l->right;
		Tp hs = r->right;
		l->right = r->right = NULL;
		assert(hs != l && hs != r && r != l);
		// FIXME recursion...
		// We can use l->right after merge returns, since merge() always
		// returns something with a right-value of NULL. l will never be
		// touched until we're about to merge it with the result of mergePairs
		l = merge(l,r);
		hs = mergePairs(hs);
		return merge(l,hs);
	}

	static Tp merge(Tp l, Tp r)
	{
		if (!l)
		{
			assert(!r->right);
			return r;
		}
		if (!r)
		{
			assert(!l->right);
			return l;
		}

		assert(!l->right && !r->right);

		if (r < l)
		{
			Tp tmp = r;
			r = l;
			l = tmp;
		}
		// l <= r!

		r->right = l->down;
		l->down = r;
		//l->right = NULL; // we know it's already null
		return l;
	}
};
pairing_ptr_heap* delete_min(pairing_ptr_heap* p)
{
	assert(p);
	return p->delete_min();
}
pairing_ptr_heap* insert(pairing_ptr_heap* l, pairing_ptr_heap* r)
{
	return pairing_ptr_heap::merge(l, r);
}

struct pageinfo
{
	/**
	 * Pointer to where the page starts.
	 * TODO: Pack some stuff in here. *Twelve* vacant bits!
	 */
	void* page;

	uint16_t size;
	//uint16_t isize;
	uint16_t chunks;
	uint16_t chunks_free;
	uint8_t index; // index into array of pages

	/**
	 * The heap of address-sorted pages in this category that have free pages
	 */
	pairing_ptr_heap heap;
	/**
	 * 1-32 bytes of bitmap data. A set bit means *free* chunk.
	 */
	uint8_t bitmap[];

	// TODO merge bitmap into page?
};
#define pageinfo_from_heap(heap_) \
	((pageinfo*)((char*)(heap_) - offsetof(pageinfo, heap)))

bool page_filled(pageinfo* page)
{
	return !page->chunks_free;
}
void* page_get_chunk(pageinfo* page)
{
	page->chunks_free--;
	uint8_t* bitmap = page->bitmap;
	for (size_t i = 0; i < page->chunks / 8; i++)
	{
		const uint8_t found = bitmap[i];
		if (found)
		{
			uint8_t mask = 0x80;
			size_t n = i << 3;
			while (mask)
			{
				if (mask & found)
				{
					bitmap[i] = found & ~mask;
					return (uint8_t*)page->page + (n * page->size);
				}
				mask >>= 1;
				n++;
			}
		}
	}
	panic("No free chunks found?");
}
void page_free_chunk(pageinfo* page, void* ptr)
{
	size_t ix = (uint8_t*)ptr - (uint8_t*)page->page;
	ix /= page->size; // FIXME store inverse or something instead
	page->bitmap[ix >> 3] |= 1 << (7 - (ix & 7));
	page->chunks_free++;
}

#define N_SIZES (128/16+5)
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)

static pairing_ptr_heap* g_free_pages;
static pageinfo* g_chunk_pages[N_SIZES];
static uintptr_t g_first_page;
static uintptr_t g_n_pages;
// Assumes mostly contiguous pages...
static pageinfo** g_pages;

void init()
{
	g_first_page = (uintptr_t)sbrk(0);
}

void fini()
{
	// TODO Unmap everything?
}

void panic(...)
{
	abort();
}

size_t size_ix(size_t size)
{
	if (size <= 128)
		return (size + 15) / 16 - 1;

	size_t ix = 8; // 256 bytes
	size >>= 8;
	while (size) { size >>= 1; ix++; }
	return ix;
}

size_t ix_size(size_t ix)
{
	return ix < 8 ? 16 * (ix + 1) : (1 << ix);
}

void* get_page()
{
	if (void* ret = g_free_pages)
	{
		g_free_pages = delete_min(g_free_pages);
		return ret;
	}
	else
	{
		uintptr_t cur = (uintptr_t)sbrk(0);
		sbrk((PAGE_SIZE - cur) & (PAGE_SIZE - 1));
		return sbrk(PAGE_SIZE);
	}
}

void set_pageinfo(void* page, pageinfo* info)
{
	uintptr_t offset;
	if (g_pages)
	{
		offset = ((uintptr_t)page - g_first_page) >> PAGE_SHIFT;
	}
	else
	{
		g_first_page = (uintptr_t)page;
		offset = 0;
	}

	if (offset >= g_n_pages)
	{
		size_t required = (offset + PAGE_SIZE) & ~(PAGE_SIZE-1);
		pageinfo** new_pages = (pageinfo**)mmap(NULL, required, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
		assert(new_pages != MAP_FAILED);

		memcpy(new_pages, g_pages, g_n_pages * sizeof(pageinfo*));
		munmap(g_pages, g_n_pages * sizeof(pageinfo*));

		g_pages = new_pages;
		g_n_pages = required / sizeof(pageinfo*);
	}

	g_pages[offset] = info;
}

pageinfo* new_chunkpage(size_t size)
{
	size_t ix = size_ix(size);
	size = ix_size(ix);

	size_t nchunks = 4096/size;
	pageinfo* ret = NULL;
	size_t pisize = sizeof(pageinfo) + nchunks/8;
	if (!g_chunk_pages[size_ix(pisize)])
	{
		ret = (pageinfo*)get_page();
		set_pageinfo(ret, NULL);
	}
	else
	{
		ret = (pageinfo*)malloc(pisize);
	}

	memset(&ret->heap, 0, sizeof(ret->heap));
	ret->page = get_page();
	ret->size = size;
//	ret->shift = ix_shift(ix);
	ret->chunks = nchunks;
	ret->chunks_free = nchunks;
	ret->index = ix;

	memset(ret->bitmap, 0xff, nchunks/8);

	set_pageinfo(ret->page, ret);

	return ret;
}

pageinfo* ptr_pageinfo(void* ptr)
{
	uintptr_t offset = ((uintptr_t)ptr - g_first_page) >> PAGE_SHIFT;
	if (offset > g_n_pages) return NULL;
	pageinfo* ret = g_pages[offset];
	assert(!ret || !(((uintptr_t)ret->page ^ (uintptr_t)ptr) >> PAGE_SHIFT));
	return ret;
}

size_t get_alloc_size(void* ptr)
{
	pageinfo* info = ptr_pageinfo(ptr);
	if (!info) panic("get_alloc_size for unknown pointer %p", ptr);
	return info->size;
}

void *malloc(size_t size)
{
	if (!size) return NULL;

	pageinfo** pagep = g_chunk_pages + size_ix(size);
	pageinfo* page = *pagep;
	if (!page)
	{
		printf("Adding new chunk page for size %u (cat %d)\n", size, size_ix(size));
		page = new_chunkpage(size);
		*pagep = page;
	}
	printf("Allocating chunk from %p (info %p, %d left)\n", page->page, page, page->chunks_free);
	void* ret = page_get_chunk(page);
	if (page_filled(page))
	{
		printf("Page %p (info %p) filled\n", page->page, page);
		pairing_ptr_heap* newpage = delete_min(&page->heap);
		*pagep = newpage ? pageinfo_from_heap(newpage) : NULL;
	}
	return ret;
}

void* calloc(size_t n, size_t sz)
{
	size_t size = n * sz;
	void* ptr = malloc(size);
	if (ptr) memset(ptr, 0, size);
	return ptr;
}

void* realloc(void* ptr, size_t new_size)
{
	size_t old_size = get_alloc_size(ptr);
	void* ret = malloc(new_size);
	if (ret)
	{
		memcpy(ret, ptr, new_size < old_size ? new_size : old_size);
	}
	return ret;
}

void free(void *ptr)
{
	if (!ptr) return;

	pageinfo* page = ptr_pageinfo(ptr);
	if (!page) panic("free on unknown pointer %p", ptr);

	bool was_filled = page_filled(page);
	page_free_chunk(page, ptr);
	if (was_filled)
	{
		pageinfo** pagep = g_chunk_pages + page->index;
		pageinfo* free_page = *pagep;
		if (!free_page)
			*pagep = page;
		else
			*pagep = pageinfo_from_heap(insert(&free_page->heap, &page->heap));
	}
	else if (page->chunks_free == page->chunks)
	{
		printf("Free: page %p (info %p) is now free\n", page->page, page);
	}
}

#ifdef TEST

int32_t xrand()
{
	static int32_t m_w = 1246987127, m_z = 789456123;
	m_z = 36969 * (m_z & 65535) + (m_z >> 16);
	m_w = 18000 * (m_w & 65535) + (m_w >> 16);
	return (m_z << 16) + m_w;  /* 32-bit result */
}

const size_t DELAY = 10;
const size_t NTESTS = 100000;
const size_t MAXALLOC = 512;

int main()
{
	void* ptrs[DELAY] = {0};
	for (size_t i = 0; i < NTESTS; i++)
	{
		size_t size = i % MAXALLOC;
		void** p = ptrs + (i % DELAY);
		printf("free(%p)\n", *p);
		free(*p);
		printf("malloc(%lu)\n", (unsigned long)size);
		*p = malloc(size);
		printf("malloc(%lu): %p\n", (unsigned long)size, *p);
		for (size_t j = 0; j < DELAY; j++)
		{
			assert(ptrs + j == p || !p[0] || ptrs[j] != p[0]);
		}
	}
}
#endif
<commit_msg>Add macros for debug mode and likely/unlikely annotations<commit_after>#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

void init() __attribute__((constructor));
void fini() __attribute__((destructor));

static void panic(...) __attribute__((noreturn));

#ifdef DEBUG
#define debug printf
#define assert xassert
#define xassert(e) if (e); else panic(#e)
#define IFDEBUG(X) X
#else
#define debug(...) (void)0
#define assert(...) (void)0
#define IFDEBUG(X) /* nothing */
#endif

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

/**
 * These are adapted to be stored internally in whatever data we have.
 */
struct pairing_ptr_heap
{
	typedef pairing_ptr_heap T;
	typedef pairing_ptr_heap* Tp;

	/**
	 * down,right: first child and right sibling of this page in pairing heap
	 * of pages with free space.
	 */
	pairing_ptr_heap* down;
	pairing_ptr_heap* right;

	Tp delete_min()
	{
		assert(!right);
		Tp l = down;
		down = NULL;
		return mergePairs(l);
	}

	static Tp mergePairs(Tp l)
	{
		if (!l || !l->right) return l;

		Tp r = l->right;
		Tp hs = r->right;
		l->right = r->right = NULL;
		assert(hs != l && hs != r && r != l);
		// FIXME recursion...
		// We can use l->right after merge returns, since merge() always
		// returns something with a right-value of NULL. l will never be
		// touched until we're about to merge it with the result of mergePairs
		l = merge(l,r);
		hs = mergePairs(hs);
		return merge(l,hs);
	}

	static Tp merge(Tp l, Tp r)
	{
		if (!l)
		{
			assert(!r->right);
			return r;
		}
		if (!r)
		{
			assert(!l->right);
			return l;
		}

		assert(!l->right && !r->right);

		if (r < l)
		{
			Tp tmp = r;
			r = l;
			l = tmp;
		}
		// l <= r!

		r->right = l->down;
		l->down = r;
		//l->right = NULL; // we know it's already null
		return l;
	}
};
pairing_ptr_heap* delete_min(pairing_ptr_heap* p)
{
	assert(p);
	return p->delete_min();
}
pairing_ptr_heap* insert(pairing_ptr_heap* l, pairing_ptr_heap* r)
{
	return pairing_ptr_heap::merge(l, r);
}

struct pageinfo
{
	/**
	 * Pointer to where the page starts.
	 * TODO: Pack some stuff in here. *Twelve* vacant bits!
	 */
	void* page;

	uint16_t size;
	//uint16_t isize;
	uint16_t chunks;
	uint16_t chunks_free;
	uint8_t index; // index into array of pages

	/**
	 * The heap of address-sorted pages in this category that have free pages
	 */
	pairing_ptr_heap heap;
	/**
	 * 1-32 bytes of bitmap data. A set bit means *free* chunk.
	 */
	uint8_t bitmap[];

	// TODO merge bitmap into page?
};
#define pageinfo_from_heap(heap_) \
	((pageinfo*)((char*)(heap_) - offsetof(pageinfo, heap)))

bool page_filled(pageinfo* page)
{
	return !page->chunks_free;
}
void* page_get_chunk(pageinfo* page)
{
	page->chunks_free--;
	uint8_t* bitmap = page->bitmap;
	for (size_t i = 0; i < page->chunks / 8; i++)
	{
		const uint8_t found = bitmap[i];
		if (found)
		{
			uint8_t mask = 0x80;
			size_t n = i << 3;
			while (mask)
			{
				if (mask & found)
				{
					bitmap[i] = found & ~mask;
					return (uint8_t*)page->page + (n * page->size);
				}
				mask >>= 1;
				n++;
			}
		}
	}
	panic("No free chunks found?");
}
void page_free_chunk(pageinfo* page, void* ptr)
{
	size_t ix = (uint8_t*)ptr - (uint8_t*)page->page;
	ix /= page->size; // FIXME store inverse or something instead
	page->bitmap[ix >> 3] |= 1 << (7 - (ix & 7));
	page->chunks_free++;
}

#define N_SIZES (128/16+5)
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)

static pairing_ptr_heap* g_free_pages;
static pageinfo* g_chunk_pages[N_SIZES];
static uintptr_t g_first_page;
static uintptr_t g_n_pages;
// Assumes mostly contiguous pages...
static pageinfo** g_pages;

void init()
{
	g_first_page = (uintptr_t)sbrk(0);
}

void fini()
{
	// TODO Unmap everything?
}

void panic(...)
{
	abort();
}

size_t size_ix(size_t size)
{
	if (size <= 128)
		return (size + 15) / 16 - 1;

	size_t ix = 8; // 256 bytes
	size >>= 8;
	while (size) { size >>= 1; ix++; }
	return ix;
}

size_t ix_size(size_t ix)
{
	return ix < 8 ? 16 * (ix + 1) : (1 << ix);
}

void* get_page()
{
	if (void* ret = g_free_pages)
	{
		g_free_pages = delete_min(g_free_pages);
		return ret;
	}
	else
	{
		uintptr_t cur = (uintptr_t)sbrk(0);
		sbrk((PAGE_SIZE - cur) & (PAGE_SIZE - 1));
		return sbrk(PAGE_SIZE);
	}
}

void set_pageinfo(void* page, pageinfo* info)
{
	uintptr_t offset;
	if (g_pages)
	{
		offset = ((uintptr_t)page - g_first_page) >> PAGE_SHIFT;
	}
	else
	{
		g_first_page = (uintptr_t)page;
		offset = 0;
	}

	if (offset >= g_n_pages)
	{
		size_t required = (offset + PAGE_SIZE) & ~(PAGE_SIZE-1);
		pageinfo** new_pages = (pageinfo**)mmap(NULL, required, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
		assert(new_pages != MAP_FAILED);

		memcpy(new_pages, g_pages, g_n_pages * sizeof(pageinfo*));
		munmap(g_pages, g_n_pages * sizeof(pageinfo*));

		g_pages = new_pages;
		g_n_pages = required / sizeof(pageinfo*);
	}

	g_pages[offset] = info;
}

pageinfo* new_chunkpage(size_t size)
{
	size_t ix = size_ix(size);
	size = ix_size(ix);

	size_t nchunks = 4096/size;
	pageinfo* ret = NULL;
	size_t pisize = sizeof(pageinfo) + nchunks/8;
	if (!g_chunk_pages[size_ix(pisize)])
	{
		ret = (pageinfo*)get_page();
		set_pageinfo(ret, NULL);
	}
	else
	{
		ret = (pageinfo*)malloc(pisize);
	}

	memset(&ret->heap, 0, sizeof(ret->heap));
	ret->page = get_page();
	ret->size = size;
//	ret->shift = ix_shift(ix);
	ret->chunks = nchunks;
	ret->chunks_free = nchunks;
	ret->index = ix;

	memset(ret->bitmap, 0xff, nchunks/8);

	set_pageinfo(ret->page, ret);

	return ret;
}

pageinfo* ptr_pageinfo(void* ptr)
{
	uintptr_t offset = ((uintptr_t)ptr - g_first_page) >> PAGE_SHIFT;
	if (offset > g_n_pages) return NULL;
	pageinfo* ret = g_pages[offset];
	assert(!ret || !(((uintptr_t)ret->page ^ (uintptr_t)ptr) >> PAGE_SHIFT));
	return ret;
}

size_t get_alloc_size(void* ptr)
{
	pageinfo* info = ptr_pageinfo(ptr);
	if (!info) panic("get_alloc_size for unknown pointer %p", ptr);
	return info->size;
}

void *malloc(size_t size)
{
	if (!size) return NULL;

	pageinfo** pagep = g_chunk_pages + size_ix(size);
	pageinfo* page = *pagep;
	if (unlikely(!page))
	{
		debug("Adding new chunk page for size %lu (cat %ld)\n", size, size_ix(size));
		page = new_chunkpage(size);
		*pagep = page;
	}
	debug("Allocating chunk from %p (info %p, %d left)\n", page->page, page, page->chunks_free);
	void* ret = page_get_chunk(page);
	if (unlikely(page_filled(page)))
	{
		debug("Page %p (info %p) filled\n", page->page, page);
		pairing_ptr_heap* newpage = delete_min(&page->heap);
		*pagep = newpage ? pageinfo_from_heap(newpage) : NULL;
	}
	return ret;
}

void* calloc(size_t n, size_t sz)
{
	size_t size = n * sz;
	void* ptr = malloc(size);
	if (likely(ptr)) memset(ptr, 0, size);
	return ptr;
}

void* realloc(void* ptr, size_t new_size)
{
	size_t old_size = get_alloc_size(ptr);
	void* ret = malloc(new_size);
	if (likely(ret))
	{
		memcpy(ret, ptr, unlikely(new_size < old_size) ? new_size : old_size);
	}
	return ret;
}

void free(void *ptr)
{
	if (unlikely(!ptr)) return;

	pageinfo* page = ptr_pageinfo(ptr);
	if (unlikely(!page)) panic("free on unknown pointer %p", ptr);

	bool was_filled = page_filled(page);
	page_free_chunk(page, ptr);
	if (was_filled)
	{
		pageinfo** pagep = g_chunk_pages + page->index;
		pageinfo* free_page = *pagep;
		if (!free_page)
			*pagep = page;
		else
			*pagep = pageinfo_from_heap(insert(&free_page->heap, &page->heap));
	}
	else if (unlikely(page->chunks_free == page->chunks))
	{
		debug("Free: page %p (info %p) is now free\n", page->page, page);
	}
}

#ifdef TEST

int32_t xrand()
{
	static int32_t m_w = 1246987127, m_z = 789456123;
	m_z = 36969 * (m_z & 65535) + (m_z >> 16);
	m_w = 18000 * (m_w & 65535) + (m_w >> 16);
	return (m_z << 16) + m_w;  /* 32-bit result */
}

const size_t DELAY = 10;
const size_t NTESTS = 100000;
const size_t MAXALLOC = 512;

int main()
{
	void* ptrs[DELAY] = {0};
	for (size_t i = 0; i < NTESTS; i++)
	{
		size_t size = i % MAXALLOC;
		void** p = ptrs + (i % DELAY);
		debug("free(%p)\n", *p);
		free(*p);
		debug("malloc(%lu)\n", (unsigned long)size);
		*p = malloc(size);
		debug("malloc(%lu): %p\n", (unsigned long)size, *p);
		for (size_t j = 0; j < DELAY; j++)
		{
			assert(ptrs + j == p || !p[0] || ptrs[j] != p[0]);
		}
	}
}
#endif
<|endoftext|>


<commit_before>#include "dialogs/helpdialog.h"

#include <QApplication>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QSettings>
#include <QDir>

HelpDialog::HelpDialog(const QString& path, const QString& page, QWidget* parent)
    : QDialog(parent)
{
    setWindowFlags(Qt::Tool);
    setWindowTitle(tr("HOW TO USE REVERSCREEN"));

    QTextBrowser* textBrowser = new QTextBrowser;
    textBrowser->setSource(QUrl(path + page));
    textBrowser->setContextMenuPolicy(Qt::NoContextMenu);
    textBrowser->setTextInteractionFlags(Qt::NoTextInteraction);

    QCheckBox* checkBox = new QCheckBox(tr("Don't show this dialog again"));
    checkBox->setCheckState(Qt::Checked);
    connect(checkBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxToggled(bool)));

    QPushButton* closeButton = new QPushButton(tr("Close"));

    QHBoxLayout *buttonLayout = new QHBoxLayout;
    buttonLayout->addWidget(checkBox);
    buttonLayout->addStretch();
    buttonLayout->addWidget(closeButton);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(textBrowser);
    mainLayout->addLayout(buttonLayout);
    setLayout(mainLayout);

    connect(closeButton, SIGNAL(clicked()), this, SLOT(reject()));

    QSettings settings;
    bool checked = settings.value("hideHelpDialog", true).toBool();
    checkBox->setCheckState(checked ? Qt::Checked : Qt::Unchecked);

    setFixedSize(450, 300);
    move(parent->geometry().center() - geometry().center());
}

void HelpDialog::showPage(const QString& path, const QString& page, QWidget* parent)
{
  HelpDialog *helpDialog = new HelpDialog(path, page, parent);
  helpDialog->exec();

}
void HelpDialog::checkBoxToggled(bool checked)
{
    QSettings settings;
    settings.setValue("showHelpDialog", checked);
}
<commit_msg>bug fixing (remarks)<commit_after>#include "dialogs/helpdialog.h"

#include <QApplication>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QSettings>
#include <QDir>

HelpDialog::HelpDialog(const QString& path, const QString& page, QWidget* parent)
    : QDialog(parent)
{
    setWindowFlags(Qt::Tool);
    setWindowTitle(tr("HOW TO USE REVERSCREEN"));

    QTextBrowser* textBrowser = new QTextBrowser;
    textBrowser->setSource(QUrl(path + page));
    textBrowser->setContextMenuPolicy(Qt::NoContextMenu);
    textBrowser->setTextInteractionFlags(Qt::NoTextInteraction);

    QCheckBox* checkBox = new QCheckBox(tr("Don't show this dialog again"));
    checkBox->setCheckState(Qt::Checked);
    connect(checkBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxToggled(bool)));

    QPushButton* closeButton = new QPushButton(tr("Close"));

    QHBoxLayout *buttonLayout = new QHBoxLayout;
    buttonLayout->addWidget(checkBox);
    buttonLayout->addStretch();
    buttonLayout->addWidget(closeButton);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(textBrowser);
    mainLayout->addLayout(buttonLayout);
    setLayout(mainLayout);

    connect(closeButton, SIGNAL(clicked()), this, SLOT(reject()));

    QSettings settings;
    bool checked = settings.value("hideHelpDialog", true).toBool();
    checkBox->setCheckState(checked ? Qt::Checked : Qt::Unchecked);

    setFixedSize(450, 300);
    move(parent->geometry().center() - geometry().center());
}

void HelpDialog::showPage(const QString& path, const QString& page, QWidget* parent)
{
  HelpDialog *helpDialog = new HelpDialog(path, page, parent);
  helpDialog->exec();

}
void HelpDialog::checkBoxToggled(bool checked)
{
    QSettings settings;
    settings.setValue("hideHelpDialog", checked);
}
<|endoftext|>


<commit_before>// IFC SDK : IFC2X3 C++ Early Classes
// Copyright (C) 2009 CSTB
//
// 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.
// The full license is in Licence.txt file included with this
// distribution or is available at :
//     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
//
// 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.

#include <ifc2x3/IfcLayeredItem.h>

#include <ifc2x3/CopyOp.h>
#include <ifc2x3/IfcRepresentation.h>
#include <ifc2x3/IfcRepresentationItem.h>
#include <ifc2x3/Visitor.h>
#include <Step/BaseObject.h>

#include "precompiled.h"

using namespace ifc2x3;

IfcLayeredItem::IfcLayeredItem() : Step::BaseObject(0) {
    m_type = UNSET;
}

IfcLayeredItem::IfcLayeredItem(Step::SPFData *args) : Step::BaseObject(args) {
    m_type = UNSET;
}

IfcLayeredItem::~IfcLayeredItem() {
    deleteUnion();
}

bool IfcLayeredItem::acceptVisitor(Step::BaseVisitor *visitor) {
    return static_cast< Visitor * > (visitor)->visitIfcLayeredItem(this);
}

bool IfcLayeredItem::init() {
    return false;
}

const std::string &IfcLayeredItem::type() const {
    return IfcLayeredItem::s_type.getName();
}

const Step::ClassType &IfcLayeredItem::getClassType() {
    return IfcLayeredItem::s_type;
}

const Step::ClassType &IfcLayeredItem::getType() const {
    return IfcLayeredItem::s_type;
}

bool IfcLayeredItem::isOfType(const Step::ClassType &t) const {
    return IfcLayeredItem::s_type == t ? true : Step::BaseObject::isOfType(t);
}

void IfcLayeredItem::copy(const IfcLayeredItem &obj, const CopyOp &copyop) {
    switch(obj.m_type) {
    case IFCREPRESENTATIONITEM:
        setIfcRepresentationItem((IfcRepresentationItem *) (copyop(obj.m_IfcLayeredItem_union.m_IfcRepresentationItem)));
        break;
    case IFCREPRESENTATION:
        setIfcRepresentation((IfcRepresentation *) (copyop(obj.m_IfcLayeredItem_union.m_IfcRepresentation)));
        break;
    default:
        break;
    }
}

std::string IfcLayeredItem::currentTypeName() const {
    switch(m_type) {
    case IFCREPRESENTATIONITEM:
        return "IfcRepresentationItem";
        break;
    case IFCREPRESENTATION:
        return "IfcRepresentation";
        break;
    default:
        return "UNSET";
    }
}

IfcLayeredItem::IfcLayeredItem_select IfcLayeredItem::currentType() const {
    return m_type;
}

void IfcLayeredItem::deleteUnion() {
    switch(m_type) {
    case IFCREPRESENTATIONITEM:
        m_IfcLayeredItem_union.m_IfcRepresentationItem->unref();
        break;
    case IFCREPRESENTATION:
        m_IfcLayeredItem_union.m_IfcRepresentation->unref();
        break;
    default:
        break;
    }
    m_type = UNSET;
}

IfcRepresentationItem *IfcLayeredItem::getIfcRepresentationItem() const {
    if (m_type == IFCREPRESENTATIONITEM) {
        return m_IfcLayeredItem_union.m_IfcRepresentationItem;
    }
    else {
        return NULL;
    }
}

void IfcLayeredItem::setIfcRepresentationItem(IfcRepresentationItem *value) {
    if (m_type != UNSET) {
        deleteUnion();
    }
    m_IfcLayeredItem_union.m_IfcRepresentationItem = value;
    if (value) {
        value->ref();
        m_type = IFCREPRESENTATIONITEM;
    }
    else {
        m_type = UNSET;
    }
    m_type = IFCREPRESENTATIONITEM;
}

IfcRepresentation *IfcLayeredItem::getIfcRepresentation() const {
    if (m_type == IFCREPRESENTATION) {
        return m_IfcLayeredItem_union.m_IfcRepresentation;
    }
    else {
        return NULL;
    }
}

void IfcLayeredItem::setIfcRepresentation(IfcRepresentation *value) {
    if (m_type != UNSET) {
        deleteUnion();
    }
    m_IfcLayeredItem_union.m_IfcRepresentation = value;
    if (value) {
        value->ref();
        m_type = IFCREPRESENTATION;
    }
    else {
        m_type = UNSET;
    }
    m_type = IFCREPRESENTATION;
}

void IfcLayeredItem::set(Step::BaseObject *v)
{
    if (v != nullptr)
    {
        if (v->isOfType(IfcRepresentationItem::getClassType())) {
            setIfcRepresentationItem(static_cast< IfcRepresentationItem* > (v));
        }
        else if (v->isOfType(IfcRepresentation::getClassType())) {
            setIfcRepresentation(static_cast< IfcRepresentation* > (v));
        }
    }
}

IFC2X3_EXPORT Step::ClassType IfcLayeredItem::s_type("IfcLayeredItem");
<commit_msg>not C++11 ready yet :-)<commit_after>// IFC SDK : IFC2X3 C++ Early Classes
// Copyright (C) 2009 CSTB
//
// 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.
// The full license is in Licence.txt file included with this
// distribution or is available at :
//     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
//
// 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.

#include <ifc2x3/IfcLayeredItem.h>

#include <ifc2x3/CopyOp.h>
#include <ifc2x3/IfcRepresentation.h>
#include <ifc2x3/IfcRepresentationItem.h>
#include <ifc2x3/Visitor.h>
#include <Step/BaseObject.h>

#include "precompiled.h"

using namespace ifc2x3;

IfcLayeredItem::IfcLayeredItem() : Step::BaseObject(0) {
    m_type = UNSET;
}

IfcLayeredItem::IfcLayeredItem(Step::SPFData *args) : Step::BaseObject(args) {
    m_type = UNSET;
}

IfcLayeredItem::~IfcLayeredItem() {
    deleteUnion();
}

bool IfcLayeredItem::acceptVisitor(Step::BaseVisitor *visitor) {
    return static_cast< Visitor * > (visitor)->visitIfcLayeredItem(this);
}

bool IfcLayeredItem::init() {
    return false;
}

const std::string &IfcLayeredItem::type() const {
    return IfcLayeredItem::s_type.getName();
}

const Step::ClassType &IfcLayeredItem::getClassType() {
    return IfcLayeredItem::s_type;
}

const Step::ClassType &IfcLayeredItem::getType() const {
    return IfcLayeredItem::s_type;
}

bool IfcLayeredItem::isOfType(const Step::ClassType &t) const {
    return IfcLayeredItem::s_type == t ? true : Step::BaseObject::isOfType(t);
}

void IfcLayeredItem::copy(const IfcLayeredItem &obj, const CopyOp &copyop) {
    switch(obj.m_type) {
    case IFCREPRESENTATIONITEM:
        setIfcRepresentationItem((IfcRepresentationItem *) (copyop(obj.m_IfcLayeredItem_union.m_IfcRepresentationItem)));
        break;
    case IFCREPRESENTATION:
        setIfcRepresentation((IfcRepresentation *) (copyop(obj.m_IfcLayeredItem_union.m_IfcRepresentation)));
        break;
    default:
        break;
    }
}

std::string IfcLayeredItem::currentTypeName() const {
    switch(m_type) {
    case IFCREPRESENTATIONITEM:
        return "IfcRepresentationItem";
        break;
    case IFCREPRESENTATION:
        return "IfcRepresentation";
        break;
    default:
        return "UNSET";
    }
}

IfcLayeredItem::IfcLayeredItem_select IfcLayeredItem::currentType() const {
    return m_type;
}

void IfcLayeredItem::deleteUnion() {
    switch(m_type) {
    case IFCREPRESENTATIONITEM:
        m_IfcLayeredItem_union.m_IfcRepresentationItem->unref();
        break;
    case IFCREPRESENTATION:
        m_IfcLayeredItem_union.m_IfcRepresentation->unref();
        break;
    default:
        break;
    }
    m_type = UNSET;
}

IfcRepresentationItem *IfcLayeredItem::getIfcRepresentationItem() const {
    if (m_type == IFCREPRESENTATIONITEM) {
        return m_IfcLayeredItem_union.m_IfcRepresentationItem;
    }
    else {
        return NULL;
    }
}

void IfcLayeredItem::setIfcRepresentationItem(IfcRepresentationItem *value) {
    if (m_type != UNSET) {
        deleteUnion();
    }
    m_IfcLayeredItem_union.m_IfcRepresentationItem = value;
    if (value) {
        value->ref();
        m_type = IFCREPRESENTATIONITEM;
    }
    else {
        m_type = UNSET;
    }
    m_type = IFCREPRESENTATIONITEM;
}

IfcRepresentation *IfcLayeredItem::getIfcRepresentation() const {
    if (m_type == IFCREPRESENTATION) {
        return m_IfcLayeredItem_union.m_IfcRepresentation;
    }
    else {
        return NULL;
    }
}

void IfcLayeredItem::setIfcRepresentation(IfcRepresentation *value) {
    if (m_type != UNSET) {
        deleteUnion();
    }
    m_IfcLayeredItem_union.m_IfcRepresentation = value;
    if (value) {
        value->ref();
        m_type = IFCREPRESENTATION;
    }
    else {
        m_type = UNSET;
    }
    m_type = IFCREPRESENTATION;
}

void IfcLayeredItem::set(Step::BaseObject *v)
{
    if (v != 0)
    {
        if (v->isOfType(IfcRepresentationItem::getClassType())) {
            setIfcRepresentationItem(static_cast< IfcRepresentationItem* > (v));
        }
        else if (v->isOfType(IfcRepresentation::getClassType())) {
            setIfcRepresentation(static_cast< IfcRepresentation* > (v));
        }
    }
}

IFC2X3_EXPORT Step::ClassType IfcLayeredItem::s_type("IfcLayeredItem");
<|endoftext|>


<commit_before>#pragma once
#include "restag.hpp"
#include "singleton.hpp"
#include <unordered_set>

namespace spi {
	//! 名前無しリソースマネージャ
	/*!
		中身の保持はすべてスマートポインタで行う
		シングルスレッド動作
	*/
	template <class T, class Allocator=std::allocator<T>>
	class ResMgr {
		public:
			using value_t = T;
			using shared_t = std::shared_ptr<value_t>;
		private:
			template <class Ar, class T2>
			friend void save(Ar&, const ResMgr<T2>&);
			template <class Ar, class T2>
			friend void load(Ar&, ResMgr<T2>&);

			using this_t = ResMgr<T>;
			using tag_t = ResTag<value_t>;

			using Set = std::unordered_set<tag_t>;
			struct Resource {
				Set			set;
			};
			using Resource_SP = std::shared_ptr<Resource>;

			template <bool B>
			class _iterator : public Set::iterator {
				public:
					using base_t = typename Set::iterator;
					using base_t::base_t;
					using v_t = std::conditional_t<B, const value_t, value_t>;
					using s_t = std::shared_ptr<v_t>;
					s_t operator *() const {
						return base_t::operator*().weak.lock();
					}
					s_t operator ->() const {
						return base_t::operator->()->weak.lock();
					}
			};
			using iterator = _iterator<false>;
			using const_iterator = _iterator<true>;

			Resource_SP		_resource;

			template <class P>
			static void _Release(const Resource_SP& r, P *const p) noexcept {
				auto& set = r->set;
				typename Allocator::template rebind<P>::other alc;
				const auto itr = set.find(p);
				try {
					Assert0(itr != set.end());
					set.erase(itr);
					alc.destroy(p);
					alc.deallocate(p, 1);
				} catch(...) {}
			}
		public:
			ResMgr():
				_resource(std::make_shared<Resource>())
			{}
			iterator begin() noexcept { return _resource->set.begin(); }
			iterator end() noexcept { return _resource->set.end(); }
			const_iterator begin() const noexcept { return _resource->set.begin(); }
			const_iterator end() const noexcept { return _resource->set.end(); }
			const_iterator cbegin() const noexcept { return _resource->set.cbegin(); }
			const_iterator cend() const noexcept { return _resource->set.cend(); }

			// (主にデバッグ用)
			bool operator == (const ResMgr& m) const noexcept {
				auto	&s0 = _resource->set,
						&s1 = m._resource->set;
				if(s0.size() == s1.size()) {
					auto itr0 = s0.begin(),
						 itr1 = s1.begin();
					while(itr0 != s0.end()) {
						if(*itr0 != *itr1)
							return false;
						++itr0;
						++itr1;
					}
					return true;
				}
				return false;
			}
			bool operator != (const ResMgr& m) const noexcept {
				return !(this->operator == (m));
			}
			template <class T2=value_t, class... Ts>
			auto emplace(Ts&&... ts) {
				typename Allocator::template rebind<T2>::other alc;
				T2 *const ptr = alc.allocate(1);
				alc.construct(ptr, std::forward<Ts>(ts)...);
				std::shared_ptr<T2> sp(
					ptr,
					[r=_resource](T2 *const p){
						_Release(r, p);
					}
				);
				D_Assert0(_resource->set.count(tag_t(sp.get())) == 0);

				// リソース管理のためのリスト登録
				_resource->set.emplace(sp);
				return sp;
			}
			std::size_t size() const noexcept {
				return _resource->set.size();
			}
	};
}
<commit_msg>resmgr: getResourceSet()を追加<commit_after>#pragma once
#include "restag.hpp"
#include "singleton.hpp"
#include <unordered_set>

namespace spi {
	//! 名前無しリソースマネージャ
	/*!
		中身の保持はすべてスマートポインタで行う
		シングルスレッド動作
	*/
	template <class T, class Allocator=std::allocator<T>>
	class ResMgr {
		public:
			using value_t = T;
			using shared_t = std::shared_ptr<value_t>;
		private:
			template <class Ar, class T2>
			friend void save(Ar&, const ResMgr<T2>&);
			template <class Ar, class T2>
			friend void load(Ar&, ResMgr<T2>&);

			using this_t = ResMgr<T>;
			using tag_t = ResTag<value_t>;

			using Set = std::unordered_set<tag_t>;
			struct Resource {
				Set			set;
			};
			using Resource_SP = std::shared_ptr<Resource>;

			template <bool B>
			class _iterator : public Set::iterator {
				public:
					using base_t = typename Set::iterator;
					using base_t::base_t;
					using v_t = std::conditional_t<B, const value_t, value_t>;
					using s_t = std::shared_ptr<v_t>;
					s_t operator *() const {
						return base_t::operator*().weak.lock();
					}
					s_t operator ->() const {
						return base_t::operator->()->weak.lock();
					}
			};
			using iterator = _iterator<false>;
			using const_iterator = _iterator<true>;

			Resource_SP		_resource;

			template <class P>
			static void _Release(const Resource_SP& r, P *const p) noexcept {
				auto& set = r->set;
				typename Allocator::template rebind<P>::other alc;
				const auto itr = set.find(p);
				try {
					Assert0(itr != set.end());
					set.erase(itr);
					alc.destroy(p);
					alc.deallocate(p, 1);
				} catch(...) {}
			}
		public:
			ResMgr():
				_resource(std::make_shared<Resource>())
			{}
			iterator begin() noexcept { return _resource->set.begin(); }
			iterator end() noexcept { return _resource->set.end(); }
			const_iterator begin() const noexcept { return _resource->set.begin(); }
			const_iterator end() const noexcept { return _resource->set.end(); }
			const_iterator cbegin() const noexcept { return _resource->set.cbegin(); }
			const_iterator cend() const noexcept { return _resource->set.cend(); }

			const Resource_SP& getResourceSet() noexcept {
				return _resource;
			}
			// (主にデバッグ用)
			bool operator == (const ResMgr& m) const noexcept {
				auto	&s0 = _resource->set,
						&s1 = m._resource->set;
				if(s0.size() == s1.size()) {
					auto itr0 = s0.begin(),
						 itr1 = s1.begin();
					while(itr0 != s0.end()) {
						if(*itr0 != *itr1)
							return false;
						++itr0;
						++itr1;
					}
					return true;
				}
				return false;
			}
			bool operator != (const ResMgr& m) const noexcept {
				return !(this->operator == (m));
			}
			template <class T2=value_t, class... Ts>
			auto emplace(Ts&&... ts) {
				typename Allocator::template rebind<T2>::other alc;
				T2 *const ptr = alc.allocate(1);
				alc.construct(ptr, std::forward<Ts>(ts)...);
				std::shared_ptr<T2> sp(
					ptr,
					[r=_resource](T2 *const p){
						_Release(r, p);
					}
				);
				D_Assert0(_resource->set.count(tag_t(sp.get())) == 0);

				// リソース管理のためのリスト登録
				_resource->set.emplace(sp);
				return sp;
			}
			std::size_t size() const noexcept {
				return _resource->set.size();
			}
	};
}
<|endoftext|>


<commit_before>#include "kirbi.h"
#include "Arduino.h"

#define LEFT_LIDAR_SERIAL Serial1
#define RIGHT_LIDAR_SERIAL Serial2

#define MAX_DIST //Whatever the lidar returns when it doesn't see anything

x_accel = new CircularArray<>(8);
y_accel = new CircularArray<>(8);
distances = new CircularArray<>(8);
current = new CircularArray<>(8);

enum State {
    SEARCH_LEFT,
    SEARCH_RIGHT,
    ADJUST_LEFT,
    ADJUST_RIGHT,
    SLAMMY_WHAMMY,
    PANIC_HIT,
    PANIC_FIRE,

    WAIT_FOR_START,
    STARTUP
};

State state_machine(State lastState) {
    curr_time = millis();
    get_distances();
    get_current();
    if (curr_time - prev_time > check_accel) {
        prev_time = millis();
        get_accel();
    }
    int[] curr_distances = distances.getFront();
    if (curr_distances[2] != MAX_DIST) {
        if (curr_distances[3] != MAX_DIST) {
            if (curr_distances[1] == 0 && curr_distances[4] == 0) {
                return SLAMMY_WHAMMY; //temp but kinda what we want
            } else if (curr_distances[1] == 1 && curr_distances[4] == 0) {
                return ADJUST_LEFT;
            } else if (curr_distances[1] == 0 && curr_distances[4] == 1) {
                return ADJUST_RIGHT;
            } else {
                return SLAMMY_WHAMMY; //either we're seeing them on all 4 middle sensors or something weird is happening
            }
        }

    } else if (curr_distances[3] != MAX_DIST) {

    } else if (lastState == WAIT_FOR_START) {
        return STARTUP;
    }

}

void drive(int left, int right) {
    left = left*left_multi;
    right = right*right_multi;
    // TODO: actually set ECSs
}

/**
 * INTERRUPT METHODS
**/
void do_line_action_left() {
    //TODO: implement
    drive(-x, -y);
}
void do_line_action_right() {
    //TODO: implement
    drive(-y, -x);
}

void increment_encoder_right() {
    right_encoder++;
}

void increment_encoder_left() {
    left_encoder++;
}

/**
 * Method for startup action
**/
void do_startup_action() {
    //TODO: implement
}

/**
 * SETUP METHODS
**/
 void setup_imu() {
    pinMode(9, OUTPUT);
    digitalWrite(9, LOW);
    Wire2.begin();
    Wire2.setSDA(8);
    Wire2.setSCL(7);
    icm.begin()
    icm.disableDataReadyInterrupt();
    icm.configAccel(ICM20948::ACCEL_RANGE_2G, ICM20948::ACCEL_DLPF_BANDWIDTH_6HZ);
    icm.configGyro(ICM20948::GYRO_RANGE_250DPS, ICM209480::GYRO_DLPF_BANDWIDTH_6HZ);
 }

 void setup_distance() {
     /* lidar setup */
     LIDAR_SERIAL.begin(115200);
     LIDAR_SERIAL.write(configUART, 5);
     LIDAR_SERIAL.write(configOutput, 5);
     // TODO: the rest of the distance sensors
 }

 void setup_current() {
    // ignore for now
 }

 void setup_motors(){
     // TODO: implement
    left_multi = 1;
    right_multi = 1;
 }

/**
 * SENSOR READ METHODS
**/
void get_accel() {
    //TODO: implement
    x_accel.add(icm.getAccelX_mss());
    y_accel.add(icm.getAccelY_mss());
}
void get_gyro() {
    //TODO: implement
}
void get_distances() {
    //TODO: implement
    int[] dist = int[6];
    dist[0] = digitalRead(omron0);
    dist[1] = digitalRead(omron1);
    dist[2] = read_lidar(LEFT_LIDAR_SERIAL);
    dist[3] = read_lidar(RIGHT_LIDAR_SERIAL);
    dist[4] = digitalRead(omron4);
    dist[5] = digitalRead(omron5);
    distances.add(dist);
    return dist;
}
int read_lidar(Serial s) {
    byte[] bytes = byte[9];
    s.readBytes(bytes, 9);
    int dist_low = 0;
    while (dist_low < 9) {
        if (bytes[dist_low] == 0x89) {
            if (dist_low == 0) {
                if (bytes[8] == 0x89) {
                    return bytes[1] + (bytes[2] << 8);
                }
            } else if (dist_low == 7) {
                if (bytes[8] == 0x89) {
                    return bytes[0] + (bytes[1] << 8);
                }
            } else {
                if (bytes[++dist_low] == 0x89) {
                    return bytes[++dist_low] + (bytes[++dist_low] << 8);
                }
            }
        }
        dist_low++;
    }
    return read_lidar(s);
}
void get_current() {
    // ignore for now
}

/**
 * OTHER
**/
void balance_motors() {
    if (left_encoder > right_encoder) {
        left_multi = right_encoder/left_encoder;
        right_multi = 1;
    } else {
        right_multi = left_encoder/right_encoder;
        left_multi = 1;
    }
}<commit_msg>Added definitions for use in methods involving the ESC. Finished implementing drive with some modifications to its parameters.<commit_after>#include "kirbi.h"
#include "Arduino.h"

#define LEFT_LIDAR_SERIAL Serial1
#define RIGHT_LIDAR_SERIAL Serial4

#define ESC_SERIAL Serial5
#define ESC_ADDRESS 128
#define ESC_CHECKSUM 0b01111111

#define MAX_DIST //Whatever the lidar returns when it doesn't see anything

x_accel = new CircularArray<>(8);
y_accel = new CircularArray<>(8);
distances = new CircularArray<>(8);
current = new CircularArray<>(8);

enum State {
    SEARCH_LEFT,
    SEARCH_RIGHT,
    ADJUST_LEFT,
    ADJUST_RIGHT,
    SLAMMY_WHAMMY,
    PANIC_HIT,
    PANIC_FIRE,

    WAIT_FOR_START,
    STARTUP
};

State state_machine(State lastState) {
    curr_time = millis();
    get_distances();
    get_current();
    if (curr_time - prev_time > check_accel) {
        prev_time = millis();
        get_accel();
    }
    int[] curr_distances = distances.getFront();
    if (curr_distances[2] != MAX_DIST) {
        if (curr_distances[3] != MAX_DIST) {
            if (curr_distances[1] == 0 && curr_distances[4] == 0) {
                return SLAMMY_WHAMMY; //temp but kinda what we want
            } else if (curr_distances[1] == 1 && curr_distances[4] == 0) {
                return ADJUST_LEFT;
            } else if (curr_distances[1] == 0 && curr_distances[4] == 1) {
                return ADJUST_RIGHT;
            } else {
                return SLAMMY_WHAMMY; //either we're seeing them on all 4 middle sensors or something weird is happening
            }
        }

    } else if (curr_distances[3] != MAX_DIST) {

    } else if (lastState == WAIT_FOR_START) {
        return STARTUP;
    }

}

void drive(int left, int right, bool left_reverse, bool right_reverse) {
    left = left*left_multi;
    right = right*right_multi;
    ESC_SERIAL.write(ESC_ADDRESS);
    ESC_SERIAL.write(left_reverse);
    ESC_SERIAL.write(left);
    ESC_SERIAL.write((ESC_ADDRESS+left_reverse+left)&ESC_CHECKSUM);
    ESC_SERIAL.write(ESC_ADDRESS);
    ESC_SERIAL.write(right_reverse);
    ESC_SERIAL.write(right);
    ESC_SERIAL.write((ESC_ADDRESS+right_reverse+right)&ESC_CHECKSUM);
}

/**
 * INTERRUPT METHODS
**/
void do_line_action_left() {
    //TODO: implement
    drive(x, y, true, true);
}
void do_line_action_right() {
    //TODO: implement
    drive(y, x, true, true);
}

void increment_encoder_right() {
    right_encoder++;
}

void increment_encoder_left() {
    left_encoder++;
}

/**
 * Method for startup action
**/
void do_startup_action() {
    //TODO: implement
}

/**
 * SETUP METHODS
**/
 void setup_imu() {
    pinMode(9, OUTPUT);
    digitalWrite(9, LOW);
    Wire2.begin();
    Wire2.setSDA(8);
    Wire2.setSCL(7);
    icm.begin()
    icm.disableDataReadyInterrupt();
    icm.configAccel(ICM20948::ACCEL_RANGE_2G, ICM20948::ACCEL_DLPF_BANDWIDTH_6HZ);
    icm.configGyro(ICM20948::GYRO_RANGE_250DPS, ICM209480::GYRO_DLPF_BANDWIDTH_6HZ);
 }

 void setup_distance() {
     /* lidar setup */
     LEFT_LIDAR_SERIAL.begin(115200);
     LEFT_LIDAR_SERIAL.write(configUART, 5);
     LEFT_LIDAR_SERIAL.write(configOutput, 5);
     RIGHT_LIDAR_SERIAL.begin(115200);
     RIGHT_LIDAR_SERIAL.write(configUART, 5);
     RIGHT_LIDAR_SERIAL.write(configOutput, 5);
     // TODO: the rest of the distance sensors
 }

 void setup_current() {
    // ignore for now
 }

 void setup_motors(){
     // TODO: implement
    left_multi = 1;
    right_multi = 1;
    ESC_SERIAL.begin(115200);
 }

/**
 * SENSOR READ METHODS
**/
void get_accel() {
    //TODO: implement
    x_accel.add(icm.getAccelX_mss());
    y_accel.add(icm.getAccelY_mss());
}
void get_gyro() {
    //TODO: implement?
}
void get_distances() {
    //TODO: implement
    int[] dist = int[6];
    dist[0] = digitalRead(omron0);
    dist[1] = digitalRead(omron1);
    dist[2] = read_lidar(LEFT_LIDAR_SERIAL);
    dist[3] = read_lidar(RIGHT_LIDAR_SERIAL);
    dist[4] = digitalRead(omron4);
    dist[5] = digitalRead(omron5);
    distances.add(dist);
    return dist;
}
int read_lidar(Serial s) {
    byte[] bytes = byte[9];
    s.readBytes(bytes, 9);
    int dist_low = 0;
    while (dist_low < 9) {
        if (bytes[dist_low] == 0x89) {
            if (dist_low == 0) {
                if (bytes[8] == 0x89) {
                    return bytes[1] + (bytes[2] << 8);
                }
            } else if (dist_low == 7) {
                if (bytes[8] == 0x89) {
                    return bytes[0] + (bytes[1] << 8);
                }
            } else {
                if (bytes[++dist_low] == 0x89) {
                    return bytes[++dist_low] + (bytes[++dist_low] << 8);
                }
            }
        }
        dist_low++;
    }
    return read_lidar(s);
}
void get_current() {
    // ignore for now
}

/**
 * OTHER
**/
void balance_motors() {
    if (left_encoder > right_encoder) {
        left_multi = right_encoder/left_encoder;
        right_multi = 1;
    } else {
        right_multi = left_encoder/right_encoder;
        left_multi = 1;
    }
}<|endoftext|>