<commit_before>/*-
 * Copyright (c) 2010 Benjamin Close <Benjamin.Close@clearchain.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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 AUTHOR 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 AUTHOR 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 "CameraException.h"
#include "DC1394CameraFactory.h"

namespace wcl {

	DC1394CameraFactory *DC1394CameraFactory::instance;
	std::vector<DC1394Camera *> DC1394CameraFactory::cameras;

	DC1394CameraFactory::DC1394CameraFactory()
	{
	}

	DC1394CameraFactory::~DC1394CameraFactory()
	{
		for(std::vector<DC1394Camera *>::iterator it = this->cameras.begin();
				it != this->cameras.end();
				++it )
		{
			DC1394Camera *c = *it;
			delete c;
		}
	}

	DC1394CameraFactory *DC1394CameraFactory::getInstance()
	{
		if( DC1394CameraFactory::instance == NULL ){
			DC1394CameraFactory::instance = new DC1394CameraFactory();
			instance->probeCameras();
		}

		return DC1394CameraFactory::instance;
	}

	std::vector<DC1394Camera *> DC1394CameraFactory::getCameras()
	{
		DC1394CameraFactory *instance = DC1394CameraFactory::getInstance();
		return instance->cameras;
	}

	void DC1394CameraFactory::probeCameras()
	{
		using namespace std;

		// attempt to located the cameras on the firewire bus
		dc1394error_t err;
		dc1394_t * d;
		dc1394camera_list_t * list;
		d = dc1394_new ();
		if( !d )
		    throw CameraException(CameraException::EACCESS);

		err=dc1394_camera_enumerate (d, &list);

		for( unsigned i = 0 ; i < list->num; i++ ){
			DC1394Camera *c = new DC1394Camera(list->ids[i].guid);
			this->cameras.push_back(c);
		}

		dc1394_camera_free_list(list);
	}

}
<commit_msg>camera: Throw an exception if cameras can't be enumerated<commit_after>/*-
 * Copyright (c) 2010 Benjamin Close <Benjamin.Close@clearchain.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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 AUTHOR 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 AUTHOR 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 "CameraException.h"
#include "DC1394CameraFactory.h"

namespace wcl {

	DC1394CameraFactory *DC1394CameraFactory::instance;
	std::vector<DC1394Camera *> DC1394CameraFactory::cameras;

	DC1394CameraFactory::DC1394CameraFactory()
	{
	}

	DC1394CameraFactory::~DC1394CameraFactory()
	{
		for(std::vector<DC1394Camera *>::iterator it = this->cameras.begin();
				it != this->cameras.end();
				++it )
		{
			DC1394Camera *c = *it;
			delete c;
		}
	}

	DC1394CameraFactory *DC1394CameraFactory::getInstance()
	{
		if( DC1394CameraFactory::instance == NULL ){
			DC1394CameraFactory::instance = new DC1394CameraFactory();
			instance->probeCameras();
		}

		return DC1394CameraFactory::instance;
	}

	std::vector<DC1394Camera *> DC1394CameraFactory::getCameras()
	{
		DC1394CameraFactory *instance = DC1394CameraFactory::getInstance();
		return instance->cameras;
	}

	void DC1394CameraFactory::probeCameras()
	{
		using namespace std;

		// attempt to located the cameras on the firewire bus
		dc1394_t * d;
		dc1394camera_list_t * list;
		d = dc1394_new ();
		if( !d )
		    throw CameraException(CameraException::EACCESS);

		if(dc1394_camera_enumerate (d, &list) !=  DC1394_SUCCESS )
		    throw CameraException(CameraException::CONNECTIONISSUE);

		for( unsigned i = 0 ; i < list->num; i++ ){
			DC1394Camera *c = new DC1394Camera(list->ids[i].guid);
			this->cameras.push_back(c);
		}

		dc1394_camera_free_list(list);
	}

}
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015, Google Inc.
 * 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.
 *     * Neither the name of Google Inc. 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.
 *is % allowed in string
 */

#include <memory>
#include <string>

#include <gflags/gflags.h>
#include <grpc++/grpc++.h>

#include "test/cpp/util/metrics_server.h"
#include "test/cpp/util/test_config.h"
#include "test/proto/metrics.grpc.pb.h"
#include "test/proto/metrics.pb.h"

DEFINE_string(metrics_server_address, "",
              "The metrics server addresses in the fomrat <hostname>:<port>");

using grpc::testing::EmptyMessage;
using grpc::testing::GaugeResponse;
using grpc::testing::MetricsService;
using grpc::testing::MetricsServiceImpl;

void PrintMetrics(grpc::string& server_address) {
  gpr_log(GPR_INFO, "creating a channel to %s", server_address.c_str());
  std::shared_ptr<grpc::Channel> channel(
      grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials()));

  std::unique_ptr<MetricsService::Stub> stub(MetricsService::NewStub(channel));

  grpc::ClientContext context;
  EmptyMessage message;

  std::unique_ptr<grpc::ClientReader<GaugeResponse>> reader(
      stub->GetAllGauges(&context, message));

  GaugeResponse gauge_response;
  long overall_qps = 0;
  int idx = 0;
  while (reader->Read(&gauge_response)) {
    if (gauge_response.value_case() == GaugeResponse::kLongValue) {
      gpr_log(GPR_INFO, "Gauge: %d (%s: %ld)", ++idx,
              gauge_response.name().c_str(), gauge_response.long_value());
      overall_qps += gauge_response.long_value();
    } else {
      gpr_log(GPR_INFO, "Gauge %s is not a long value",
              gauge_response.name().c_str());
    }
  }

  gpr_log(GPR_INFO, "OVERALL: %ld", overall_qps);

  const grpc::Status status = reader->Finish();
  if (!status.ok()) {
    gpr_log(GPR_ERROR, "Error in getting metrics from the client");
  }
}

int main(int argc, char** argv) {
  grpc::testing::InitTest(&argc, &argv, true);

  // Make sure server_addresses flag is not empty
  if (FLAGS_metrics_server_address.empty()) {
    gpr_log(
        GPR_ERROR,
        "Cannot connect to the Metrics server. Please pass the address of the"
        "metrics server to connect to via the 'metrics_server_address' flag");
    return 1;
  }

  PrintMetrics(FLAGS_metrics_server_address);

  return 0;
}
<commit_msg>Fix for when grpc::string is not the same type as FLAGS_...<commit_after>/*
 *
 * Copyright 2015, Google Inc.
 * 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.
 *     * Neither the name of Google Inc. 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.
 *is % allowed in string
 */

#include <memory>
#include <string>

#include <gflags/gflags.h>
#include <grpc++/grpc++.h>

#include "test/cpp/util/metrics_server.h"
#include "test/cpp/util/test_config.h"
#include "test/proto/metrics.grpc.pb.h"
#include "test/proto/metrics.pb.h"

DEFINE_string(metrics_server_address, "",
              "The metrics server addresses in the fomrat <hostname>:<port>");

using grpc::testing::EmptyMessage;
using grpc::testing::GaugeResponse;
using grpc::testing::MetricsService;
using grpc::testing::MetricsServiceImpl;

void PrintMetrics(const grpc::string& server_address) {
  gpr_log(GPR_INFO, "creating a channel to %s", server_address.c_str());
  std::shared_ptr<grpc::Channel> channel(
      grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials()));

  std::unique_ptr<MetricsService::Stub> stub(MetricsService::NewStub(channel));

  grpc::ClientContext context;
  EmptyMessage message;

  std::unique_ptr<grpc::ClientReader<GaugeResponse>> reader(
      stub->GetAllGauges(&context, message));

  GaugeResponse gauge_response;
  long overall_qps = 0;
  int idx = 0;
  while (reader->Read(&gauge_response)) {
    if (gauge_response.value_case() == GaugeResponse::kLongValue) {
      gpr_log(GPR_INFO, "Gauge: %d (%s: %ld)", ++idx,
              gauge_response.name().c_str(), gauge_response.long_value());
      overall_qps += gauge_response.long_value();
    } else {
      gpr_log(GPR_INFO, "Gauge %s is not a long value",
              gauge_response.name().c_str());
    }
  }

  gpr_log(GPR_INFO, "OVERALL: %ld", overall_qps);

  const grpc::Status status = reader->Finish();
  if (!status.ok()) {
    gpr_log(GPR_ERROR, "Error in getting metrics from the client");
  }
}

int main(int argc, char** argv) {
  grpc::testing::InitTest(&argc, &argv, true);

  // Make sure server_addresses flag is not empty
  if (FLAGS_metrics_server_address.empty()) {
    gpr_log(
        GPR_ERROR,
        "Cannot connect to the Metrics server. Please pass the address of the"
        "metrics server to connect to via the 'metrics_server_address' flag");
    return 1;
  }

  PrintMetrics(FLAGS_metrics_server_address);

  return 0;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2016 Artem Pavlenko
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
// mapnik
#include <mapnik/text/face.hpp>
#include <mapnik/debug.hpp>

#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>

extern "C"
{
#include FT_GLYPH_H
#include FT_TRUETYPE_TABLES_H
}

#pragma GCC diagnostic pop

namespace mapnik
{

font_face::font_face(FT_Face face)
    : face_(face)
{
    static const uint32_t tag = FT_MAKE_TAG('C', 'B', 'D', 'T');
    unsigned long length = 0;
    FT_Load_Sfnt_Table(face_, tag, 0, nullptr, &length);
    if (length) color_font_ = true;
}

bool font_face::set_character_sizes(double size)
{
    return (FT_Set_Char_Size(face_, 0, static_cast<FT_F26Dot6>(size * (1 << 6)), 0, 0) == 0);
}

bool font_face::set_unscaled_character_sizes()
{
    FT_F26Dot6 char_height = face_->units_per_EM > 0 ? face_->units_per_EM : 2048.0;
    return (FT_Set_Char_Size(face_, 0, char_height, 0, 0) == 0);
}

bool font_face::glyph_dimensions(glyph_info & glyph) const
{
    FT_Vector pen;
    pen.x = 0;
    pen.y = 0;
    if (color_font_) FT_Select_Size(face_, 0);
    FT_Set_Transform(face_, 0, &pen);
    FT_Int32 load_flags = FT_LOAD_DEFAULT;// | FT_LOAD_NO_HINTING;
    if (color_font_) load_flags |= FT_LOAD_COLOR ;
    if (FT_Load_Glyph(face_, glyph.glyph_index, load_flags))
    {
        MAPNIK_LOG_ERROR(font_face) << "FT_Load_Glyph failed :( index=" << glyph.glyph_index << " " << load_flags
                                    << " " << face_->family_name << " " << face_->style_name  ;
        return false;
    }
    FT_Glyph image;
    if (FT_Get_Glyph(face_->glyph, &image))
    {
        MAPNIK_LOG_ERROR(font_face) << "FT_Get_Glyph failed";
        return false;
    }
    FT_BBox glyph_bbox;
    FT_Glyph_Get_CBox(image, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox);
    FT_Done_Glyph(image);
    glyph.unscaled_ymin = glyph_bbox.yMin;
    glyph.unscaled_ymax = glyph_bbox.yMax;
    glyph.unscaled_advance = face_->glyph->advance.x;
    glyph.unscaled_line_height = face_->size->metrics.height;
    return true;
}

font_face::~font_face()
{
    MAPNIK_LOG_DEBUG(font_face) <<
        "font_face: Clean up face \"" << family_name() <<
        " " << style_name() << "\"";

    FT_Done_Face(face_);
}

/******************************************************************************/

void font_face_set::add(face_ptr face)
{
    faces_.push_back(face);
}

void font_face_set::set_character_sizes(double _size)
{
    for (face_ptr const& face : faces_)
    {
        face->set_character_sizes(_size);
    }
}

void font_face_set::set_unscaled_character_sizes()
{
    for (face_ptr const& face : faces_)
    {
        face->set_unscaled_character_sizes();
    }
}

/******************************************************************************/

void stroker::init(double radius)
{
    FT_Stroker_Set(s_, static_cast<FT_Fixed>(radius * (1<<6)),
                   FT_STROKER_LINECAP_ROUND,
                   FT_STROKER_LINEJOIN_ROUND,
                   0);
}

stroker::~stroker()
{
    MAPNIK_LOG_DEBUG(font_engine_freetype) << "stroker: Destroy stroker=" << s_;

    FT_Stroker_Done(s_);
}

}//ns mapnik
<commit_msg>don't forget FT_LOAD_NO_HINTING<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2016 Artem Pavlenko
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
// mapnik
#include <mapnik/text/face.hpp>
#include <mapnik/debug.hpp>

#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>

extern "C"
{
#include FT_GLYPH_H
#include FT_TRUETYPE_TABLES_H
}

#pragma GCC diagnostic pop

namespace mapnik
{

font_face::font_face(FT_Face face)
    : face_(face)
{
    static const uint32_t tag = FT_MAKE_TAG('C', 'B', 'D', 'T');
    unsigned long length = 0;
    FT_Load_Sfnt_Table(face_, tag, 0, nullptr, &length);
    if (length) color_font_ = true;
}

bool font_face::set_character_sizes(double size)
{
    return (FT_Set_Char_Size(face_, 0, static_cast<FT_F26Dot6>(size * (1 << 6)), 0, 0) == 0);
}

bool font_face::set_unscaled_character_sizes()
{
    FT_F26Dot6 char_height = face_->units_per_EM > 0 ? face_->units_per_EM : 2048.0;
    return (FT_Set_Char_Size(face_, 0, char_height, 0, 0) == 0);
}

bool font_face::glyph_dimensions(glyph_info & glyph) const
{
    FT_Vector pen;
    pen.x = 0;
    pen.y = 0;
    if (color_font_) FT_Select_Size(face_, 0);
    FT_Set_Transform(face_, 0, &pen);
    FT_Int32 load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
    if (color_font_) load_flags |= FT_LOAD_COLOR ;
    if (FT_Load_Glyph(face_, glyph.glyph_index, load_flags))
    {
        MAPNIK_LOG_ERROR(font_face) << "FT_Load_Glyph failed :( index=" << glyph.glyph_index << " " << load_flags
                                    << " " << face_->family_name << " " << face_->style_name  ;
        return false;
    }
    FT_Glyph image;
    if (FT_Get_Glyph(face_->glyph, &image))
    {
        MAPNIK_LOG_ERROR(font_face) << "FT_Get_Glyph failed";
        return false;
    }
    FT_BBox glyph_bbox;
    FT_Glyph_Get_CBox(image, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox);
    FT_Done_Glyph(image);
    glyph.unscaled_ymin = glyph_bbox.yMin;
    glyph.unscaled_ymax = glyph_bbox.yMax;
    glyph.unscaled_advance = face_->glyph->advance.x;
    glyph.unscaled_line_height = face_->size->metrics.height;
    return true;
}

font_face::~font_face()
{
    MAPNIK_LOG_DEBUG(font_face) <<
        "font_face: Clean up face \"" << family_name() <<
        " " << style_name() << "\"";

    FT_Done_Face(face_);
}

/******************************************************************************/

void font_face_set::add(face_ptr face)
{
    faces_.push_back(face);
}

void font_face_set::set_character_sizes(double _size)
{
    for (face_ptr const& face : faces_)
    {
        face->set_character_sizes(_size);
    }
}

void font_face_set::set_unscaled_character_sizes()
{
    for (face_ptr const& face : faces_)
    {
        face->set_unscaled_character_sizes();
    }
}

/******************************************************************************/

void stroker::init(double radius)
{
    FT_Stroker_Set(s_, static_cast<FT_Fixed>(radius * (1<<6)),
                   FT_STROKER_LINECAP_ROUND,
                   FT_STROKER_LINEJOIN_ROUND,
                   0);
}

stroker::~stroker()
{
    MAPNIK_LOG_DEBUG(font_engine_freetype) << "stroker: Destroy stroker=" << s_;

    FT_Stroker_Done(s_);
}

}//ns mapnik
<|endoftext|>


<commit_before>#include "threadpool.h"

// Function that retrieves a task from a queue, runs it and deletes it
static void *getWork(void * param) {
	Task *mw = 0;
	Queue<Task *> *wq = (Queue<Task *> *)param;
	while (wq->pop(mw)) {
		mw->run();
		delete mw;
	}
	return 0;
}

// Allocate a thread pool and set them to work trying to get tasks
ThreadPool::ThreadPool(int n) : numThreads(n) {
	printf("Creating a thread pool with %d threads\n", n);

	threads = new pthread_t[numThreads];
	for (int i = 0; i < numThreads; ++i) {
		pthread_create(&(threads[i]), 0, getWork, &workQueue);
	}
}

// Wait for the threads to finish, then delete them
ThreadPool::~ThreadPool() {
	finish();
	for (int i = 0; i < numThreads; ++i) {
		pthread_join(threads[i], 0);
	}
	delete [] threads;
}

// Add a task
void ThreadPool::addTask(Task *nt) {
	workQueue.push(nt);
}

// Tell the tasks to finish and return
void ThreadPool::finish() {
	workQueue.finish();
}
<commit_msg>Use NULL<commit_after>#include "threadpool.h"

// Function that retrieves a task from a queue, runs it and deletes it
static void *getWork(void * param) {
	Queue<Task *> *wq = (Queue<Task *> *)param;
	Task *mw = NULL;
	while (wq->pop(mw)) {
		mw->run();
		delete mw;
	}
	return NULL;
}

// Allocate a thread pool and set them to work trying to get tasks
ThreadPool::ThreadPool(int n) : numThreads(n) {
	printf("Creating a thread pool with %d threads\n", n);

	threads = new pthread_t[numThreads];
	for (int i = 0; i < numThreads; ++i) {
		pthread_create(&(threads[i]), 0, getWork, &workQueue);
	}
}

// Wait for the threads to finish, then delete them
ThreadPool::~ThreadPool() {
	finish();
	for (int i = 0; i < numThreads; ++i) {
		pthread_join(threads[i], 0);
	}
	delete [] threads;
}

// Add a task
void ThreadPool::addTask(Task *nt) {
	workQueue.push(nt);
}

// Tell the tasks to finish and return
void ThreadPool::finish() {
	workQueue.finish();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "threadpool.h"

#include "utils.h"

#include <assert.h>
#include <string.h>

struct ThreadInfo {
    int threadNumber;
    const char *format;
    Queue<Task *> *workQueue;
};

void Task::inc_ref()
{
	pthread_mutex_lock(&task_mutex);
	refs++;
	pthread_mutex_unlock(&task_mutex);
}

void Task::rel_ref()
{
	pthread_mutex_lock(&task_mutex);
	refs--;
	assert(refs >= 0);
	if (refs == 0) {
		pthread_mutex_unlock(&task_mutex);
		delete this;
	} else {
		pthread_mutex_unlock(&task_mutex);
	}
};

Task::Task() : refs(0)
{
	pthread_mutexattr_init(&task_mutex_attr);
	pthread_mutexattr_settype(&task_mutex_attr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&task_mutex, &task_mutex_attr);
}

Task::~Task()
{
	pthread_mutex_destroy(&task_mutex);
	pthread_mutexattr_destroy(&task_mutex_attr);
}

// Function that retrieves a task from a queue, runs it and deletes it
void *ThreadPool::getWork(void * wq_=NULL) {
    ThreadInfo *threadInfo = static_cast<ThreadInfo *>(wq_);
    char name[100];
    sprintf(name, threadInfo->format, threadInfo->threadNumber);
#ifdef HAVE_PTHREAD_SETNAME_NP_2
    pthread_setname_np(pthread_self(), name);
#else
    pthread_setname_np(name);
#endif
	Task *mw;
	while (threadInfo->workQueue->pop(mw)) {
		mw->run();
		mw->rel_ref();
	}
    delete threadInfo;
	return NULL;
}

// Allocate a thread pool and set them to work trying to get tasks
ThreadPool::ThreadPool(const char *format, int n) : numThreads(n) {
	LOG_OBJ(this, "Creating a thread pool with %d threads\n", n);

	threads = new pthread_t[numThreads];
	for (int i = 0; i < numThreads; ++i) {
        ThreadInfo *threadInfo = new ThreadInfo();
        threadInfo->threadNumber = i;
        threadInfo->format = format;
        threadInfo->workQueue = &workQueue;
		if (pthread_create(&(threads[i]), 0, getWork, threadInfo) != 0) {
			LOG_ERR(this, "ERROR: thread: %s\n", strerror(errno));
			threads[i] = 0;
		}
	}
}

// Wait for the threads to finish, then delete them
ThreadPool::~ThreadPool() {
	finish();
	join();
	delete [] threads;
}

void ThreadPool::join() {
	for (int i = 0; i < numThreads; ++i) {
		if (threads[i]) {
			if (pthread_join(threads[i], 0) != 0) {
				LOG_ERR(this, "ERROR: thread: %s\n", strerror(errno));
			} else {
				threads[i] = 0;
			}
		}
	}
}

// Add a task
void ThreadPool::addTask(Task *nt) {
	nt->inc_ref();
	workQueue.push(nt);
}

// Tell the tasks to finish and return
void ThreadPool::finish() {
	workQueue.finish();
}

size_t ThreadPool::length(){
	return workQueue.size();
}<commit_msg>Style cleanups<commit_after>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "threadpool.h"

#include "utils.h"

#include <assert.h>
#include <string.h>

struct ThreadInfo {
	int threadNumber;
	const char *format;
	Queue<Task *> *workQueue;
};

void Task::inc_ref()
{
	pthread_mutex_lock(&task_mutex);
	refs++;
	pthread_mutex_unlock(&task_mutex);
}

void Task::rel_ref()
{
	pthread_mutex_lock(&task_mutex);
	refs--;
	assert(refs >= 0);
	if (refs == 0) {
		pthread_mutex_unlock(&task_mutex);
		delete this;
	} else {
		pthread_mutex_unlock(&task_mutex);
	}
};

Task::Task() : refs(0)
{
	pthread_mutexattr_init(&task_mutex_attr);
	pthread_mutexattr_settype(&task_mutex_attr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&task_mutex, &task_mutex_attr);
}

Task::~Task()
{
	pthread_mutex_destroy(&task_mutex);
	pthread_mutexattr_destroy(&task_mutex_attr);
}

// Function that retrieves a task from a queue, runs it and deletes it
void *ThreadPool::getWork(void * wq_=NULL) {
	ThreadInfo *threadInfo = static_cast<ThreadInfo *>(wq_);
	char name[100];
	sprintf(name, threadInfo->format, threadInfo->threadNumber);
#ifdef HAVE_PTHREAD_SETNAME_NP_2
	pthread_setname_np(pthread_self(), name);
#else
	pthread_setname_np(name);
#endif
	Task *mw;
	while (threadInfo->workQueue->pop(mw)) {
		mw->run();
		mw->rel_ref();
	}
	delete threadInfo;
	return NULL;
}

// Allocate a thread pool and set them to work trying to get tasks
ThreadPool::ThreadPool(const char *format, int n) : numThreads(n) {
	LOG_OBJ(this, "Creating a thread pool with %d threads\n", n);

	threads = new pthread_t[numThreads];
	for (int i = 0; i < numThreads; ++i) {
		ThreadInfo *threadInfo = new ThreadInfo();
		threadInfo->threadNumber = i;
		threadInfo->format = format;
		threadInfo->workQueue = &workQueue;
		if (pthread_create(&(threads[i]), 0, getWork, threadInfo) != 0) {
			LOG_ERR(this, "ERROR: thread: %s\n", strerror(errno));
			threads[i] = 0;
		}
	}
}

// Wait for the threads to finish, then delete them
ThreadPool::~ThreadPool() {
	finish();
	join();
	delete [] threads;
}

void ThreadPool::join() {
	for (int i = 0; i < numThreads; ++i) {
		if (threads[i]) {
			if (pthread_join(threads[i], 0) != 0) {
				LOG_ERR(this, "ERROR: thread: %s\n", strerror(errno));
			} else {
				threads[i] = 0;
			}
		}
	}
}

// Add a task
void ThreadPool::addTask(Task *nt) {
	nt->inc_ref();
	workQueue.push(nt);
}

// Tell the tasks to finish and return
void ThreadPool::finish() {
	workQueue.finish();
}

size_t ThreadPool::length(){
	return workQueue.size();
}<|endoftext|>


<commit_before>// Copyright (c) 2017 Andrey Valyaev
//
// This software may be modified and distributed under the terms
// of the MIT license.  See the LICENSE file for details.

#include <upp11.h>

using namespace std;

UP_SUITE_BEGIN(gost89)
UP_SUITE_BEGIN(ProceduralImitTest)

class Key final {
public:
	explicit Key(const void *key)
		: sbox()
	{
		memcpy(key_, key, sizeof(key_));
		memset(mask_, 0, sizeof(mask_));
	}

	virtual void set_sbox(const void *box) {
		const uint8_t *sptr = static_cast<const uint8_t *>(box);
		expand_tab(sptr, 0, &sbox[0]);
		expand_tab(sptr, 1, &sbox[256]);
		expand_tab(sptr, 2, &sbox[512]);
		expand_tab(sptr, 3, &sbox[768]);
	}

private:
	friend class ImitContext;

	void expand_tab(const uint8_t sbox[64], size_t offset, uint8_t tab[256]) {
		for (size_t i = 0; i < 256; i++) {
			tab[i] = (sbox[(i / 16) * 4 + offset] & 0xf0)
				+ (sbox[(i % 16) * 4 + offset] & 0x0f);
		}
	}

	uint32_t key_[8];
	uint32_t mask_[8];
	array<uint8_t, 1024> sbox;
};

class ImitContext final {
public:
	explicit ImitContext(const Key *key)
		: key_(key), blocks(0)
	{
		memset(state, 0, sizeof(state));
	}

	void imit(const void *data, size_t len, int expand = 0)
	{
		if (len % 8 != 0 && !expand) {
			throw length_error("Imit::imit(): data length isn't "
					"multiple of block size");
		}

		const uint8_t *ptr = static_cast<const uint8_t *>(data);

		while (len >= 8) {
			for (int i = 0; i < 8; i++) {
				state[i] ^= ptr[i];
			}

			imit_block(state);
			blocks++;
			ptr += 8;
			len -= 8;
		}

		if (len != 0) {
			for (size_t i = 0; i < len; i++) {
				state[i] ^= ptr[i];
			}

			imit_block(state);
			blocks++;
		}
	}

	uint32_t result()
	{
		check_two_blocks();
		uint32_t result;
		memcpy(&result, &state[0], sizeof(result));
		return result;
	}

private:
	void check_two_blocks() {
		while (blocks < 2) {
			imit_block(state);
			blocks++;
		}
	}

	void cycle(uint32_t *half1, uint32_t *half2,
		 const uint32_t key, const uint32_t mask) const
	{
		uint32_t tmp1 = key + *half2 - mask;
		uint32_t tmp2 = key_->sbox[tmp1 & 0xff];
		tmp2 |= (key_->sbox[256 + ((tmp1 >> 8) & 0xff)]) << 8;
		tmp2 |= (key_->sbox[512 + ((tmp1 >> 16) & 0xff)]) << 16;
		tmp2 |= (key_->sbox[768 + ((tmp1 >> 24) & 0xff)]) << 24;
		tmp2 = (tmp2 << 11) | ((tmp2 >> 21) & 0x7ff);

		*half1 ^= tmp2;
	}

	void imit_block(void *block) const {
		uint32_t a = static_cast<uint32_t *>(block)[1];
		uint32_t b = static_cast<uint32_t *>(block)[0];
		const uint32_t *ekey = key_->key_;
		const uint32_t *emask = key_->mask_;

		cycle(&a, &b, ekey[0], emask[0]);
		cycle(&b, &a, ekey[1], emask[1]);
		cycle(&a, &b, ekey[2], emask[2]);
		cycle(&b, &a, ekey[3], emask[3]);
		cycle(&a, &b, ekey[4], emask[4]);
		cycle(&b, &a, ekey[5], emask[5]);
		cycle(&a, &b, ekey[6], emask[6]);
		cycle(&b, &a, ekey[7], emask[7]);

		cycle(&a, &b, ekey[0], emask[0]);
		cycle(&b, &a, ekey[1], emask[1]);
		cycle(&a, &b, ekey[2], emask[2]);
		cycle(&b, &a, ekey[3], emask[3]);
		cycle(&a, &b, ekey[4], emask[4]);
		cycle(&b, &a, ekey[5], emask[5]);
		cycle(&a, &b, ekey[6], emask[6]);
		cycle(&b, &a, ekey[7], emask[7]);

		static_cast<uint32_t *>(block)[1] = a;
		static_cast<uint32_t *>(block)[0] = b;
	}

	const Key *key_;
	uint8_t state[8];
	size_t blocks;
};

UP_TEST(Benchmark10M)
{
	// Given
	const vector<uint8_t> data(10000000U, 'A');
	vector<uint32_t> keydata = {
		0xE0F67504U,
		0xFAFB3850U,
		0x90C3C7D2U,
		0x3DCAB3EDU,
		0x42124715U,
		0x8A1EAE91U,
		0x9ECD792FU,
		0xBDEFBCD2U
	};
	vector<uint8_t> sbox{
		0xc4, 0xed, 0x83, 0xc9, 0x92, 0x98, 0xfe, 0x6b,
		0xff, 0xbe, 0x65, 0x5c, 0xe5, 0x2c, 0xb9, 0x20,
		0x89, 0x57, 0x16, 0xb3, 0x11, 0xf3, 0x98, 0x06,
		0x30, 0x79, 0xc0, 0x97, 0xa8, 0x1a, 0x5d, 0xd5,
		0x2e, 0x01, 0xda, 0x34, 0x73, 0xd5, 0x3b, 0xe8,
		0x4b, 0xc2, 0x77, 0x7e, 0xdc, 0x64, 0xac, 0xaf,
		0x6d, 0xa6, 0x02, 0xf1, 0x07, 0x4f, 0xe1, 0x4a,
		0xba, 0x30, 0x2f, 0x12, 0x56, 0x8b, 0x44, 0x8d
	};
	Key key(&keydata[0]);
	key.set_sbox(&sbox[0]);
	ImitContext imit(&key);
	// When
	imit.imit(&data[0], data.size());
	// Then
	UP_ASSERT_EQUAL(imit.result(), 2954209623);
}

UP_SUITE_END()
UP_SUITE_END()
<commit_msg>#291: more todo<commit_after>// Copyright (c) 2017 Andrey Valyaev
//
// This software may be modified and distributed under the terms
// of the MIT license.  See the LICENSE file for details.

#include <upp11.h>

using namespace std;

// @todo #291 ProceduralImitTest move to benchmark utility,
//  for comparsion with us. This is not a test.

UP_SUITE_BEGIN(gost89)
UP_SUITE_BEGIN(ProceduralImitTest)

class Key final {
public:
	explicit Key(const void *key)
		: sbox()
	{
		memcpy(key_, key, sizeof(key_));
		memset(mask_, 0, sizeof(mask_));
	}

	virtual void set_sbox(const void *box) {
		const uint8_t *sptr = static_cast<const uint8_t *>(box);
		expand_tab(sptr, 0, &sbox[0]);
		expand_tab(sptr, 1, &sbox[256]);
		expand_tab(sptr, 2, &sbox[512]);
		expand_tab(sptr, 3, &sbox[768]);
	}

private:
	friend class ImitContext;

	void expand_tab(const uint8_t sbox[64], size_t offset, uint8_t tab[256]) {
		for (size_t i = 0; i < 256; i++) {
			tab[i] = (sbox[(i / 16) * 4 + offset] & 0xf0)
				+ (sbox[(i % 16) * 4 + offset] & 0x0f);
		}
	}

	uint32_t key_[8];
	uint32_t mask_[8];
	array<uint8_t, 1024> sbox;
};

class ImitContext final {
public:
	explicit ImitContext(const Key *key)
		: key_(key), blocks(0)
	{
		memset(state, 0, sizeof(state));
	}

	void imit(const void *data, size_t len, int expand = 0)
	{
		if (len % 8 != 0 && !expand) {
			throw length_error("Imit::imit(): data length isn't "
					"multiple of block size");
		}

		const uint8_t *ptr = static_cast<const uint8_t *>(data);

		while (len >= 8) {
			for (int i = 0; i < 8; i++) {
				state[i] ^= ptr[i];
			}

			imit_block(state);
			blocks++;
			ptr += 8;
			len -= 8;
		}

		if (len != 0) {
			for (size_t i = 0; i < len; i++) {
				state[i] ^= ptr[i];
			}

			imit_block(state);
			blocks++;
		}
	}

	uint32_t result()
	{
		check_two_blocks();
		uint32_t result;
		memcpy(&result, &state[0], sizeof(result));
		return result;
	}

private:
	void check_two_blocks() {
		while (blocks < 2) {
			imit_block(state);
			blocks++;
		}
	}

	void cycle(uint32_t *half1, uint32_t *half2,
		 const uint32_t key, const uint32_t mask) const
	{
		uint32_t tmp1 = key + *half2 - mask;
		uint32_t tmp2 = key_->sbox[tmp1 & 0xff];
		tmp2 |= (key_->sbox[256 + ((tmp1 >> 8) & 0xff)]) << 8;
		tmp2 |= (key_->sbox[512 + ((tmp1 >> 16) & 0xff)]) << 16;
		tmp2 |= (key_->sbox[768 + ((tmp1 >> 24) & 0xff)]) << 24;
		tmp2 = (tmp2 << 11) | ((tmp2 >> 21) & 0x7ff);

		*half1 ^= tmp2;
	}

	void imit_block(void *block) const {
		uint32_t a = static_cast<uint32_t *>(block)[1];
		uint32_t b = static_cast<uint32_t *>(block)[0];
		const uint32_t *ekey = key_->key_;
		const uint32_t *emask = key_->mask_;

		cycle(&a, &b, ekey[0], emask[0]);
		cycle(&b, &a, ekey[1], emask[1]);
		cycle(&a, &b, ekey[2], emask[2]);
		cycle(&b, &a, ekey[3], emask[3]);
		cycle(&a, &b, ekey[4], emask[4]);
		cycle(&b, &a, ekey[5], emask[5]);
		cycle(&a, &b, ekey[6], emask[6]);
		cycle(&b, &a, ekey[7], emask[7]);

		cycle(&a, &b, ekey[0], emask[0]);
		cycle(&b, &a, ekey[1], emask[1]);
		cycle(&a, &b, ekey[2], emask[2]);
		cycle(&b, &a, ekey[3], emask[3]);
		cycle(&a, &b, ekey[4], emask[4]);
		cycle(&b, &a, ekey[5], emask[5]);
		cycle(&a, &b, ekey[6], emask[6]);
		cycle(&b, &a, ekey[7], emask[7]);

		static_cast<uint32_t *>(block)[1] = a;
		static_cast<uint32_t *>(block)[0] = b;
	}

	const Key *key_;
	uint8_t state[8];
	size_t blocks;
};

UP_TEST(Benchmark10M)
{
	// Given
	const vector<uint8_t> data(10000000U, 'A');
	vector<uint32_t> keydata = {
		0xE0F67504U,
		0xFAFB3850U,
		0x90C3C7D2U,
		0x3DCAB3EDU,
		0x42124715U,
		0x8A1EAE91U,
		0x9ECD792FU,
		0xBDEFBCD2U
	};
	vector<uint8_t> sbox{
		0xc4, 0xed, 0x83, 0xc9, 0x92, 0x98, 0xfe, 0x6b,
		0xff, 0xbe, 0x65, 0x5c, 0xe5, 0x2c, 0xb9, 0x20,
		0x89, 0x57, 0x16, 0xb3, 0x11, 0xf3, 0x98, 0x06,
		0x30, 0x79, 0xc0, 0x97, 0xa8, 0x1a, 0x5d, 0xd5,
		0x2e, 0x01, 0xda, 0x34, 0x73, 0xd5, 0x3b, 0xe8,
		0x4b, 0xc2, 0x77, 0x7e, 0xdc, 0x64, 0xac, 0xaf,
		0x6d, 0xa6, 0x02, 0xf1, 0x07, 0x4f, 0xe1, 0x4a,
		0xba, 0x30, 0x2f, 0x12, 0x56, 0x8b, 0x44, 0x8d
	};
	Key key(&keydata[0]);
	key.set_sbox(&sbox[0]);
	ImitContext imit(&key);
	// When
	imit.imit(&data[0], data.size());
	// Then
	UP_ASSERT_EQUAL(imit.result(), 2954209623);
}

UP_SUITE_END()
UP_SUITE_END()
<|endoftext|>


<commit_before><commit_msg>coverity#708279 Uninitialized pointer field<commit_after><|endoftext|>


<commit_before>// Copyright 2019 The TCMalloc Authors
//
// 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
//
//     https://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 <stddef.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

#include <algorithm>
#include <cstddef>
#include <new>

#include "benchmark/benchmark.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/memory/memory.h"
#include "tcmalloc/common.h"
#include "tcmalloc/guarded_page_allocator.h"
#include "tcmalloc/internal/bits.h"
#include "tcmalloc/internal/declarations.h"
#include "tcmalloc/malloc_extension.h"
#include "tcmalloc/static_vars.h"

namespace tcmalloc {
namespace {

class GuardedAllocAlignmentTest : public testing::Test {
 protected:
  GuardedAllocAlignmentTest() {
    profile_sampling_rate_ = MallocExtension::GetProfileSamplingRate();
    guarded_sample_rate_ = MallocExtension::GetGuardedSamplingRate();
    MallocExtension::SetProfileSamplingRate(1);     // Always do heapz samples.
    MallocExtension::SetGuardedSamplingRate(0);     // Guard every heapz sample.
    MallocExtension::ActivateGuardedSampling();

    // Eat up unsampled bytes remaining to flush the new sample rates.
    while (true) {
      void *p = ::operator new(kPageSize);
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(p)) {
        ::operator delete(p);
        break;
      }
      ::operator delete(p);
    }

    // Ensure subsequent allocations are guarded.
    void *p = ::operator new(1);
    CHECK_CONDITION(
        tcmalloc::Static::guardedpage_allocator()->PointerIsMine(p));
    ::operator delete(p);
  }

  ~GuardedAllocAlignmentTest() {
    MallocExtension::SetProfileSamplingRate(profile_sampling_rate_);
    MallocExtension::SetGuardedSamplingRate(guarded_sample_rate_);
  }

 private:
  int64_t profile_sampling_rate_;
  int32_t guarded_sample_rate_;
};

TEST_F(GuardedAllocAlignmentTest, Malloc) {
  for (size_t lg = 0; lg <= kPageShift; lg++) {
    size_t base_size = size_t{1} << lg;
    const size_t sizes[] = {base_size - 1, base_size, base_size + 1};
    for (size_t size : sizes) {
      void *p = malloc(size);
      // TCMalloc currently always aligns mallocs to alignof(std::max_align_t),
      // even for small sizes.  If this ever changes, we can reduce the expected
      // alignment here for sizes < alignof(std::max_align_t).
      EXPECT_EQ(reinterpret_cast<uintptr_t>(p) % alignof(std::max_align_t), 0);
      free(p);
    }
  }
}

TEST_F(GuardedAllocAlignmentTest, PosixMemalign) {
  for (size_t align = sizeof(void *); align <= kPageSize; align <<= 1) {
    void *p = nullptr;
    EXPECT_EQ(posix_memalign(&p, align, 1), 0);
    EXPECT_EQ(reinterpret_cast<uintptr_t>(p) % align, 0);
    benchmark::DoNotOptimize(p);
    free(p);
  }
}

TEST_F(GuardedAllocAlignmentTest, New) {
  for (size_t lg = 0; lg <= kPageShift; lg++) {
    size_t base_size = size_t{1} << lg;
    const size_t sizes[] = {base_size - 1, base_size, base_size + 1};
    for (size_t size : sizes) {
      void *p = ::operator new(size);

      // In the absence of a user-specified alignment, the required alignment
      // for operator new is never larger than the size rounded up to the next
      // power of 2.  GuardedPageAllocator uses this fact to minimize alignment
      // padding between the end of small allocations and their guard pages.
      int lg_size =
          std::max(tcmalloc::tcmalloc_internal::Bits::Log2Ceiling(size), 0);
      size_t expected_align = std::min(size_t{1} << lg_size, kAlignment);

      EXPECT_EQ(reinterpret_cast<uintptr_t>(p) % expected_align, 0);
      ::operator delete(p);
    }
  }
}

TEST_F(GuardedAllocAlignmentTest, AlignedNew) {
  for (size_t align = 1; align <= kPageSize; align <<= 1) {
    void *p = ::operator new(1, static_cast<std::align_val_t>(align));
    EXPECT_EQ(reinterpret_cast<uintptr_t>(p) % align, 0);
    ::operator delete(p);
  }
}

class TcMallocTest : public testing::Test {
 protected:
  TcMallocTest() {
    MallocExtension::SetGuardedSamplingRate(
        100 * MallocExtension::GetProfileSamplingRate());

    // Prevent SEGV handler from writing XML properties in death tests.
    unsetenv("XML_OUTPUT_FILE");
  }
};

TEST_F(TcMallocTest, UnderflowReadDetected) {
  auto RepeatUnderflowRead = []() {
    for (int i = 0; i < 1000000; i++) {
      auto buf = absl::make_unique<char[]>(kPageSize / 2);
      benchmark::DoNotOptimize(buf);
      // TCMalloc may crash without a GWP-ASan report if we underflow a regular
      // allocation.  Make sure we have a guarded allocation.
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(buf.get())) {
        volatile char sink = buf[-1];
        benchmark::DoNotOptimize(sink);
      }
    }
  };
  EXPECT_DEATH(RepeatUnderflowRead(),
               "Buffer underflow occurs in thread [0-9]+ at");
}

TEST_F(TcMallocTest, OverflowReadDetected) {
  auto RepeatOverflowRead = []() {
    for (int i = 0; i < 1000000; i++) {
      auto buf = absl::make_unique<char[]>(kPageSize / 2);
      benchmark::DoNotOptimize(buf);
      // TCMalloc may crash without a GWP-ASan report if we overflow a regular
      // allocation.  Make sure we have a guarded allocation.
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(buf.get())) {
        volatile char sink = buf[kPageSize / 2];
        benchmark::DoNotOptimize(sink);
      }
    }
  };
  EXPECT_DEATH(RepeatOverflowRead(),
               "Buffer overflow occurs in thread [0-9]+ at");
}

TEST_F(TcMallocTest, UseAfterFreeDetected) {
  auto RepeatUseAfterFree = []() {
    for (int i = 0; i < 1000000; i++) {
      char *sink_buf = new char[kPageSize];
      benchmark::DoNotOptimize(sink_buf);
      delete[] sink_buf;
      volatile char sink = sink_buf[0];
      benchmark::DoNotOptimize(sink);
    }
  };
  EXPECT_DEATH(RepeatUseAfterFree(),
               "Use-after-free occurs in thread [0-9]+ at");
}

// Double free triggers an ASSERT within TCMalloc in non-opt builds.  So only
// run this test for opt builds.
#ifdef NDEBUG
TEST_F(TcMallocTest, DoubleFreeDetected) {
  auto RepeatDoubleFree = []() {
    for (int i = 0; i < 1000000; i++) {
      void *buf = ::operator new(kPageSize);
      ::operator delete(buf);
      // TCMalloc often SEGVs on double free (without GWP-ASan report). Make
      // sure we have a guarded allocation before double-freeing.
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(buf)) {
        ::operator delete(buf);
      }
    }
  };
  EXPECT_DEATH(RepeatDoubleFree(), "Double free occurs in thread [0-9]+ at");
}
#endif

TEST_F(TcMallocTest, OverflowWriteDetectedAtFree) {
  auto RepeatOverflowWrite = []() {
    for (int i = 0; i < 1000000; i++) {
      // Make buffer smaller than kPageSize to test detection-at-free of write
      // overflows.
      auto sink_buf = absl::make_unique<char[]>(kPageSize - 1);
      benchmark::DoNotOptimize(sink_buf);
      sink_buf[kPageSize - 1] = '\0';
    }
  };
  EXPECT_DEATH(RepeatOverflowWrite(),
               "Buffer overflow \\(write\\) detected in thread [0-9]+ at free");
}

TEST_F(TcMallocTest, ReallocNoFalsePositive) {
  for (int i = 0; i < 1000000; i++) {
    auto sink_buf = reinterpret_cast<char *>(malloc(kPageSize - 1));
    benchmark::DoNotOptimize(sink_buf);
    sink_buf = reinterpret_cast<char *>(realloc(sink_buf, kPageSize));
    sink_buf[kPageSize - 1] = '\0';
    benchmark::DoNotOptimize(sink_buf);
    free(sink_buf);
  }
}

TEST_F(TcMallocTest, OffsetAndLength) {
  auto RepeatUseAfterFree = [](size_t buffer_len, off_t access_offset) {
    for (int i = 0; i < 1000000; i++) {
      void *buf = ::operator new(buffer_len);
      ::operator delete(buf);
      // TCMalloc may crash without a GWP-ASan report if we overflow a regular
      // allocation.  Make sure we have a guarded allocation.
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(buf)) {
        volatile char sink = static_cast<char *>(buf)[access_offset];
        benchmark::DoNotOptimize(sink);
      }
    }
  };
  EXPECT_DEATH(RepeatUseAfterFree(3999, -42),
               ">>> Access at offset -42 into buffer of length 3999");
  EXPECT_DEATH(RepeatUseAfterFree(6543, 1221),
               ">>> Access at offset 1221 into buffer of length 6543");
  EXPECT_DEATH(RepeatUseAfterFree(8192, 8484),
               ">>> Access at offset 8484 into buffer of length 8192");
}

// Ensure non-GWP-ASan segfaults also crash.
TEST_F(TcMallocTest, NonGwpAsanSegv) {
  int *volatile p = static_cast<int *>(
      mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
  EXPECT_DEATH((*p)++, "");
  munmap(p, kPageSize);
}

}  // namespace
}  // namespace tcmalloc
<commit_msg>Prevent overflow write from being optimized out.<commit_after>// Copyright 2019 The TCMalloc Authors
//
// 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
//
//     https://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 <stddef.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

#include <algorithm>
#include <cstddef>
#include <new>

#include "benchmark/benchmark.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/memory/memory.h"
#include "tcmalloc/common.h"
#include "tcmalloc/guarded_page_allocator.h"
#include "tcmalloc/internal/bits.h"
#include "tcmalloc/internal/declarations.h"
#include "tcmalloc/malloc_extension.h"
#include "tcmalloc/static_vars.h"

namespace tcmalloc {
namespace {

class GuardedAllocAlignmentTest : public testing::Test {
 protected:
  GuardedAllocAlignmentTest() {
    profile_sampling_rate_ = MallocExtension::GetProfileSamplingRate();
    guarded_sample_rate_ = MallocExtension::GetGuardedSamplingRate();
    MallocExtension::SetProfileSamplingRate(1);     // Always do heapz samples.
    MallocExtension::SetGuardedSamplingRate(0);     // Guard every heapz sample.
    MallocExtension::ActivateGuardedSampling();

    // Eat up unsampled bytes remaining to flush the new sample rates.
    while (true) {
      void *p = ::operator new(kPageSize);
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(p)) {
        ::operator delete(p);
        break;
      }
      ::operator delete(p);
    }

    // Ensure subsequent allocations are guarded.
    void *p = ::operator new(1);
    CHECK_CONDITION(
        tcmalloc::Static::guardedpage_allocator()->PointerIsMine(p));
    ::operator delete(p);
  }

  ~GuardedAllocAlignmentTest() {
    MallocExtension::SetProfileSamplingRate(profile_sampling_rate_);
    MallocExtension::SetGuardedSamplingRate(guarded_sample_rate_);
  }

 private:
  int64_t profile_sampling_rate_;
  int32_t guarded_sample_rate_;
};

TEST_F(GuardedAllocAlignmentTest, Malloc) {
  for (size_t lg = 0; lg <= kPageShift; lg++) {
    size_t base_size = size_t{1} << lg;
    const size_t sizes[] = {base_size - 1, base_size, base_size + 1};
    for (size_t size : sizes) {
      void *p = malloc(size);
      // TCMalloc currently always aligns mallocs to alignof(std::max_align_t),
      // even for small sizes.  If this ever changes, we can reduce the expected
      // alignment here for sizes < alignof(std::max_align_t).
      EXPECT_EQ(reinterpret_cast<uintptr_t>(p) % alignof(std::max_align_t), 0);
      free(p);
    }
  }
}

TEST_F(GuardedAllocAlignmentTest, PosixMemalign) {
  for (size_t align = sizeof(void *); align <= kPageSize; align <<= 1) {
    void *p = nullptr;
    EXPECT_EQ(posix_memalign(&p, align, 1), 0);
    EXPECT_EQ(reinterpret_cast<uintptr_t>(p) % align, 0);
    benchmark::DoNotOptimize(p);
    free(p);
  }
}

TEST_F(GuardedAllocAlignmentTest, New) {
  for (size_t lg = 0; lg <= kPageShift; lg++) {
    size_t base_size = size_t{1} << lg;
    const size_t sizes[] = {base_size - 1, base_size, base_size + 1};
    for (size_t size : sizes) {
      void *p = ::operator new(size);

      // In the absence of a user-specified alignment, the required alignment
      // for operator new is never larger than the size rounded up to the next
      // power of 2.  GuardedPageAllocator uses this fact to minimize alignment
      // padding between the end of small allocations and their guard pages.
      int lg_size =
          std::max(tcmalloc::tcmalloc_internal::Bits::Log2Ceiling(size), 0);
      size_t expected_align = std::min(size_t{1} << lg_size, kAlignment);

      EXPECT_EQ(reinterpret_cast<uintptr_t>(p) % expected_align, 0);
      ::operator delete(p);
    }
  }
}

TEST_F(GuardedAllocAlignmentTest, AlignedNew) {
  for (size_t align = 1; align <= kPageSize; align <<= 1) {
    void *p = ::operator new(1, static_cast<std::align_val_t>(align));
    EXPECT_EQ(reinterpret_cast<uintptr_t>(p) % align, 0);
    ::operator delete(p);
  }
}

class TcMallocTest : public testing::Test {
 protected:
  TcMallocTest() {
    MallocExtension::SetGuardedSamplingRate(
        100 * MallocExtension::GetProfileSamplingRate());

    // Prevent SEGV handler from writing XML properties in death tests.
    unsetenv("XML_OUTPUT_FILE");
  }
};

TEST_F(TcMallocTest, UnderflowReadDetected) {
  auto RepeatUnderflowRead = []() {
    for (int i = 0; i < 1000000; i++) {
      auto buf = absl::make_unique<char[]>(kPageSize / 2);
      benchmark::DoNotOptimize(buf);
      // TCMalloc may crash without a GWP-ASan report if we underflow a regular
      // allocation.  Make sure we have a guarded allocation.
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(buf.get())) {
        volatile char sink = buf[-1];
        benchmark::DoNotOptimize(sink);
      }
    }
  };
  EXPECT_DEATH(RepeatUnderflowRead(),
               "Buffer underflow occurs in thread [0-9]+ at");
}

TEST_F(TcMallocTest, OverflowReadDetected) {
  auto RepeatOverflowRead = []() {
    for (int i = 0; i < 1000000; i++) {
      auto buf = absl::make_unique<char[]>(kPageSize / 2);
      benchmark::DoNotOptimize(buf);
      // TCMalloc may crash without a GWP-ASan report if we overflow a regular
      // allocation.  Make sure we have a guarded allocation.
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(buf.get())) {
        volatile char sink = buf[kPageSize / 2];
        benchmark::DoNotOptimize(sink);
      }
    }
  };
  EXPECT_DEATH(RepeatOverflowRead(),
               "Buffer overflow occurs in thread [0-9]+ at");
}

TEST_F(TcMallocTest, UseAfterFreeDetected) {
  auto RepeatUseAfterFree = []() {
    for (int i = 0; i < 1000000; i++) {
      char *sink_buf = new char[kPageSize];
      benchmark::DoNotOptimize(sink_buf);
      delete[] sink_buf;
      volatile char sink = sink_buf[0];
      benchmark::DoNotOptimize(sink);
    }
  };
  EXPECT_DEATH(RepeatUseAfterFree(),
               "Use-after-free occurs in thread [0-9]+ at");
}

// Double free triggers an ASSERT within TCMalloc in non-opt builds.  So only
// run this test for opt builds.
#ifdef NDEBUG
TEST_F(TcMallocTest, DoubleFreeDetected) {
  auto RepeatDoubleFree = []() {
    for (int i = 0; i < 1000000; i++) {
      void *buf = ::operator new(kPageSize);
      ::operator delete(buf);
      // TCMalloc often SEGVs on double free (without GWP-ASan report). Make
      // sure we have a guarded allocation before double-freeing.
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(buf)) {
        ::operator delete(buf);
      }
    }
  };
  EXPECT_DEATH(RepeatDoubleFree(), "Double free occurs in thread [0-9]+ at");
}
#endif

TEST_F(TcMallocTest, OverflowWriteDetectedAtFree) {
  auto RepeatOverflowWrite = []() {
    for (int i = 0; i < 1000000; i++) {
      // Make buffer smaller than kPageSize to test detection-at-free of write
      // overflows.
      constexpr size_t kSize = kPageSize - 1;
      auto sink_buf = absl::make_unique<char[]>(kSize);
      benchmark::DoNotOptimize(sink_buf);
      sink_buf[kSize] = '\0';
      benchmark::DoNotOptimize(sink_buf[kSize]);
    }
  };
  EXPECT_DEATH(RepeatOverflowWrite(),
               "Buffer overflow \\(write\\) detected in thread [0-9]+ at free");
}

TEST_F(TcMallocTest, ReallocNoFalsePositive) {
  for (int i = 0; i < 1000000; i++) {
    auto sink_buf = reinterpret_cast<char *>(malloc(kPageSize - 1));
    benchmark::DoNotOptimize(sink_buf);
    sink_buf = reinterpret_cast<char *>(realloc(sink_buf, kPageSize));
    sink_buf[kPageSize - 1] = '\0';
    benchmark::DoNotOptimize(sink_buf);
    free(sink_buf);
  }
}

TEST_F(TcMallocTest, OffsetAndLength) {
  auto RepeatUseAfterFree = [](size_t buffer_len, off_t access_offset) {
    for (int i = 0; i < 1000000; i++) {
      void *buf = ::operator new(buffer_len);
      ::operator delete(buf);
      // TCMalloc may crash without a GWP-ASan report if we overflow a regular
      // allocation.  Make sure we have a guarded allocation.
      if (tcmalloc::Static::guardedpage_allocator()->PointerIsMine(buf)) {
        volatile char sink = static_cast<char *>(buf)[access_offset];
        benchmark::DoNotOptimize(sink);
      }
    }
  };
  EXPECT_DEATH(RepeatUseAfterFree(3999, -42),
               ">>> Access at offset -42 into buffer of length 3999");
  EXPECT_DEATH(RepeatUseAfterFree(6543, 1221),
               ">>> Access at offset 1221 into buffer of length 6543");
  EXPECT_DEATH(RepeatUseAfterFree(8192, 8484),
               ">>> Access at offset 8484 into buffer of length 8192");
}

// Ensure non-GWP-ASan segfaults also crash.
TEST_F(TcMallocTest, NonGwpAsanSegv) {
  int *volatile p = static_cast<int *>(
      mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
  EXPECT_DEATH((*p)++, "");
  munmap(p, kPageSize);
}

}  // namespace
}  // namespace tcmalloc
<|endoftext|>


<commit_before>#pragma once

#ifdef TBM_USE_MKL
# include "mkl/lanczos.hpp"
#else
# include "eigen3/lanczos.hpp"
#endif

#include "support/sparse.hpp"
#include "compute/linear_algebra.hpp"
#include <tuple>

namespace compute {

/**
 Use the Lanczos algorithm to find the min and max eigenvalues at given precision (%)
 @return (min, max, iteration_count)
*/
template<typename scalar_t, typename real_t = num::get_real_t<scalar_t>>
std::tuple<real_t, real_t, int>
    minmax_eigenvalues(const SparseMatrixX<scalar_t>& matrix, real_t precision_percent)
{
    auto precision = precision_percent / 100;
    const auto matrix_size = static_cast<int>(matrix.rows());

    // Starting right vector -> initial value is random, normalized
    VectorX<scalar_t> right = VectorX<scalar_t>::Random(matrix_size);
    right.normalize();
    // Initial values for right_previous and left are not important
    VectorX<scalar_t> right_previous{matrix_size};
    VectorX<scalar_t> left{matrix_size};

    // Alpha and beta are the diagonals of the tridiagonal matrix.
    // The final size is not known ahead of time, but it will be small.
    std::vector<real_t> alpha; alpha.reserve(100);
    std::vector<real_t> beta; beta.reserve(100);

    // Energy values from the previous iteration. Used to test convergence.
    // Initial values as far away from expected as possible.
    real_t previous_min = std::numeric_limits<real_t>::max();
    real_t previous_max = std::numeric_limits<real_t>::lowest();

    constexpr auto loop_limit = 1000;
    // This may iterate up to matrix_size, but since only the extreme eigenvalues are required it
    // will converge very quickly. More than loop_limit iterations would suggest something is wrong.
    for (int i = 0; i < loop_limit; ++i) {
        // PART 1: Calculate tridiagonal matrix elements a and b
        // =====================================================
        // left = h_matrix * right
        // matrix-vector multiplication (the most compute intensive part of each iteration)
        compute::matrix_vector_mul(matrix, right, left);

        // vector dot product (left*right) -> we just need the real part
        real_t a = std::real(compute::dot_product(left, right));
        // get b from the previous iteration (or 0 if this is the first iteration)
        real_t b = !beta.empty() ? beta.back() : 0;

        // left -= a*right + b*right_previous;
        compute::axpy(scalar_t(-a), right, left);
        compute::axpy(scalar_t(-b), right_previous, left);
        b = left.norm();

        // right_previous gets the old value of right
        right_previous.swap(right);
        // right moves on
        right = (1/b) * left;

        // add a and b to tridiagonal matrix
        alpha.push_back(a);
        beta.push_back(b);

        // PART 2: Check if the largest magnitude eigenvalues have converged
        // =================================================================
        auto eigenvalues = compute::tridiagonal_eigenvalues(eigen_cast<ArrayX>(alpha),
                                                            eigen_cast<ArrayX>(beta));

        real_t min = eigenvalues.minCoeff();
        real_t max = eigenvalues.maxCoeff();

        using std::abs;
        bool is_converged_min = abs((previous_min - min) / min) < precision;
        bool is_converged_max = abs((previous_max - max) / max) < precision;

        previous_min = min;
        previous_max = max;

        if (is_converged_min && is_converged_max)
            return std::make_tuple(min, max, i);
    };

    throw std::runtime_error{"Lanczos algorithm did not converge for the min/max eigenvalues."};
    return {};
}

} // namespace compute
<commit_msg>Fix occasional QR decomposition error caused by uninitialized variables<commit_after>#pragma once

#ifdef TBM_USE_MKL
# include "mkl/lanczos.hpp"
#else
# include "eigen3/lanczos.hpp"
#endif

#include "support/sparse.hpp"
#include "compute/linear_algebra.hpp"
#include <tuple>

namespace compute {

/**
 Use the Lanczos algorithm to find the min and max eigenvalues at given precision (%)
 @return (min, max, iteration_count)
*/
template<typename scalar_t, typename real_t = num::get_real_t<scalar_t>>
std::tuple<real_t, real_t, int>
    minmax_eigenvalues(const SparseMatrixX<scalar_t>& matrix, real_t precision_percent)
{
    auto precision = precision_percent / 100;
    const auto matrix_size = static_cast<int>(matrix.rows());

    VectorX<scalar_t> left = VectorX<scalar_t>::Zero(matrix_size);
    VectorX<scalar_t> right_previous = VectorX<scalar_t>::Zero(matrix_size);

    VectorX<scalar_t> right = VectorX<scalar_t>::Random(matrix_size);
    right.normalize();

    // Alpha and beta are the diagonals of the tridiagonal matrix.
    // The final size is not known ahead of time, but it will be small.
    std::vector<real_t> alpha; alpha.reserve(100);
    std::vector<real_t> beta; beta.reserve(100);

    // Energy values from the previous iteration. Used to test convergence.
    // Initial values as far away from expected as possible.
    real_t previous_min = std::numeric_limits<real_t>::max();
    real_t previous_max = std::numeric_limits<real_t>::lowest();

    constexpr auto loop_limit = 1000;
    // This may iterate up to matrix_size, but since only the extreme eigenvalues are required it
    // will converge very quickly. More than loop_limit iterations would suggest something is wrong.
    for (int i = 0; i < loop_limit; ++i) {
        // PART 1: Calculate tridiagonal matrix elements a and b
        // =====================================================
        // left = h_matrix * right
        // matrix-vector multiplication (the most compute intensive part of each iteration)
        compute::matrix_vector_mul(matrix, right, left);

        // vector dot product (left*right) -> we just need the real part
        real_t a = std::real(compute::dot_product(left, right));
        // get b from the previous iteration (or 0 if this is the first iteration)
        real_t b = !beta.empty() ? beta.back() : 0;

        // left -= a*right + b*right_previous;
        compute::axpy(scalar_t(-a), right, left);
        compute::axpy(scalar_t(-b), right_previous, left);
        b = left.norm();

        // right_previous gets the old value of right
        right_previous.swap(right);
        // right moves on
        right = (1/b) * left;

        // add a and b to tridiagonal matrix
        alpha.push_back(a);
        beta.push_back(b);

        // PART 2: Check if the largest magnitude eigenvalues have converged
        // =================================================================
        auto eigenvalues = compute::tridiagonal_eigenvalues(eigen_cast<ArrayX>(alpha),
                                                            eigen_cast<ArrayX>(beta));

        real_t min = eigenvalues.minCoeff();
        real_t max = eigenvalues.maxCoeff();

        using std::abs;
        bool is_converged_min = abs((previous_min - min) / min) < precision;
        bool is_converged_max = abs((previous_max - max) / max) < precision;

        previous_min = min;
        previous_max = max;

        if (is_converged_min && is_converged_max)
            return std::make_tuple(min, max, i);
    };

    throw std::runtime_error{"Lanczos algorithm did not converge for the min/max eigenvalues."};
    return {};
}

} // namespace compute
<|endoftext|>


<commit_before>#include "Halide.h"

using namespace Halide;

int main(int argc, char **argv) {
    Target target = get_jit_target_from_environment();
    Target target_fuzzed = target.with_feature(Target::FuzzFloatStores);

    const int size = 1000;

    {
        // Check some code that should be unaffected
        Func f;
        Var x;
        f(x) = (x - 42.5f) / 16.0f;
        f.vectorize(x, 8);

        // Pipelines that only use a few significant bits of the float should be unaffected
        Image<float> im_ref = f.realize(size, target);
        Image<float> im_fuzzed = f.realize(size, target_fuzzed);

        for (int i = 0; i < im_ref.width(); i++) {
            // Test for exact floating point equality, which is exactly
            // the sort of thing FuzzFloatStores is trying to discourage.
            if (im_ref(i) != im_fuzzed(i)) {
                printf("Expected exact floating point equality between %10.10g and %10.10g\n", im_ref(i), im_fuzzed(i));
                return -1;
            }
        }
    }

    {
        // Check some code that should be affected
        Func f;
        Var x;
        f(x) = sqrt(x - 42.3333333f) / 17.0f - tan(x);
        f.vectorize(x, 8);

        // Pipelines that use all the bits should be wrong about half the time
        Image<float> im_ref = f.realize(size, target);
        Image<float> im_fuzzed = f.realize(size, target_fuzzed);

        int differences = 0;
        for (int i = 0; i < im_ref.width(); i++) {
            // Test for exact floating point equality, which is exactly
            // the sort of thing FuzzFloatStores is trying to discourage.
            if (im_ref(i) != im_fuzzed(i)) {
                differences++;
            }
        }

        if (differences == 0) {
            printf("fuzzing float stores should have done something\n");
            return -1;
        }

        // It should change the output about half the time. Assuming
        // it's sum of 'size' coin flips...
        int mean = size/2;
        int variance = size/4;
        int five_sigma = 5 * ceil(sqrt(variance));
        if (differences < mean - five_sigma || differences > mean + five_sigma) {
            printf("There were %d differences with floating point fuzzing on. Expected more like %d +/- %d.\n",
                   differences, mean, five_sigma);
            return -1;
        }
    }

    printf("Success!\n");
    return 0;
}
<commit_msg>Comment tweak<commit_after>#include "Halide.h"

using namespace Halide;

int main(int argc, char **argv) {
    Target target = get_jit_target_from_environment();
    Target target_fuzzed = target.with_feature(Target::FuzzFloatStores);

    const int size = 1000;

    {
        // Check some code that should be unaffected
        Func f;
        Var x;
        f(x) = (x - 42.5f) / 16.0f;
        f.vectorize(x, 8);

        // Pipelines that only use a few significant bits of the float should be unaffected
        Image<float> im_ref = f.realize(size, target);
        Image<float> im_fuzzed = f.realize(size, target_fuzzed);

        for (int i = 0; i < im_ref.width(); i++) {
            // Test for exact floating point equality, which is exactly
            // the sort of thing FuzzFloatStores is trying to discourage.
            if (im_ref(i) != im_fuzzed(i)) {
                printf("Expected exact floating point equality between %10.10g and %10.10g\n", im_ref(i), im_fuzzed(i));
                return -1;
            }
        }
    }

    {
        // Check some code that should be affected
        Func f;
        Var x;
        f(x) = sqrt(x - 42.3333333f) / 17.0f - tan(x);
        f.vectorize(x, 8);

        Image<float> im_ref = f.realize(size, target);
        Image<float> im_fuzzed = f.realize(size, target_fuzzed);

        int differences = 0;
        for (int i = 0; i < im_ref.width(); i++) {
            // Pipelines that use all the bits should be wrong about half the time
            if (im_ref(i) != im_fuzzed(i)) {
                differences++;
            }
        }

        if (differences == 0) {
            printf("fuzzing float stores should have done something\n");
            return -1;
        }

        // It should change the output about half the time. Assuming
        // it's sum of 'size' coin flips...
        int mean = size/2;
        int variance = size/4;
        int five_sigma = 5 * ceil(sqrt(variance));
        if (differences < mean - five_sigma || differences > mean + five_sigma) {
            printf("There were %d differences with floating point fuzzing on. Expected more like %d +/- %d.\n",
                   differences, mean, five_sigma);
            return -1;
        }
    }

    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Priority.hh
 *
 * Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2000, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#ifndef _LOG4CPP_PRIORITY_HH
#define _LOG4CPP_PRIORITY_HH

#include <string>

/*
 * Optionally work around rudeness in windows.h on Win32.
 */
#ifdef ERROR
#ifdef LOG4CPP_FIX_ERROR_COLLISION

namespace log4cpp {
    static const int _tmpERRORValue = ERROR;
}

#undef ERROR
    static const int ERROR = log4cpp::_tmpERRORValue;
#define ERROR ERROR

#else
#error Naming collision for 'ERROR' detected. Please read the FAQ for a \
       workaround.
#endif // LOG4CPP_FIX_ERROR_COLLISION

#endif // ERROR

/*
 * Other Win32 rudeness in EDK.h
 */
#ifdef DEBUG

#ifdef LOG4CPP_FIX_ERROR_COLLISION

#undef DEBUG
#define DEBUG DEBUG
#endif

#else
#error Naming collision for 'DEBUG' detected. Please read the FAQ for a \
       workaround.
#endif // LOG4CPP_FIX_ERROR_COLLISION

#endif // DEBUG

namespace log4cpp {

    /**
     * The Priority class provides importance levels with which one
     * can categorize log messages.
     **/
    class Priority {
        public:

        /**
         * Predefined Levels of Priorities. These correspond to the
         * priority levels used by syslog(3).
         **/
        typedef enum {EMERG  = 0,
		      FATAL  = 0,
                      ALERT  = 100,
                      CRIT   = 200,
                      ERROR  = 300,
                      WARN   = 400,
                      NOTICE = 500,
                      INFO   = 600,
                      DEBUG  = 700,
                      NOTSET = 800
        } PriorityLevel;

        /**
         * The type of Priority Values
         **/
        typedef int Value;

        /**
         * Returns the name of the given priority value.
         * Currently, if the value is not one of the PriorityLevel values,
         * the method returns the name of the largest priority smaller
         * the given value.
         * @param priority the numeric value of the priority.
         * @returns a string representing the name of the priority.
         **/
        static const std::string& getPriorityName(int priority) throw();
    };
}

#endif // _LOG4CPP_PRIORITY_HH
<commit_msg>Fix workaround for #define DEBUG.<commit_after>/*
 * Priority.hh
 *
 * Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2000, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#ifndef _LOG4CPP_PRIORITY_HH
#define _LOG4CPP_PRIORITY_HH

#include <string>

/*
 * Optionally work around rudeness in windows.h on Win32.
 */
#ifdef ERROR
#ifdef LOG4CPP_FIX_ERROR_COLLISION

namespace log4cpp {
    static const int _tmpERRORValue = ERROR;
}

#undef ERROR
    static const int ERROR = log4cpp::_tmpERRORValue;
#define ERROR ERROR

#else  // LOG4CPP_FIX_ERROR_COLLISION
#error Naming collision for 'ERROR' detected. Please read the FAQ for a \
       workaround.
#endif // LOG4CPP_FIX_ERROR_COLLISION

#endif // ERROR

/*
 * Other Win32 rudeness in EDK.h
 */
#ifdef DEBUG

#ifdef LOG4CPP_FIX_ERROR_COLLISION

#undef DEBUG
#define DEBUG DEBUG

#else  // LOG4CPP_FIX_ERROR_COLLISION
#error Naming collision for 'DEBUG' detected. Please read the FAQ for a \
       workaround.
#endif // LOG4CPP_FIX_ERROR_COLLISION

#endif // DEBUG

namespace log4cpp {

    /**
     * The Priority class provides importance levels with which one
     * can categorize log messages.
     **/
    class Priority {
        public:

        /**
         * Predefined Levels of Priorities. These correspond to the
         * priority levels used by syslog(3).
         **/
        typedef enum {EMERG  = 0,
		      FATAL  = 0,
                      ALERT  = 100,
                      CRIT   = 200,
                      ERROR  = 300,
                      WARN   = 400,
                      NOTICE = 500,
                      INFO   = 600,
                      DEBUG  = 700,
                      NOTSET = 800
        } PriorityLevel;

        /**
         * The type of Priority Values
         **/
        typedef int Value;

        /**
         * Returns the name of the given priority value.
         * Currently, if the value is not one of the PriorityLevel values,
         * the method returns the name of the largest priority smaller
         * the given value.
         * @param priority the numeric value of the priority.
         * @returns a string representing the name of the priority.
         **/
        static const std::string& getPriorityName(int priority) throw();
    };
}

#endif // _LOG4CPP_PRIORITY_HH
<|endoftext|>


<commit_before>#pragma once

#include <array>
#include <vector>

#include "zmsg_cmm.hpp"

namespace zmsg {

/**
 * \brief typedefs
 */
typedef signed char CHAR;
typedef unsigned char UCHAR;

typedef signed short SHORT;
typedef unsigned short USHORT;

typedef int8_t INT8;
typedef uint8_t UINT8;
typedef int16_t INT16;
typedef uint16_t UINT16;
typedef int32_t INT32;
typedef uint32_t UINT32;

typedef signed long LONG;
typedef unsigned long ULONG;

typedef float FLOAT;

typedef double DOUBLE;

typedef ULONG BOOL;

typedef void VOID;

} /* namespace zmsg */

/**
 * \brief img fiber defect description
 */
typedef uint32_t ifd_t;

static constexpr ifd_t ifd_spot = 0x1;
static constexpr ifd_t ifd_break = 0x2;
static constexpr ifd_t ifd_bottom_sag = 0x4;
static constexpr ifd_t ifd_bottom_crest = 0x8;
static constexpr ifd_t ifd_bottom_corner = 0x10;
static constexpr ifd_t ifd_top_sag = 0x20;
static constexpr ifd_t ifd_top_crest = 0x40;
static constexpr ifd_t ifd_top_corner = 0x80;
static constexpr ifd_t ifd_end_crude = 0x100;
static constexpr ifd_t ifd_horizontal_angle = 0x200;
static constexpr ifd_t ifd_vertical_angle = 0x400;

static constexpr ifd_t ifd_cant_identify = 0x80000000;

typedef struct ifd_line final {
	ifd_t core;
	ifd_t wrap;

	double h_angle;
	double v_angle;

	ifd_line()
	: core(0)
	, wrap(0)
	, h_angle(0)
	, v_angle(0)
	{
	}

	operator bool() const
	{
		return (core || wrap);
	}

	bool check(ifd_t msk) const
	{
		return ((core & msk)
			|| (wrap & msk));
	}
public:
	ZMSG_PU(core, wrap, h_angle, v_angle)
} ifd_line_t;

typedef struct img_defects final {
	ifd_line_t yzl;
	ifd_line_t yzr;
	ifd_line_t xzl;
	ifd_line_t xzr;

	operator bool() const
	{
		return (yzl || yzr || xzl || xzr);
	}

	bool check(ifd_t msk) const
	{
		return (yzl.check(msk)
			|| yzr.check(msk)
			|| xzl.check(msk)
			|| xzr.check(msk));
	}
public:
	ZMSG_PU(yzl, yzr, xzl, xzr)
} img_defects_t;

/**
 * \brief service fs state
 */
enum class svc_fs_state_t : uint16_t {
	fs_reseting,
	fs_idle,
	fs_ready,
	fs_clring,
	fs_calibrating,
};

/**
 * \brief service heat state
 */
enum class svc_heat_state_t : uint16_t {
	heat_ready,
	heat_ascending,
	heat_stabling,
	heat_descending,
};

/**
 * \brief motor id
 */
enum motorId_t : uint8_t {
	LZ = 0,	// left z
	RZ,	// right z
	X,	// x
	Y,	// y

	NUM,	// total number
};

/**
 * \brief fusion splice display mode
 */
enum class fs_display_mode_t : uint8_t {
	X = 0x0,	/// only x
	Y,		/// only y
	TB,		/// top <-> bottom
	LR,		/// left <-> right
	NO,		/// no

	max,		/// number
};

/**
 * \brief fusion splice related error code
 */
enum class fs_err_t : uint8_t {
	success,
	cover_openned,
	no_fiber,
	fiber_defect,
	fiber_cross_over,
};

/**
 * \brief heat related error code
 */
enum class heat_err_t : uint8_t {
	success,
};

/**
 * \brief led id
 */
enum ledId_t : uint8_t {
	CMOS_X = 0x0,
	CMOS_Y,

	LED_NUM,
};

/**
 * \brief discharge_data_t, used for discharge revising
 */
typedef struct {
	struct {
		uint16_t x;
		double   y;
	public:
		ZMSG_PU(x, y)
	} p[2];

	bool empty() const
	{
		return (p[0].x == p[1].x);
	}
public:
	ZMSG_PU(p)
} discharge_data_t;
<commit_msg>zmsg: add missed fs_state<commit_after>#pragma once

#include <array>
#include <vector>

#include "zmsg_cmm.hpp"

namespace zmsg {

/**
 * \brief typedefs
 */
typedef signed char CHAR;
typedef unsigned char UCHAR;

typedef signed short SHORT;
typedef unsigned short USHORT;

typedef int8_t INT8;
typedef uint8_t UINT8;
typedef int16_t INT16;
typedef uint16_t UINT16;
typedef int32_t INT32;
typedef uint32_t UINT32;

typedef signed long LONG;
typedef unsigned long ULONG;

typedef float FLOAT;

typedef double DOUBLE;

typedef ULONG BOOL;

typedef void VOID;

} /* namespace zmsg */

/**
 * \brief img fiber defect description
 */
typedef uint32_t ifd_t;

static constexpr ifd_t ifd_spot = 0x1;
static constexpr ifd_t ifd_break = 0x2;
static constexpr ifd_t ifd_bottom_sag = 0x4;
static constexpr ifd_t ifd_bottom_crest = 0x8;
static constexpr ifd_t ifd_bottom_corner = 0x10;
static constexpr ifd_t ifd_top_sag = 0x20;
static constexpr ifd_t ifd_top_crest = 0x40;
static constexpr ifd_t ifd_top_corner = 0x80;
static constexpr ifd_t ifd_end_crude = 0x100;
static constexpr ifd_t ifd_horizontal_angle = 0x200;
static constexpr ifd_t ifd_vertical_angle = 0x400;

static constexpr ifd_t ifd_cant_identify = 0x80000000;

typedef struct ifd_line final {
	ifd_t core;
	ifd_t wrap;

	double h_angle;
	double v_angle;

	ifd_line()
	: core(0)
	, wrap(0)
	, h_angle(0)
	, v_angle(0)
	{
	}

	operator bool() const
	{
		return (core || wrap);
	}

	bool check(ifd_t msk) const
	{
		return ((core & msk)
			|| (wrap & msk));
	}
public:
	ZMSG_PU(core, wrap, h_angle, v_angle)
} ifd_line_t;

typedef struct img_defects final {
	ifd_line_t yzl;
	ifd_line_t yzr;
	ifd_line_t xzl;
	ifd_line_t xzr;

	operator bool() const
	{
		return (yzl || yzr || xzl || xzr);
	}

	bool check(ifd_t msk) const
	{
		return (yzl.check(msk)
			|| yzr.check(msk)
			|| xzl.check(msk)
			|| xzr.check(msk));
	}
public:
	ZMSG_PU(yzl, yzr, xzl, xzr)
} img_defects_t;

/**
 * \brief service fs state
 * \note all states mean enter this state.
 */
enum class svc_fs_state_t : uint16_t {
	fs_reseting,
	fs_idle,
	fs_ready,

	fs_entering,
	fs_push1,
	fs_calibrating,
	fs_clring,
	fs_defect_detecting,
	fs_push2,
	fs_pause1,
	fs_precise_calibrating,
	fs_pause2,
	fs_pre_splice,
	fs_discharge1,
	fs_discharge2,
	fs_discharge_manual,
	fs_loss_estimating,
	fs_tension_testing,
};

/**
 * \brief service heat state
 */
enum class svc_heat_state_t : uint16_t {
	heat_ready,
	heat_ascending,
	heat_stabling,
	heat_descending,
};

/**
 * \brief motor id
 */
enum motorId_t : uint8_t {
	LZ = 0,	// left z
	RZ,	// right z
	X,	// x
	Y,	// y

	NUM,	// total number
};

/**
 * \brief fusion splice display mode
 */
enum class fs_display_mode_t : uint8_t {
	X = 0x0,	/// only x
	Y,		/// only y
	TB,		/// top <-> bottom
	LR,		/// left <-> right
	NO,		/// no

	max,		/// number
};

/**
 * \brief fusion splice related error code
 */
enum class fs_err_t : uint8_t {
	success,
	cover_openned,
	no_fiber,
	fiber_defect,
	fiber_cross_over,
};

/**
 * \brief heat related error code
 */
enum class heat_err_t : uint8_t {
	success,
};

/**
 * \brief led id
 */
enum ledId_t : uint8_t {
	CMOS_X = 0x0,
	CMOS_Y,

	LED_NUM,
};

/**
 * \brief discharge_data_t, used for discharge revising
 */
typedef struct {
	struct {
		uint16_t x;
		double   y;
	public:
		ZMSG_PU(x, y)
	} p[2];

	bool empty() const
	{
		return (p[0].x == p[1].x);
	}
public:
	ZMSG_PU(p)
} discharge_data_t;
<|endoftext|>