<commit_before>/*
 * Copyright (c) 2017-2018 Tuukka Norri
 * This code is licensed under MIT license (see LICENSE for details).
 */

#include <boost/format.hpp>
#include <boost/io/ios_state.hpp>
#include <vcf2multialign/generate_sequences_context.hh>

namespace lb = libbio;

namespace vcf2multialign {

	void generate_sequences_context::update_haplotypes(char const *out_reference_fname)
	{
		m_haplotypes.clear();

		size_t i(0);
		while (m_sample_names_it != m_sample_names_end)
		{
			auto const &sample_name(m_sample_names_it->first);
			auto const sample_no(m_sample_names_it->second);
			auto const current_ploidy(m_ploidy.find(sample_no)->second);

			// Since file_ostream is not movable, check first if the vector has already been created.
			// If not, create it with the exact size to avoid resizing and thus moving later.
			auto it(m_haplotypes.find(sample_no));
			if (m_haplotypes.end() == it)
			{
				it = m_haplotypes.emplace(
					std::piecewise_construct,
					std::forward_as_tuple(sample_no),
					std::forward_as_tuple(current_ploidy)
				).first;
			}

			auto &haplotype_vec(it->second);

			for (size_t i(1); i <= current_ploidy; ++i)
			{
				auto const fname(boost::str(boost::format("%s-%u") % sample_name % i));
				lb::open_file_for_writing(fname.c_str(), haplotype_vec[i - 1].output_stream, m_should_overwrite_files);
			}

			++m_sample_names_it;
			++i;

			if (i == m_chunk_size)
				break;
		}

		// Check if reference output was requested.
		if (out_reference_fname)
		{
			lb::always_assert(
				m_haplotypes.cend() == m_haplotypes.find(REF_SAMPLE_NUMBER),
				"REF_SAMPLE_NUMBER already in use"
			);

			auto it(m_haplotypes.emplace(
				std::piecewise_construct,
				std::forward_as_tuple(0),
				std::forward_as_tuple(1)
			).first);

			auto &haplotype_vec(it->second);
			lb::open_file_for_writing(out_reference_fname, haplotype_vec[0].output_stream, m_should_overwrite_files);
		}
	}

	// Handle m_chunk_size samples.
	void generate_sequences_context::generate_sequences(char const *out_reference_fname)
	{
		// Open files for the samples. If no files were opened, exit.
		update_haplotypes(out_reference_fname);
		if (0 == m_haplotypes.size())
			finish();

		++m_current_round;
		std::cerr << "Round " << m_current_round << '/' << m_total_rounds << std::endl;
		m_round_start_time = std::chrono::system_clock::now();
		auto const start_time(std::chrono::system_clock::to_time_t(m_round_start_time));
		std::cerr << "Starting on " << std::ctime(&start_time) << std::flush;
		m_variant_handler.process_variants(m_haplotypes);
	}

	void generate_sequences_context::finish_round()
	{
		// Save the stream state.
		boost::io::ios_flags_saver ifs(std::cerr);

		// Change FP notation.
		std::cerr << std::fixed;

		auto const end_time(std::chrono::system_clock::now());
		std::chrono::duration <double> elapsed_seconds(end_time - m_round_start_time);
		std::cerr << "Finished in " << (elapsed_seconds.count() / 60.0) << " minutes." << std::endl;
	}

	void generate_sequences_context::variant_handler_did_finish(variant_handler &handler)
	{
		finish_round();
		generate_sequences();
	}

	void generate_sequences_context::load_and_generate(
		char const *reference_fname,
		char const *variants_fname,
		char const *out_reference_fname,
		char const *report_fname,
		sv_handling const sv_handling_method,
		bool const should_check_ref
	)
	{
		// Open the files.
		std::cerr << "Opening files…" << std::endl;
		open_files(reference_fname, variants_fname, report_fname);

		{
			auto const &sample_names(m_vcf_reader.sample_names());
			m_sample_names_it = sample_names.cbegin();
			m_sample_names_end = sample_names.cend();

			auto const sample_count(sample_names.size());
			m_total_rounds = std::ceil(1.0 * sample_count / m_chunk_size);
		}

		generate_context_base::load_and_generate(
			sv_handling_method,
			should_check_ref
		);

		// Replace the placeholder variant_handler.
		{
			variant_handler temp(
				m_main_queue,
				m_parsing_queue,
				m_vcf_reader,
				m_reference,
				sv_handling_method,
				m_skipped_variants,
				m_null_allele_seq,
				m_error_logger,
				*this
			);

			m_variant_handler = std::move(temp);
			m_variant_handler.get_variant_buffer().set_delegate(m_variant_handler);
		}

		std::cerr << "Generating haplotype sequences…" << std::endl;
		m_start_time = std::chrono::system_clock::now();
		generate_sequences(out_reference_fname);
	}
}
<commit_msg>Use a constant instead of a magic number<commit_after>/*
 * Copyright (c) 2017-2018 Tuukka Norri
 * This code is licensed under MIT license (see LICENSE for details).
 */

#include <boost/format.hpp>
#include <boost/io/ios_state.hpp>
#include <vcf2multialign/generate_sequences_context.hh>

namespace lb = libbio;

namespace vcf2multialign {

	void generate_sequences_context::update_haplotypes(char const *out_reference_fname)
	{
		m_haplotypes.clear();

		size_t i(0);
		while (m_sample_names_it != m_sample_names_end)
		{
			auto const &sample_name(m_sample_names_it->first);
			auto const sample_no(m_sample_names_it->second);
			auto const current_ploidy(m_ploidy.find(sample_no)->second);

			// Since file_ostream is not movable, check first if the vector has already been created.
			// If not, create it with the exact size to avoid resizing and thus moving later.
			auto it(m_haplotypes.find(sample_no));
			if (m_haplotypes.end() == it)
			{
				it = m_haplotypes.emplace(
					std::piecewise_construct,
					std::forward_as_tuple(sample_no),
					std::forward_as_tuple(current_ploidy)
				).first;
			}

			auto &haplotype_vec(it->second);

			for (size_t i(1); i <= current_ploidy; ++i)
			{
				auto const fname(boost::str(boost::format("%s-%u") % sample_name % i));
				lb::open_file_for_writing(fname.c_str(), haplotype_vec[i - 1].output_stream, m_should_overwrite_files);
			}

			++m_sample_names_it;
			++i;

			if (i == m_chunk_size)
				break;
		}

		// Check if reference output was requested.
		if (out_reference_fname)
		{
			lb::always_assert(
				m_haplotypes.cend() == m_haplotypes.find(REF_SAMPLE_NUMBER),
				"REF_SAMPLE_NUMBER already in use"
			);

			auto it(m_haplotypes.emplace(
				std::piecewise_construct,
				std::forward_as_tuple(REF_SAMPLE_NUMBER),
				std::forward_as_tuple(1)
			).first);

			auto &haplotype_vec(it->second);
			lb::open_file_for_writing(out_reference_fname, haplotype_vec[0].output_stream, m_should_overwrite_files);
		}
	}

	// Handle m_chunk_size samples.
	void generate_sequences_context::generate_sequences(char const *out_reference_fname)
	{
		// Open files for the samples. If no files were opened, exit.
		update_haplotypes(out_reference_fname);
		if (0 == m_haplotypes.size())
			finish();

		++m_current_round;
		std::cerr << "Round " << m_current_round << '/' << m_total_rounds << std::endl;
		m_round_start_time = std::chrono::system_clock::now();
		auto const start_time(std::chrono::system_clock::to_time_t(m_round_start_time));
		std::cerr << "Starting on " << std::ctime(&start_time) << std::flush;
		m_variant_handler.process_variants(m_haplotypes);
	}

	void generate_sequences_context::finish_round()
	{
		// Save the stream state.
		boost::io::ios_flags_saver ifs(std::cerr);

		// Change FP notation.
		std::cerr << std::fixed;

		auto const end_time(std::chrono::system_clock::now());
		std::chrono::duration <double> elapsed_seconds(end_time - m_round_start_time);
		std::cerr << "Finished in " << (elapsed_seconds.count() / 60.0) << " minutes." << std::endl;
	}

	void generate_sequences_context::variant_handler_did_finish(variant_handler &handler)
	{
		finish_round();
		generate_sequences();
	}

	void generate_sequences_context::load_and_generate(
		char const *reference_fname,
		char const *variants_fname,
		char const *out_reference_fname,
		char const *report_fname,
		sv_handling const sv_handling_method,
		bool const should_check_ref
	)
	{
		// Open the files.
		std::cerr << "Opening files…" << std::endl;
		open_files(reference_fname, variants_fname, report_fname);

		{
			auto const &sample_names(m_vcf_reader.sample_names());
			m_sample_names_it = sample_names.cbegin();
			m_sample_names_end = sample_names.cend();

			auto const sample_count(sample_names.size());
			m_total_rounds = std::ceil(1.0 * sample_count / m_chunk_size);
		}

		generate_context_base::load_and_generate(
			sv_handling_method,
			should_check_ref
		);

		// Replace the placeholder variant_handler.
		{
			variant_handler temp(
				m_main_queue,
				m_parsing_queue,
				m_vcf_reader,
				m_reference,
				sv_handling_method,
				m_skipped_variants,
				m_null_allele_seq,
				m_error_logger,
				*this
			);

			m_variant_handler = std::move(temp);
			m_variant_handler.get_variant_buffer().set_delegate(m_variant_handler);
		}

		std::cerr << "Generating haplotype sequences…" << std::endl;
		m_start_time = std::chrono::system_clock::now();
		generate_sequences(out_reference_fname);
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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.
 */

/**
 * \file ir_import_prototypes.cpp
 * Import function prototypes from one IR tree into another.
 *
 * \author Ian Romanick
 */
#include <cstdio>
#include "ir.h"
#include "glsl_symbol_table.h"

/**
 * Visitor used to import function prototypes
 *
 * Normally the \c clone method of either \c ir_function or
 * \c ir_function_signature could be used.  However, we don't want a complete
 * clone of the \c ir_function_signature.  We want everything \b except the
 * body of the function.
 */
class import_prototype_visitor : public ir_hierarchical_visitor {
public:
   /**
    */
   import_prototype_visitor(exec_list *list, glsl_symbol_table *symbols,
			    void *mem_ctx)
   {
      this->mem_ctx = mem_ctx;
      this->list = list;
      this->symbols = symbols;
      this->function = NULL;
   }

   virtual ir_visitor_status visit_enter(ir_function *ir)
   {
      assert(this->function == NULL);

      this->function = this->symbols->get_function(ir->name);
      if (!this->function) {
	 this->function = new(this->mem_ctx) ir_function(ir->name);

	 list->push_tail(this->function);

	 /* Add the new function to the symbol table.
	  */
	 this->symbols->add_function(this->function->name, this->function);
      }
      return visit_continue;
   }

   virtual ir_visitor_status visit_leave(ir_function *ir)
   {
      (void) ir;
      assert(this->function != NULL);

      this->function = NULL;
      return visit_continue;
   }

   ir_visitor_status visit_enter(ir_function_signature *ir)
   {
      assert(this->function != NULL);

      ir_function_signature *copy =
	 new(mem_ctx) ir_function_signature(ir->return_type);

      copy->is_defined = false;
      copy->is_built_in = ir->is_built_in;

      /* Clone the parameter list, but NOT the body.
       */
      foreach_list_const(node, &ir->parameters) {
	 const ir_variable *const param = (const ir_variable *) node;

	 assert(const_cast<ir_variable *>(param)->as_variable() != NULL);

	 ir_variable *const param_copy = param->clone(NULL);
	 copy->parameters.push_tail(param_copy);
      }

      this->function->add_signature(copy);

      /* Do not process child nodes of the ir_function_signature.  There can
       * never be any nodes inside the ir_function_signature that we care
       * about.  Instead continue with the next sibling.
       */
      return visit_continue_with_parent;
   }

private:
   exec_list *list;
   ir_function *function;
   glsl_symbol_table *symbols;
   void *mem_ctx;
};

/**
 * Import function prototypes from one IR tree into another
 *
 * \param source   Source instruction stream containing functions whose
 *                 prototypes are to be imported
 * \param dest     Destination instruction stream where new \c ir_function and
 *                 \c ir_function_signature nodes will be stored
 * \param symbols  Symbol table where new functions will be stored
 * \param mem_ctx  talloc memory context used for new allocations
 */
void
import_prototypes(const exec_list *source, exec_list *dest,
		  glsl_symbol_table *symbols, void *mem_ctx)
{
   import_prototype_visitor v(dest, symbols, mem_ctx);

   /* Making source be const is just extra documentation.
    */
   v.run(const_cast<exec_list *>(source));
}
<commit_msg>import_prototypes: do not put all cloned params into global builtin pool<commit_after>/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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.
 */

/**
 * \file ir_import_prototypes.cpp
 * Import function prototypes from one IR tree into another.
 *
 * \author Ian Romanick
 */
#include <cstdio>
#include "ir.h"
#include "glsl_symbol_table.h"

/**
 * Visitor used to import function prototypes
 *
 * Normally the \c clone method of either \c ir_function or
 * \c ir_function_signature could be used.  However, we don't want a complete
 * clone of the \c ir_function_signature.  We want everything \b except the
 * body of the function.
 */
class import_prototype_visitor : public ir_hierarchical_visitor {
public:
   /**
    */
   import_prototype_visitor(exec_list *list, glsl_symbol_table *symbols,
			    void *mem_ctx)
   {
      this->mem_ctx = mem_ctx;
      this->list = list;
      this->symbols = symbols;
      this->function = NULL;
   }

   virtual ir_visitor_status visit_enter(ir_function *ir)
   {
      assert(this->function == NULL);

      this->function = this->symbols->get_function(ir->name);
      if (!this->function) {
	 this->function = new(this->mem_ctx) ir_function(ir->name);

	 list->push_tail(this->function);

	 /* Add the new function to the symbol table.
	  */
	 this->symbols->add_function(this->function->name, this->function);
      }
      return visit_continue;
   }

   virtual ir_visitor_status visit_leave(ir_function *ir)
   {
      (void) ir;
      assert(this->function != NULL);

      this->function = NULL;
      return visit_continue;
   }

   ir_visitor_status visit_enter(ir_function_signature *ir)
   {
      assert(this->function != NULL);

      ir_function_signature *copy =
	 new(mem_ctx) ir_function_signature(ir->return_type);

      copy->is_defined = false;
      copy->is_built_in = ir->is_built_in;

      /* Clone the parameter list, but NOT the body.
       */
      foreach_list_const(node, &ir->parameters) {
	 const ir_variable *const param = (const ir_variable *) node;

	 assert(const_cast<ir_variable *>(param)->as_variable() != NULL);

	 ir_variable *const param_copy = param->clone(NULL);
	 talloc_steal(copy, param_copy);
	 copy->parameters.push_tail(param_copy);
      }

      this->function->add_signature(copy);

      /* Do not process child nodes of the ir_function_signature.  There can
       * never be any nodes inside the ir_function_signature that we care
       * about.  Instead continue with the next sibling.
       */
      return visit_continue_with_parent;
   }

private:
   exec_list *list;
   ir_function *function;
   glsl_symbol_table *symbols;
   void *mem_ctx;
};

/**
 * Import function prototypes from one IR tree into another
 *
 * \param source   Source instruction stream containing functions whose
 *                 prototypes are to be imported
 * \param dest     Destination instruction stream where new \c ir_function and
 *                 \c ir_function_signature nodes will be stored
 * \param symbols  Symbol table where new functions will be stored
 * \param mem_ctx  talloc memory context used for new allocations
 */
void
import_prototypes(const exec_list *source, exec_list *dest,
		  glsl_symbol_table *symbols, void *mem_ctx)
{
   import_prototype_visitor v(dest, symbols, mem_ctx);

   /* Making source be const is just extra documentation.
    */
   v.run(const_cast<exec_list *>(source));
}
<|endoftext|>


<commit_before>#include <sched.h>
#include <linux/unistd.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>

#include "core_manager.h"
#include "core.h"
#include "network.h"
#include "ocache.h"
#include "config.h"
#include "packetize.h"
#include "message_types.h"

#include "log.h"
#define LOG_DEFAULT_RANK -1
#define LOG_DEFAULT_MODULE CORE_MANAGER

using namespace std;

CoreManager::CoreManager()
      :
      tid_to_core_map(3*Config::getSingleton()->getNumLocalCores()),
      tid_to_core_index_map(3*Config::getSingleton()->getNumLocalCores()),
      simthread_tid_to_core_map(3*Config::getSingleton()->getNumLocalCores())
{
   LOG_PRINT("Starting CoreManager Constructor.");

   m_maps_lock = Lock::create();

   UInt32 num_local_cores = Config::getSingleton()->getNumLocalCores();

   tid_map = new UInt32 [num_local_cores];
   core_to_simthread_tid_map = new UInt32 [num_local_cores];

   UInt32 proc_id = Config::getSingleton()->getCurrentProcessNum();
   const Config::CoreList &local_cores = Config::getSingleton()->getCoreListForProcess(proc_id);

   for (UInt32 i = 0; i < num_local_cores; i++)
   {
      tid_map[i] = UINT_MAX;
      core_to_simthread_tid_map[i] = UINT_MAX;
      m_cores.push_back(new Core(local_cores[i]));
   }

   LOG_PRINT("Finished CoreManager Constructor.");
}

CoreManager::~CoreManager()
{
   for (std::vector<Core *>::iterator i = m_cores.begin(); i != m_cores.end(); i++)
      delete *i;

   delete [] core_to_simthread_tid_map;
   delete [] tid_map;

   delete m_maps_lock;
}

void CoreManager::initializeCommId(SInt32 comm_id)
{
   UInt32 tid = getCurrentTID();
   pair<bool, UINT64> e = tid_to_core_map.find(tid);

   LOG_ASSERT_ERROR(e.first, "*ERROR* initializeCommId: Called without binding thread to a core.");
   UInt32 core_id = e.second;

   UnstructuredBuffer send_buff;
   send_buff << (SInt32)LCP_MESSAGE_COMMID_UPDATE << comm_id << core_id;

   LOG_PRINT("Initializing comm_id: %d to core_id: %d", comm_id, core_id);

   // Broadcast this update to other processes
   Transport::Node *global_node = Transport::getSingleton()->getGlobalNode();
   UInt32 num_procs = Config::getSingleton()->getProcessCount();

   for (UInt32 i = 0; i < num_procs; i++)
   {
      global_node->globalSend(i,
                              send_buff.getBuffer(),
                              send_buff.size());
   }
}

void CoreManager::initializeThread()
{
   ScopedLock scoped_maps_lock(*m_maps_lock);
   UInt32 tid = getCurrentTID();
   pair<bool, UInt64> e = tid_to_core_map.find(tid);

   LOG_ASSERT_WARNING(e.first == false, "*WARNING* Thread: %d already mapped to core: %d", tid, e.second);

   for (UInt32 i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
   {
      if (tid_map[i] == UINT_MAX)
      {
         UInt32 core_id = Config::getSingleton()->getCoreListForProcess(Config::getSingleton()->getCurrentProcessNum())[i];
         tid_map[i] = tid;
         tid_to_core_index_map.insert(tid, i);
         tid_to_core_map.insert(tid, core_id);
         LOG_PRINT("Initialize thread : index %d mapped to: thread %d, core_id: %d", i, tid_map[i], core_id);
         return;
      }
      else
      {
         // LOG_PRINT("%d/%d already mapped to: %d", i, Config::getSingleton()->getNumLocalCores(), tid_map[i]);
      }
   }

   LOG_PRINT("*ERROR* initializeThread - No free cores out of %d total.", Config::getSingleton()->getNumLocalCores());
   LOG_NOTIFY_ERROR();
}

void CoreManager::initializeThread(SInt32 core_id)
{
   ScopedLock scoped_maps_lock(*m_maps_lock);
   UInt32 tid = getCurrentTID();
   pair<bool, UInt64> e = tid_to_core_map.find(tid);

   LOG_ASSERT_ERROR(e.first == false, "Tried to initialize core %d twice.", core_id);

   for (unsigned int i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
   {
      SInt32 local_core_id = Config::getSingleton()->getCoreListForProcess(Config::getSingleton()->getCurrentProcessNum())[i];
      if(local_core_id == core_id)
      {
         if (tid_map[i] == UINT_MAX)
         {
            tid_map[i] = tid;
            tid_to_core_index_map.insert(tid, i);
            tid_to_core_map.insert(tid, core_id);
            LOG_PRINT("Initialize thread : index %d mapped to: thread %d, core_id: %d", i, tid_map[i], core_id);
            return;
         }
         else
         {
            LOG_PRINT("*ERROR* initializeThread -- %d/%d already mapped to thread %d", i, Config::getSingleton()->getNumLocalCores(), tid_map[i]);
            LOG_NOTIFY_ERROR();
         }
      }
   }

   LOG_PRINT("*ERROR* initializeThread - Requested core %d does not live on process %d.", core_id, Config::getSingleton()->getCurrentProcessNum());
   LOG_NOTIFY_ERROR();
}

void CoreManager::terminateThread()
{
   ScopedLock scoped_maps_lock(*m_maps_lock);
   UInt32 tid = getCurrentTID();
   LOG_PRINT("CoreManager::terminating thread: %d", tid);
   pair<bool, UInt64> e = tid_to_core_map.find(tid);

   LOG_ASSERT_WARNING(e.first == true, "*WARNING* Thread: %d not initialized while terminating.", e.second);

   // If it's not in the tid_to_core_map, well then we don't need to remove it
   if(e.first == false)
       return;

   for (UInt32 i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
   {
      if (tid_map[i] == tid)
      {
         tid_map[i] = UINT_MAX;
         tid_to_core_index_map.remove(tid);
         tid_to_core_map.remove(tid);
         LOG_PRINT("Terminate thread : removed %d", e.second);
         return;
      }
      else
      {
         // LOG_PRINT("%d/%d already mapped to: %d", i, Config::getSingleton()->getNumLocalCores(), tid_map[i]);
      }
   }

   LOG_PRINT("*ERROR* terminateThread - Thread tid: %d not found in list.", e.second);
   LOG_NOTIFY_ERROR();
}

UInt32 CoreManager::getCurrentCoreID()
{
   UInt32 id;
   UInt32 tid = getCurrentTID();

   pair<bool, UINT64> e = tid_to_core_map.find(tid);
   id = (e.first == false) ? -1 : e.second;

   LOG_ASSERT_ERROR(!e.first || id < Config::getSingleton()->getTotalCores(), "Illegal core_id value returned by getCurrentCoreID!\n");

   return id;
}

Core *CoreManager::getCurrentCore()
{
   Core *core;
   UInt32 tid = getCurrentTID();

   pair<bool, UINT64> e = tid_to_core_index_map.find(tid);
   core = (e.first == false) ? NULL : m_cores[e.second];

   LOG_ASSERT_ERROR(!e.first || e.second < Config::getSingleton()->getTotalCores(), "Illegal core_id value returned by getCurrentCore!\n");
   return core;
}

Core *CoreManager::getCoreFromID(UInt32 id)
{
   Core *core = NULL;
   // Look up the index from the core list
   // FIXME: make this more cached
   const Config::CoreList & cores(Config::getSingleton()->getCoreListForProcess(Config::getSingleton()->getCurrentProcessNum()));
   UInt32 idx = 0;
   for (Config::CLCI i = cores.begin(); i != cores.end(); i++)
   {
      if (*i == id)
      {
         core = m_cores[idx];
         break;
      }

      idx++;
   }

   LOG_ASSERT_ERROR(!core || idx < Config::getSingleton()->getNumLocalCores(), "Illegal index in getCoreFromID!\n");

   return core;
}

Core *CoreManager::getCoreFromIndex(UInt32 index)
{
   LOG_ASSERT_ERROR(index < Config::getSingleton()->getNumLocalCores(), "getCoreFromIndex -- invalid index %d", index);

   return m_cores[index];
}

void CoreManager::outputSummary()
{
   LOG_PRINT("Starting CoreManager::outputSummary");

   ofstream out(Config::getSingleton()->getOutputFileName());

   for (UInt32 i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
   {
      LOG_PRINT("Output summary core %i", i);

      out << "*** Core[" << i << "] summary ***" << endl;
      if (Config::getSingleton()->getEnablePerformanceModeling())
      {
         m_cores[i]->getPerfModel()->outputSummary(out);
         m_cores[i]->getNetwork()->outputSummary(out);
      }

      if (Config::getSingleton()->getEnableDCacheModeling() || Config::getSingleton()->getEnableICacheModeling())
         m_cores[i]->getOCache()->outputSummary(out);

      out << endl;
   }

   out.close();
}

int CoreManager::registerSimMemThread()
{
   UInt32 tid = getCurrentTID();

   ScopedLock sl(*m_maps_lock);
   pair<bool, UINT64> e = simthread_tid_to_core_map.find(tid);

   // If this thread isn't registered
   if (e.first == false)
   {
      // Search for an unused core to map this simthread thread to
      // one less to account for the MCP
      for (UInt32 i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
      {
         // Unused slots are set to UINT_MAX
         // FIXME: Use a different constant than UINT_MAX
         if (core_to_simthread_tid_map[i] == UINT_MAX)
         {
            core_to_simthread_tid_map[i] = tid;
            simthread_tid_to_core_map.insert(tid, i);
            return Config::getSingleton()->getCoreListForProcess(Config::getSingleton()->getCurrentProcessNum())[i];
         }
      }

      LOG_PRINT("*ERROR* registerSimMemThread - No free cores for thread: %d", tid);
      for (UInt32 j = 0; j < Config::getSingleton()->getNumLocalCores(); j++)
         LOG_PRINT("core_to_simthread_tid_map[%d] = %d\n", j, core_to_simthread_tid_map[j]);

      LOG_NOTIFY_ERROR();
   }
   else
   {
      LOG_PRINT("*WARNING* registerSimMemThread - Initialized thread twice");
      LOG_NOTIFY_WARNING();
      // FIXME: I think this is OK
      return simthread_tid_to_core_map.find(tid).second;
   }

   return -1;
}

UInt32 CoreManager::getCurrentTID()
{
   return  syscall(__NR_gettid);
}

<commit_msg>[core_manager] Fix logging formatting.<commit_after>#include <sched.h>
#include <linux/unistd.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>

#include "core_manager.h"
#include "core.h"
#include "network.h"
#include "ocache.h"
#include "config.h"
#include "packetize.h"
#include "message_types.h"

#include "log.h"
#define LOG_DEFAULT_RANK -1
#define LOG_DEFAULT_MODULE CORE_MANAGER

using namespace std;

CoreManager::CoreManager()
      :
      tid_to_core_map(3*Config::getSingleton()->getNumLocalCores()),
      tid_to_core_index_map(3*Config::getSingleton()->getNumLocalCores()),
      simthread_tid_to_core_map(3*Config::getSingleton()->getNumLocalCores())
{
   LOG_PRINT("Starting CoreManager Constructor.");

   m_maps_lock = Lock::create();

   UInt32 num_local_cores = Config::getSingleton()->getNumLocalCores();

   tid_map = new UInt32 [num_local_cores];
   core_to_simthread_tid_map = new UInt32 [num_local_cores];

   UInt32 proc_id = Config::getSingleton()->getCurrentProcessNum();
   const Config::CoreList &local_cores = Config::getSingleton()->getCoreListForProcess(proc_id);

   for (UInt32 i = 0; i < num_local_cores; i++)
   {
      tid_map[i] = UINT_MAX;
      core_to_simthread_tid_map[i] = UINT_MAX;
      m_cores.push_back(new Core(local_cores[i]));
   }

   LOG_PRINT("Finished CoreManager Constructor.");
}

CoreManager::~CoreManager()
{
   for (std::vector<Core *>::iterator i = m_cores.begin(); i != m_cores.end(); i++)
      delete *i;

   delete [] core_to_simthread_tid_map;
   delete [] tid_map;

   delete m_maps_lock;
}

void CoreManager::initializeCommId(SInt32 comm_id)
{
   UInt32 tid = getCurrentTID();
   pair<bool, UINT64> e = tid_to_core_map.find(tid);

   LOG_ASSERT_ERROR(e.first, "*ERROR* initializeCommId: Called without binding thread to a core.");
   UInt32 core_id = e.second;

   UnstructuredBuffer send_buff;
   send_buff << (SInt32)LCP_MESSAGE_COMMID_UPDATE << comm_id << core_id;

   LOG_PRINT("Initializing comm_id: %d to core_id: %d", comm_id, core_id);

   // Broadcast this update to other processes
   Transport::Node *global_node = Transport::getSingleton()->getGlobalNode();
   UInt32 num_procs = Config::getSingleton()->getProcessCount();

   for (UInt32 i = 0; i < num_procs; i++)
   {
      global_node->globalSend(i,
                              send_buff.getBuffer(),
                              send_buff.size());
   }
}

void CoreManager::initializeThread()
{
   ScopedLock scoped_maps_lock(*m_maps_lock);
   UInt32 tid = getCurrentTID();
   pair<bool, UInt64> e = tid_to_core_map.find(tid);

   LOG_ASSERT_WARNING(e.first == false, "*WARNING* Thread: %d already mapped to core: %lld", tid, e.second);

   for (UInt32 i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
   {
      if (tid_map[i] == UINT_MAX)
      {
         UInt32 core_id = Config::getSingleton()->getCoreListForProcess(Config::getSingleton()->getCurrentProcessNum())[i];
         tid_map[i] = tid;
         tid_to_core_index_map.insert(tid, i);
         tid_to_core_map.insert(tid, core_id);
         LOG_PRINT("Initialize thread : index %d mapped to: thread %d, core_id: %d", i, tid_map[i], core_id);
         return;
      }
      else
      {
         // LOG_PRINT("%d/%d already mapped to: %d", i, Config::getSingleton()->getNumLocalCores(), tid_map[i]);
      }
   }

   LOG_PRINT("*ERROR* initializeThread - No free cores out of %d total.", Config::getSingleton()->getNumLocalCores());
   LOG_NOTIFY_ERROR();
}

void CoreManager::initializeThread(SInt32 core_id)
{
   ScopedLock scoped_maps_lock(*m_maps_lock);
   UInt32 tid = getCurrentTID();
   pair<bool, UInt64> e = tid_to_core_map.find(tid);

   LOG_ASSERT_ERROR(e.first == false, "Tried to initialize core %d twice.", core_id);

   for (unsigned int i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
   {
      SInt32 local_core_id = Config::getSingleton()->getCoreListForProcess(Config::getSingleton()->getCurrentProcessNum())[i];
      if(local_core_id == core_id)
      {
         if (tid_map[i] == UINT_MAX)
         {
            tid_map[i] = tid;
            tid_to_core_index_map.insert(tid, i);
            tid_to_core_map.insert(tid, core_id);
            LOG_PRINT("Initialize thread : index %d mapped to: thread %d, core_id: %d", i, tid_map[i], core_id);
            return;
         }
         else
         {
            LOG_PRINT("*ERROR* initializeThread -- %d/%d already mapped to thread %d", i, Config::getSingleton()->getNumLocalCores(), tid_map[i]);
            LOG_NOTIFY_ERROR();
         }
      }
   }

   LOG_PRINT("*ERROR* initializeThread - Requested core %d does not live on process %d.", core_id, Config::getSingleton()->getCurrentProcessNum());
   LOG_NOTIFY_ERROR();
}

void CoreManager::terminateThread()
{
   ScopedLock scoped_maps_lock(*m_maps_lock);
   UInt32 tid = getCurrentTID();
   LOG_PRINT("CoreManager::terminating thread: %d", tid);
   pair<bool, UInt64> e = tid_to_core_map.find(tid);

   LOG_ASSERT_WARNING(e.first == true, "*WARNING* Thread: %lld not initialized while terminating.", e.second);

   // If it's not in the tid_to_core_map, well then we don't need to remove it
   if(e.first == false)
       return;

   for (UInt32 i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
   {
      if (tid_map[i] == tid)
      {
         tid_map[i] = UINT_MAX;
         tid_to_core_index_map.remove(tid);
         tid_to_core_map.remove(tid);
         LOG_PRINT("Terminate thread : removed %lld", e.second);
         return;
      }
      else
      {
         // LOG_PRINT("%d/%d already mapped to: %d", i, Config::getSingleton()->getNumLocalCores(), tid_map[i]);
      }
   }

   LOG_PRINT("*ERROR* terminateThread - Thread tid: %lld not found in list.", e.second);
   LOG_NOTIFY_ERROR();
}

UInt32 CoreManager::getCurrentCoreID()
{
   UInt32 id;
   UInt32 tid = getCurrentTID();

   pair<bool, UINT64> e = tid_to_core_map.find(tid);
   id = (e.first == false) ? -1 : e.second;

   LOG_ASSERT_ERROR(!e.first || id < Config::getSingleton()->getTotalCores(), "Illegal core_id value returned by getCurrentCoreID!\n");

   return id;
}

Core *CoreManager::getCurrentCore()
{
   Core *core;
   UInt32 tid = getCurrentTID();

   pair<bool, UINT64> e = tid_to_core_index_map.find(tid);
   core = (e.first == false) ? NULL : m_cores[e.second];

   LOG_ASSERT_ERROR(!e.first || e.second < Config::getSingleton()->getTotalCores(), "Illegal core_id value returned by getCurrentCore!\n");
   return core;
}

Core *CoreManager::getCoreFromID(UInt32 id)
{
   Core *core = NULL;
   // Look up the index from the core list
   // FIXME: make this more cached
   const Config::CoreList & cores(Config::getSingleton()->getCoreListForProcess(Config::getSingleton()->getCurrentProcessNum()));
   UInt32 idx = 0;
   for (Config::CLCI i = cores.begin(); i != cores.end(); i++)
   {
      if (*i == id)
      {
         core = m_cores[idx];
         break;
      }

      idx++;
   }

   LOG_ASSERT_ERROR(!core || idx < Config::getSingleton()->getNumLocalCores(), "Illegal index in getCoreFromID!\n");

   return core;
}

Core *CoreManager::getCoreFromIndex(UInt32 index)
{
   LOG_ASSERT_ERROR(index < Config::getSingleton()->getNumLocalCores(), "getCoreFromIndex -- invalid index %d", index);

   return m_cores[index];
}

void CoreManager::outputSummary()
{
   LOG_PRINT("Starting CoreManager::outputSummary");

   ofstream out(Config::getSingleton()->getOutputFileName());

   for (UInt32 i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
   {
      LOG_PRINT("Output summary core %i", i);

      out << "*** Core[" << i << "] summary ***" << endl;
      if (Config::getSingleton()->getEnablePerformanceModeling())
      {
         m_cores[i]->getPerfModel()->outputSummary(out);
         m_cores[i]->getNetwork()->outputSummary(out);
      }

      if (Config::getSingleton()->getEnableDCacheModeling() || Config::getSingleton()->getEnableICacheModeling())
         m_cores[i]->getOCache()->outputSummary(out);

      out << endl;
   }

   out.close();
}

int CoreManager::registerSimMemThread()
{
   UInt32 tid = getCurrentTID();

   ScopedLock sl(*m_maps_lock);
   pair<bool, UINT64> e = simthread_tid_to_core_map.find(tid);

   // If this thread isn't registered
   if (e.first == false)
   {
      // Search for an unused core to map this simthread thread to
      // one less to account for the MCP
      for (UInt32 i = 0; i < Config::getSingleton()->getNumLocalCores(); i++)
      {
         // Unused slots are set to UINT_MAX
         // FIXME: Use a different constant than UINT_MAX
         if (core_to_simthread_tid_map[i] == UINT_MAX)
         {
            core_to_simthread_tid_map[i] = tid;
            simthread_tid_to_core_map.insert(tid, i);
            return Config::getSingleton()->getCoreListForProcess(Config::getSingleton()->getCurrentProcessNum())[i];
         }
      }

      LOG_PRINT("*ERROR* registerSimMemThread - No free cores for thread: %d", tid);
      for (UInt32 j = 0; j < Config::getSingleton()->getNumLocalCores(); j++)
         LOG_PRINT("core_to_simthread_tid_map[%d] = %d\n", j, core_to_simthread_tid_map[j]);

      LOG_NOTIFY_ERROR();
   }
   else
   {
      LOG_PRINT("*WARNING* registerSimMemThread - Initialized thread twice");
      LOG_NOTIFY_WARNING();
      // FIXME: I think this is OK
      return simthread_tid_to_core_map.find(tid).second;
   }

   return -1;
}

UInt32 CoreManager::getCurrentTID()
{
   return  syscall(__NR_gettid);
}

<|endoftext|>


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

#include <fstream>
#include <iostream>
#include <string>
#include <sys/stat.h>

#include "AstPrintDocs.h"

#include "symbol.h"
#include "type.h"

AstPrintDocs::AstPrintDocs(std::ostream *file) :
  file(file),
  tabs(0)
{
}

AstPrintDocs::~AstPrintDocs() {
}

bool AstPrintDocs::enterAggrType(AggregateType* node) {
  node->printDocs(this->file, this->tabs);
  this->tabs++;
  return true;
}

void AstPrintDocs::exitAggrType(AggregateType* node) {
  this->tabs--;
}

bool AstPrintDocs::enterEnumType(EnumType* node) {
  return true;
}

void AstPrintDocs::exitEnumType(EnumType* node) {
}

void AstPrintDocs::visitPrimType(PrimitiveType* node) {
}

bool AstPrintDocs::enterArgSym(ArgSymbol* node) {
  return true;
}

void AstPrintDocs::exitArgSym(ArgSymbol* node) {
}

void AstPrintDocs::visitEnumSym(EnumSymbol* node) {
}

bool AstPrintDocs::enterFnSym(FnSymbol* node) {
  node->printDocs(file, this->tabs);
  return true;
}

void AstPrintDocs::exitFnSym(FnSymbol* node) {
}

void AstPrintDocs::visitIpeSym(IpeSymbol* node) {
}

void AstPrintDocs::visitLabelSym(LabelSymbol* node) {
}

bool AstPrintDocs::enterModSym(ModuleSymbol* node) {
  node->printDocs(this->file, this->tabs);
  //this->tabs++;
  return true;
}

void AstPrintDocs::exitModSym(ModuleSymbol* node) {
  //this->tabs--;
}

bool AstPrintDocs::enterTypeSym(TypeSymbol* node) {
  return true;
}

void AstPrintDocs::exitTypeSym(TypeSymbol* node) {
}

void AstPrintDocs::visitVarSym(VarSymbol* node) {
  node->printDocs(this->file, this->tabs);
}

bool AstPrintDocs::enterCallExpr(CallExpr* node) {
  return true;
}

void AstPrintDocs::exitCallExpr(CallExpr* node) {
}

bool AstPrintDocs::enterDefExpr(DefExpr* node) {
  return true;
}

void AstPrintDocs::exitDefExpr(DefExpr* node) {
}

bool AstPrintDocs::enterNamedExpr(NamedExpr* node) {
  return true;
}

void AstPrintDocs::exitNamedExpr(NamedExpr* node) {
}

void AstPrintDocs::visitSymExpr(SymExpr* node) {
}

void AstPrintDocs::visitUsymExpr(UnresolvedSymExpr* node) {
}

bool AstPrintDocs::enterBlockStmt(BlockStmt* node) {
  return true;
}

void AstPrintDocs::exitBlockStmt(BlockStmt* node) {
}

bool AstPrintDocs::enterWhileDoStmt(WhileDoStmt* node) {
  return true;
}

void AstPrintDocs::exitWhileDoStmt(WhileDoStmt* node) {
}

bool AstPrintDocs::enterDoWhileStmt(DoWhileStmt* node) {
  return true;
}

void AstPrintDocs::exitDoWhileStmt(DoWhileStmt* node) {
}

bool AstPrintDocs::enterCForLoop(CForLoop* node) {
  return true;
}

void AstPrintDocs::exitCForLoop(CForLoop* node) {
}

bool AstPrintDocs::enterForLoop(ForLoop* node) {
  return true;
}

void AstPrintDocs::exitForLoop(ForLoop* node) {
}

bool AstPrintDocs::enterParamForLoop(ParamForLoop* node) {
  return true;
}

void AstPrintDocs::exitParamForLoop(ParamForLoop* node) {
}

bool AstPrintDocs::enterCondStmt(CondStmt* node) {
  return true;
}

void AstPrintDocs::exitCondStmt(CondStmt* node) {
}

void AstPrintDocs::visitEblockStmt(ExternBlockStmt* node) {
}

bool AstPrintDocs::enterGotoStmt(GotoStmt* node) {
  return true;
}

void AstPrintDocs::exitGotoStmt(GotoStmt* node) {
}
<commit_msg>Update AstPrintDocs to avoid traversing into FnSymbols.<commit_after>/*
 * Copyright 2004-2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <fstream>
#include <iostream>
#include <string>
#include <sys/stat.h>

#include "AstPrintDocs.h"

#include "symbol.h"
#include "type.h"

AstPrintDocs::AstPrintDocs(std::ostream *file) :
  file(file),
  tabs(0)
{
}

AstPrintDocs::~AstPrintDocs() {
}

bool AstPrintDocs::enterAggrType(AggregateType* node) {
  node->printDocs(this->file, this->tabs);
  this->tabs++;
  return true;
}

void AstPrintDocs::exitAggrType(AggregateType* node) {
  this->tabs--;
}

bool AstPrintDocs::enterEnumType(EnumType* node) {
  return true;
}

void AstPrintDocs::exitEnumType(EnumType* node) {
}

void AstPrintDocs::visitPrimType(PrimitiveType* node) {
}

bool AstPrintDocs::enterArgSym(ArgSymbol* node) {
  return true;
}

void AstPrintDocs::exitArgSym(ArgSymbol* node) {
}

void AstPrintDocs::visitEnumSym(EnumSymbol* node) {
}

bool AstPrintDocs::enterFnSym(FnSymbol* node) {
  node->printDocs(file, this->tabs);
  return false;
}

void AstPrintDocs::exitFnSym(FnSymbol* node) {
}

void AstPrintDocs::visitIpeSym(IpeSymbol* node) {
}

void AstPrintDocs::visitLabelSym(LabelSymbol* node) {
}

bool AstPrintDocs::enterModSym(ModuleSymbol* node) {
  node->printDocs(this->file, this->tabs);
  //this->tabs++;
  return true;
}

void AstPrintDocs::exitModSym(ModuleSymbol* node) {
  //this->tabs--;
}

bool AstPrintDocs::enterTypeSym(TypeSymbol* node) {
  return true;
}

void AstPrintDocs::exitTypeSym(TypeSymbol* node) {
}

void AstPrintDocs::visitVarSym(VarSymbol* node) {
  node->printDocs(this->file, this->tabs);
}

bool AstPrintDocs::enterCallExpr(CallExpr* node) {
  return true;
}

void AstPrintDocs::exitCallExpr(CallExpr* node) {
}

bool AstPrintDocs::enterDefExpr(DefExpr* node) {
  return true;
}

void AstPrintDocs::exitDefExpr(DefExpr* node) {
}

bool AstPrintDocs::enterNamedExpr(NamedExpr* node) {
  return true;
}

void AstPrintDocs::exitNamedExpr(NamedExpr* node) {
}

void AstPrintDocs::visitSymExpr(SymExpr* node) {
}

void AstPrintDocs::visitUsymExpr(UnresolvedSymExpr* node) {
}

bool AstPrintDocs::enterBlockStmt(BlockStmt* node) {
  return true;
}

void AstPrintDocs::exitBlockStmt(BlockStmt* node) {
}

bool AstPrintDocs::enterWhileDoStmt(WhileDoStmt* node) {
  return true;
}

void AstPrintDocs::exitWhileDoStmt(WhileDoStmt* node) {
}

bool AstPrintDocs::enterDoWhileStmt(DoWhileStmt* node) {
  return true;
}

void AstPrintDocs::exitDoWhileStmt(DoWhileStmt* node) {
}

bool AstPrintDocs::enterCForLoop(CForLoop* node) {
  return true;
}

void AstPrintDocs::exitCForLoop(CForLoop* node) {
}

bool AstPrintDocs::enterForLoop(ForLoop* node) {
  return true;
}

void AstPrintDocs::exitForLoop(ForLoop* node) {
}

bool AstPrintDocs::enterParamForLoop(ParamForLoop* node) {
  return true;
}

void AstPrintDocs::exitParamForLoop(ParamForLoop* node) {
}

bool AstPrintDocs::enterCondStmt(CondStmt* node) {
  return true;
}

void AstPrintDocs::exitCondStmt(CondStmt* node) {
}

void AstPrintDocs::visitEblockStmt(ExternBlockStmt* node) {
}

bool AstPrintDocs::enterGotoStmt(GotoStmt* node) {
  return true;
}

void AstPrintDocs::exitGotoStmt(GotoStmt* node) {
}
<|endoftext|>


<commit_before>#include "emitterstate.h"
#include "yaml-cpp/exceptions.h"
#include <limits>

namespace YAML
{
	EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false), m_hasNonContent(false), m_docCount(0)
	{
		// set default global manipulators
		m_charset.set(EmitNonAscii);
		m_strFmt.set(Auto);
		m_boolFmt.set(TrueFalseBool);
		m_boolLengthFmt.set(LongBool);
		m_boolCaseFmt.set(LowerCase);
		m_intFmt.set(Dec);
		m_indent.set(2);
		m_preCommentIndent.set(2);
		m_postCommentIndent.set(1);
		m_seqFmt.set(Block);
		m_mapFmt.set(Block);
		m_mapKeyFmt.set(Auto);
        m_floatPrecision.set(6);
        m_doublePrecision.set(15);
	}

	EmitterState::~EmitterState()
	{
	}

	// SetLocalValue
	// . We blindly tries to set all possible formatters to this value
	// . Only the ones that make sense will be accepted
	void EmitterState::SetLocalValue(EMITTER_MANIP value)
	{
		SetOutputCharset(value, FmtScope::Local);
		SetStringFormat(value, FmtScope::Local);
		SetBoolFormat(value, FmtScope::Local);
		SetBoolCaseFormat(value, FmtScope::Local);
		SetBoolLengthFormat(value, FmtScope::Local);
		SetIntFormat(value, FmtScope::Local);
		SetFlowType(GroupType::Seq, value, FmtScope::Local);
		SetFlowType(GroupType::Map, value, FmtScope::Local);
		SetMapKeyFormat(value, FmtScope::Local);
	}

    void EmitterState::SetAnchor()
    {
        m_hasAnchor = true;
    }

    void EmitterState::SetTag()
    {
        m_hasTag = true;
    }

    void EmitterState::SetNonContent()
    {
        m_hasNonContent = true;
    }

    void EmitterState::SetLongKey()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;

        assert(m_groups.top().type == GroupType::Map);
        m_groups.top().longKey = true;
    }

    void EmitterState::ForceFlow()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;

        m_groups.top().flowType = FlowType::Flow;
    }

    void EmitterState::StartedNode()
    {
        if(m_groups.empty()) {
            m_docCount++;
        } else {
            m_groups.top().childCount++;
            if(m_groups.top().childCount % 2 == 0)
                m_groups.top().longKey = false;
        }

        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type) const
    {
        if(type == GroupType::Seq) {
            if(GetFlowType(type) == Block)
                return EmitterNodeType::BlockSeq;
            else
                return EmitterNodeType::FlowSeq;
        } else {
            if(GetFlowType(type) == Block)
                return EmitterNodeType::BlockMap;
            else
                return EmitterNodeType::FlowMap;
        }

        // can't happen
        assert(false);
        return EmitterNodeType::None;
    }

    void EmitterState::StartedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    void EmitterState::EndedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    void EmitterState::StartedScalar()
    {
        StartedNode();
        ClearModifiedSettings();
    }

	void EmitterState::StartedGroup(GroupType::value type)
	{
        StartedNode();

		const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		m_curIndent += lastGroupIndent;

		std::auto_ptr<Group> pGroup(new Group(type));

		// transfer settings (which last until this group is done)
		pGroup->modifiedSettings = m_modifiedSettings;

		// set up group
        if(GetFlowType(type) == Block)
            pGroup->flowType = FlowType::Block;
        else
            pGroup->flowType = FlowType::Flow;
		pGroup->indent = GetIndent();

		m_groups.push(pGroup);
	}

	void EmitterState::EndedGroup(GroupType::value type)
	{
		if(m_groups.empty()) {
            if(type == GroupType::Seq)
                return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
            else
                return SetError(ErrorMsg::UNEXPECTED_END_MAP);
        }

		// get rid of the current group
		{
			std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
			if(pFinishedGroup->type != type)
				return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
		}

		// reset old settings
		unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		assert(m_curIndent >= lastIndent);
		m_curIndent -= lastIndent;

		// some global settings that we changed may have been overridden
		// by a local setting we just popped, so we need to restore them
		m_globalModifiedSettings.restore();

        ClearModifiedSettings();
	}

    EmitterNodeType::value EmitterState::CurGroupNodeType() const
    {
        if(m_groups.empty())
            return EmitterNodeType::None;

        return m_groups.top().NodeType();
    }

    GroupType::value EmitterState::CurGroupType() const
	{
        return m_groups.empty() ? GroupType::None : m_groups.top().type;
	}

    FlowType::value EmitterState::CurGroupFlowType() const
	{
        return m_groups.empty() ? FlowType::None : m_groups.top().flowType;
	}

    int EmitterState::CurGroupIndent() const
    {
        return m_groups.empty() ? 0 : m_groups.top().indent;
    }

    std::size_t EmitterState::CurGroupChildCount() const
    {
        return m_groups.empty() ? m_docCount : m_groups.top().childCount;
    }

    bool EmitterState::CurGroupLongKey() const
    {
        return m_groups.empty() ? false : m_groups.top().longKey;
    }

    int EmitterState::LastIndent() const
    {
        if(m_groups.size() <= 1)
            return 0;

        return m_curIndent - m_groups.top(-1).indent;
    }

	void EmitterState::ClearModifiedSettings()
	{
		m_modifiedSettings.clear();
	}

	bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case EmitNonAscii:
			case EscapeNonAscii:
				_Set(m_charset, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Auto:
			case SingleQuoted:
			case DoubleQuoted:
			case Literal:
				_Set(m_strFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case OnOffBool:
			case TrueFalseBool:
			case YesNoBool:
				_Set(m_boolFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case LongBool:
			case ShortBool:
				_Set(m_boolLengthFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case UpperCase:
			case LowerCase:
			case CamelCase:
				_Set(m_boolCaseFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Dec:
			case Hex:
			case Oct:
				_Set(m_intFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetIndent(unsigned value, FmtScope::value scope)
	{
		if(value <= 1)
			return false;

		_Set(m_indent, value, scope);
		return true;
	}

	bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_preCommentIndent, value, scope);
		return true;
	}

	bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_postCommentIndent, value, scope);
		return true;
	}

	bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Block:
			case Flow:
				_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const
	{
		// force flow style if we're currently in a flow
		if(CurGroupFlowType() == FlowType::Flow)
			return Flow;

		// otherwise, go with what's asked of us
		return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
	}

	bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Auto:
			case LongKey:
				_Set(m_mapKeyFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

    bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope)
    {
        if(value < 0 || value > std::numeric_limits<float>::digits10)
            return false;
        _Set(m_floatPrecision, value, scope);
        return true;
    }

    bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope)
    {
        if(value < 0 || value > std::numeric_limits<double>::digits10)
            return false;
        _Set(m_doublePrecision, value, scope);
        return true;
    }
}

<commit_msg>Switch default precision to one more than the number of digits allows.<commit_after>#include "emitterstate.h"
#include "yaml-cpp/exceptions.h"
#include <limits>

namespace YAML
{
	EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false), m_hasNonContent(false), m_docCount(0)
	{
		// set default global manipulators
		m_charset.set(EmitNonAscii);
		m_strFmt.set(Auto);
		m_boolFmt.set(TrueFalseBool);
		m_boolLengthFmt.set(LongBool);
		m_boolCaseFmt.set(LowerCase);
		m_intFmt.set(Dec);
		m_indent.set(2);
		m_preCommentIndent.set(2);
		m_postCommentIndent.set(1);
		m_seqFmt.set(Block);
		m_mapFmt.set(Block);
		m_mapKeyFmt.set(Auto);
        m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1);
        m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
	}

	EmitterState::~EmitterState()
	{
	}

	// SetLocalValue
	// . We blindly tries to set all possible formatters to this value
	// . Only the ones that make sense will be accepted
	void EmitterState::SetLocalValue(EMITTER_MANIP value)
	{
		SetOutputCharset(value, FmtScope::Local);
		SetStringFormat(value, FmtScope::Local);
		SetBoolFormat(value, FmtScope::Local);
		SetBoolCaseFormat(value, FmtScope::Local);
		SetBoolLengthFormat(value, FmtScope::Local);
		SetIntFormat(value, FmtScope::Local);
		SetFlowType(GroupType::Seq, value, FmtScope::Local);
		SetFlowType(GroupType::Map, value, FmtScope::Local);
		SetMapKeyFormat(value, FmtScope::Local);
	}

    void EmitterState::SetAnchor()
    {
        m_hasAnchor = true;
    }

    void EmitterState::SetTag()
    {
        m_hasTag = true;
    }

    void EmitterState::SetNonContent()
    {
        m_hasNonContent = true;
    }

    void EmitterState::SetLongKey()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;

        assert(m_groups.top().type == GroupType::Map);
        m_groups.top().longKey = true;
    }

    void EmitterState::ForceFlow()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;

        m_groups.top().flowType = FlowType::Flow;
    }

    void EmitterState::StartedNode()
    {
        if(m_groups.empty()) {
            m_docCount++;
        } else {
            m_groups.top().childCount++;
            if(m_groups.top().childCount % 2 == 0)
                m_groups.top().longKey = false;
        }

        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type) const
    {
        if(type == GroupType::Seq) {
            if(GetFlowType(type) == Block)
                return EmitterNodeType::BlockSeq;
            else
                return EmitterNodeType::FlowSeq;
        } else {
            if(GetFlowType(type) == Block)
                return EmitterNodeType::BlockMap;
            else
                return EmitterNodeType::FlowMap;
        }

        // can't happen
        assert(false);
        return EmitterNodeType::None;
    }

    void EmitterState::StartedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    void EmitterState::EndedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    void EmitterState::StartedScalar()
    {
        StartedNode();
        ClearModifiedSettings();
    }

	void EmitterState::StartedGroup(GroupType::value type)
	{
        StartedNode();

		const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		m_curIndent += lastGroupIndent;

		std::auto_ptr<Group> pGroup(new Group(type));

		// transfer settings (which last until this group is done)
		pGroup->modifiedSettings = m_modifiedSettings;

		// set up group
        if(GetFlowType(type) == Block)
            pGroup->flowType = FlowType::Block;
        else
            pGroup->flowType = FlowType::Flow;
		pGroup->indent = GetIndent();

		m_groups.push(pGroup);
	}

	void EmitterState::EndedGroup(GroupType::value type)
	{
		if(m_groups.empty()) {
            if(type == GroupType::Seq)
                return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
            else
                return SetError(ErrorMsg::UNEXPECTED_END_MAP);
        }

		// get rid of the current group
		{
			std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
			if(pFinishedGroup->type != type)
				return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
		}

		// reset old settings
		unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		assert(m_curIndent >= lastIndent);
		m_curIndent -= lastIndent;

		// some global settings that we changed may have been overridden
		// by a local setting we just popped, so we need to restore them
		m_globalModifiedSettings.restore();

        ClearModifiedSettings();
	}

    EmitterNodeType::value EmitterState::CurGroupNodeType() const
    {
        if(m_groups.empty())
            return EmitterNodeType::None;

        return m_groups.top().NodeType();
    }

    GroupType::value EmitterState::CurGroupType() const
	{
        return m_groups.empty() ? GroupType::None : m_groups.top().type;
	}

    FlowType::value EmitterState::CurGroupFlowType() const
	{
        return m_groups.empty() ? FlowType::None : m_groups.top().flowType;
	}

    int EmitterState::CurGroupIndent() const
    {
        return m_groups.empty() ? 0 : m_groups.top().indent;
    }

    std::size_t EmitterState::CurGroupChildCount() const
    {
        return m_groups.empty() ? m_docCount : m_groups.top().childCount;
    }

    bool EmitterState::CurGroupLongKey() const
    {
        return m_groups.empty() ? false : m_groups.top().longKey;
    }

    int EmitterState::LastIndent() const
    {
        if(m_groups.size() <= 1)
            return 0;

        return m_curIndent - m_groups.top(-1).indent;
    }

	void EmitterState::ClearModifiedSettings()
	{
		m_modifiedSettings.clear();
	}

	bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case EmitNonAscii:
			case EscapeNonAscii:
				_Set(m_charset, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Auto:
			case SingleQuoted:
			case DoubleQuoted:
			case Literal:
				_Set(m_strFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case OnOffBool:
			case TrueFalseBool:
			case YesNoBool:
				_Set(m_boolFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case LongBool:
			case ShortBool:
				_Set(m_boolLengthFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case UpperCase:
			case LowerCase:
			case CamelCase:
				_Set(m_boolCaseFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Dec:
			case Hex:
			case Oct:
				_Set(m_intFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetIndent(unsigned value, FmtScope::value scope)
	{
		if(value <= 1)
			return false;

		_Set(m_indent, value, scope);
		return true;
	}

	bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_preCommentIndent, value, scope);
		return true;
	}

	bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_postCommentIndent, value, scope);
		return true;
	}

	bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Block:
			case Flow:
				_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const
	{
		// force flow style if we're currently in a flow
		if(CurGroupFlowType() == FlowType::Flow)
			return Flow;

		// otherwise, go with what's asked of us
		return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
	}

	bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Auto:
			case LongKey:
				_Set(m_mapKeyFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

    bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope)
    {
        if(value < 0 || value > std::numeric_limits<float>::digits10 + 1)
            return false;
        _Set(m_floatPrecision, value, scope);
        return true;
    }

    bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope)
    {
        if(value < 0 || value > std::numeric_limits<double>::digits10 + 1)
            return false;
        _Set(m_doublePrecision, value, scope);
        return true;
    }
}

<|endoftext|>


<commit_before>/*
 Copyright (c) 2018 Anon authors, see AUTHORS file.

 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 "aws_http.h"
#include "dns_lookup.h"
#include "http_client.h"
#include <aws/core/http/standard/StandardHttpRequest.h>
#include <aws/core/http/standard/StandardHttpResponse.h>
#include <aws/core/http/Scheme.h>

using namespace Aws::Http;

namespace
{

class http_client : public HttpClient
{
  static std::string normalize(const std::string &path)
  {
    if (path.find("//") == 0)
      return path.substr(1);
    return path;
  }

public:
  http_client(const std::shared_ptr<aws_http_client_factory::epc_map> &maps, const std::shared_ptr<tls_context> &tls)
      : _maps(maps),
        _tls(tls)
  {
  }
  ~http_client() {}

  std::shared_ptr<endpoint_cluster> get_epc(const Aws::String &url) const
  {
    URI uri(url);
    auto key = uri.GetAuthority() + ":" + std::to_string(uri.GetPort());
    fiber_lock l(_maps->_mtx);
    auto &m = _maps->_epc_map;
    auto epc = m.find(key);
    if (epc != m.end())
      return epc->second;

    return m[key] = endpoint_cluster::create(uri.GetAuthority().c_str(), uri.GetPort(),
                                             uri.GetScheme() == Scheme::HTTPS, _tls.get());
  }

  std::shared_ptr<HttpResponse> MakeRequest(HttpRequest &request,
                                            URI uri,
                                            Aws::Utils::RateLimits::RateLimiterInterface *readLimiter,
                                            Aws::Utils::RateLimits::RateLimiterInterface *writeLimiter,
                                            int recursion) const
  {
    //URI uri = request.GetUri();
    // anon_log("MakeRequest, url: " << uri.GetURIString());

    // auto start_time = cur_time();

    auto body = request.GetContentBody();
    std::vector<char> body_buff;
    if (body)
      body_buff = std::vector<char>((std::istreambuf_iterator<char>(*body)), std::istreambuf_iterator<char>());

    auto method = request.GetMethod();
    std::ostringstream str;
    str << HttpMethodMapper::GetNameForHttpMethod(method) << " " << normalize(uri.GetPath()) << " HTTP/1.1\r\n";
    auto headers = request.GetHeaders();
    for (auto &h : headers)
      str << h.first << ": " << h.second << "\r\n";
    if (body && !request.HasHeader(CONTENT_LENGTH_HEADER))
    {
      str << "transfer-encoding: identity\r\n";
      str << "content-length: " << body_buff.size() << "\r\n";
    }

    str << "\r\n";
    if (body)
      str.write(&body_buff[0], body_buff.size());
    auto message = str.str();

    std::shared_ptr<Standard::StandardHttpResponse> resp;
    auto read_body = method != HttpMethod::HTTP_HEAD;
    try
    {
      get_epc(uri.GetURIString())->with_connected_pipe([&request, &resp, &message, read_body](const pipe_t *pipe) {
        // anon_log("sending...\n\n" << message << "\n");
        pipe->write(message.c_str(), message.size());
        http_client_response re;
        re.parse(*pipe, read_body);
        resp = std::make_shared<Standard::StandardHttpResponse>(request);
        resp->SetResponseCode(static_cast<HttpResponseCode>(re.status_code));
        for (auto &h : re.headers.headers)
          resp->AddHeader(h.first.str(), h.second.str());
        for (auto &data : re.body)
          resp->GetResponseBody().write(&data[0], data.size());
      });
    }
    catch (const std::exception &exc)
    {
      anon_log_error("failure to write request: " << exc.what());
      resp = std::make_shared<Standard::StandardHttpResponse>(request);
      resp->SetResponseCode(HttpResponseCode::INTERNAL_SERVER_ERROR);
    }
    catch (...)
    {
      anon_log_error("unknown failure to write request");
      resp = std::make_shared<Standard::StandardHttpResponse>(request);
      resp->SetResponseCode(HttpResponseCode::INTERNAL_SERVER_ERROR);
    }

    // anon_log("time for transfer: " << cur_time() - start_time);

    return std::static_pointer_cast<HttpResponse>(resp);
  }

  std::shared_ptr<HttpResponse> MakeRequest(HttpRequest &request,
                                            Aws::Utils::RateLimits::RateLimiterInterface *readLimiter,
                                            Aws::Utils::RateLimits::RateLimiterInterface *writeLimiter) const override
  {
    return MakeRequest(request, request.GetUri(), readLimiter, writeLimiter, 0);
  }

  std::shared_ptr<HttpResponse> MakeRequest(const std::shared_ptr<HttpRequest> &request,
                                            Aws::Utils::RateLimits::RateLimiterInterface *readLimiter,
                                            Aws::Utils::RateLimits::RateLimiterInterface *writeLimiter) const override
  {
    return MakeRequest(*request, readLimiter, writeLimiter);
  }

  std::shared_ptr<aws_http_client_factory::epc_map> _maps;
  std::shared_ptr<tls_context> _tls;
};

} // namespace

/////////////////////////////////////////////////////////////////////////////////////////////////

aws_http_client_factory::aws_http_client_factory()
    : _maps(std::make_shared<epc_map>()),
      _tls(std::make_shared<tls_context>(true /*client*/, nullptr /*verify_cert*/, "/etc/ssl/certs" /*verify_loc*/, nullptr, nullptr, 5))
{
}

std::shared_ptr<HttpClient> aws_http_client_factory::CreateHttpClient(const Aws::Client::ClientConfiguration &clientConfiguration) const
{
  return std::static_pointer_cast<HttpClient>(std::make_shared<http_client>(_maps, _tls));
}

std::shared_ptr<HttpRequest> aws_http_client_factory::CreateHttpRequest(const Aws::String &uri, HttpMethod method, const Aws::IOStreamFactory &streamFactory) const
{
  auto req = std::static_pointer_cast<HttpRequest>(std::make_shared<Standard::StandardHttpRequest>(uri, method));
  req->SetResponseStreamFactory(streamFactory);
  return req;
}

std::shared_ptr<HttpRequest> aws_http_client_factory::CreateHttpRequest(const URI &uri, HttpMethod method, const Aws::IOStreamFactory &streamFactory) const
{
  auto req = std::static_pointer_cast<HttpRequest>(std::make_shared<Standard::StandardHttpRequest>(uri, method));
  req->SetResponseStreamFactory(streamFactory);
  return req;
}
<commit_msg>next step<commit_after>/*
 Copyright (c) 2018 Anon authors, see AUTHORS file.

 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 "aws_http.h"
#include "dns_lookup.h"
#include "http_client.h"
#include <aws/core/http/standard/StandardHttpRequest.h>
#include <aws/core/http/standard/StandardHttpResponse.h>
#include <aws/core/http/Scheme.h>

using namespace Aws::Http;

namespace
{

class http_client : public HttpClient
{
  static std::string normalize(const std::string &path)
  {
    if (path.find("//") == 0)
      return path.substr(1);
    return path;
  }

public:
  http_client(const std::shared_ptr<aws_http_client_factory::epc_map> &maps, const std::shared_ptr<tls_context> &tls)
      : _maps(maps),
        _tls(tls)
  {
  }
  ~http_client() {}

  std::shared_ptr<endpoint_cluster> get_epc(const Aws::String &url) const
  {
    URI uri(url);
    auto key = uri.GetAuthority() + ":" + std::to_string(uri.GetPort());
    fiber_lock l(_maps->_mtx);
    auto &m = _maps->_epc_map;
    auto epc = m.find(key);
    if (epc != m.end())
      return epc->second;

    return m[key] = endpoint_cluster::create(uri.GetAuthority().c_str(), uri.GetPort(),
                                             uri.GetScheme() == Scheme::HTTPS, _tls.get());
  }

  std::shared_ptr<HttpResponse> MakeRequest(HttpRequest &request,
                                            URI uri,
                                            Aws::Utils::RateLimits::RateLimiterInterface *readLimiter,
                                            Aws::Utils::RateLimits::RateLimiterInterface *writeLimiter,
                                            int recursion) const
  {
    if (recursion > 4) {
      auto resp = std::make_shared<Standard::StandardHttpResponse>(request);
      resp->SetResponseCode(HttpResponseCode::INTERNAL_SERVER_ERROR);
      return std::static_pointer_cast<HttpResponse>(resp);
    }

    // auto start_time = cur_time();

    auto body = request.GetContentBody();
    std::vector<char> body_buff;
    if (body)
      body_buff = std::vector<char>((std::istreambuf_iterator<char>(*body)), std::istreambuf_iterator<char>());

    auto method = request.GetMethod();
    std::ostringstream str;
    str << HttpMethodMapper::GetNameForHttpMethod(method) << " " << normalize(uri.GetPath()) << " HTTP/1.1\r\n";
    auto headers = request.GetHeaders();
    for (auto &h : headers)
      str << h.first << ": " << h.second << "\r\n";
    if (body && !request.HasHeader(CONTENT_LENGTH_HEADER))
    {
      str << "transfer-encoding: identity\r\n";
      str << "content-length: " << body_buff.size() << "\r\n";
    }

    str << "\r\n";
    if (body)
      str.write(&body_buff[0], body_buff.size());
    auto message = str.str();

    std::shared_ptr<Standard::StandardHttpResponse> resp;
    auto read_body = method != HttpMethod::HTTP_HEAD;
    try
    {
      get_epc(uri.GetURIString())->with_connected_pipe([&request, &resp, &message, read_body](const pipe_t *pipe) {
        // anon_log("sending...\n\n" << message << "\n");
        pipe->write(message.c_str(), message.size());
        http_client_response re;
        re.parse(*pipe, read_body);
        resp = std::make_shared<Standard::StandardHttpResponse>(request);
        resp->SetResponseCode(static_cast<HttpResponseCode>(re.status_code));
        for (auto &h : re.headers.headers)
          resp->AddHeader(h.first.str(), h.second.str());
        for (auto &data : re.body)
          resp->GetResponseBody().write(&data[0], data.size());
      });
    }
    catch (const std::exception &exc)
    {
      anon_log_error("failure to write request: " << exc.what());
      resp = std::make_shared<Standard::StandardHttpResponse>(request);
      resp->SetResponseCode(HttpResponseCode::INTERNAL_SERVER_ERROR);
    }
    catch (...)
    {
      anon_log_error("unknown failure to write request");
      resp = std::make_shared<Standard::StandardHttpResponse>(request);
      resp->SetResponseCode(HttpResponseCode::INTERNAL_SERVER_ERROR);
    }

    // anon_log("time for transfer: " << cur_time() - start_time);

    return std::static_pointer_cast<HttpResponse>(resp);
  }

  std::shared_ptr<HttpResponse> MakeRequest(HttpRequest &request,
                                            Aws::Utils::RateLimits::RateLimiterInterface *readLimiter,
                                            Aws::Utils::RateLimits::RateLimiterInterface *writeLimiter) const override
  {
    return MakeRequest(request, request.GetUri(), readLimiter, writeLimiter, 0);
  }

  std::shared_ptr<HttpResponse> MakeRequest(const std::shared_ptr<HttpRequest> &request,
                                            Aws::Utils::RateLimits::RateLimiterInterface *readLimiter,
                                            Aws::Utils::RateLimits::RateLimiterInterface *writeLimiter) const override
  {
    return MakeRequest(*request, readLimiter, writeLimiter);
  }

  std::shared_ptr<aws_http_client_factory::epc_map> _maps;
  std::shared_ptr<tls_context> _tls;
};

} // namespace

/////////////////////////////////////////////////////////////////////////////////////////////////

aws_http_client_factory::aws_http_client_factory()
    : _maps(std::make_shared<epc_map>()),
      _tls(std::make_shared<tls_context>(true /*client*/, nullptr /*verify_cert*/, "/etc/ssl/certs" /*verify_loc*/, nullptr, nullptr, 5))
{
}

std::shared_ptr<HttpClient> aws_http_client_factory::CreateHttpClient(const Aws::Client::ClientConfiguration &clientConfiguration) const
{
  return std::static_pointer_cast<HttpClient>(std::make_shared<http_client>(_maps, _tls));
}

std::shared_ptr<HttpRequest> aws_http_client_factory::CreateHttpRequest(const Aws::String &uri, HttpMethod method, const Aws::IOStreamFactory &streamFactory) const
{
  auto req = std::static_pointer_cast<HttpRequest>(std::make_shared<Standard::StandardHttpRequest>(uri, method));
  req->SetResponseStreamFactory(streamFactory);
  return req;
}

std::shared_ptr<HttpRequest> aws_http_client_factory::CreateHttpRequest(const URI &uri, HttpMethod method, const Aws::IOStreamFactory &streamFactory) const
{
  auto req = std::static_pointer_cast<HttpRequest>(std::make_shared<Standard::StandardHttpRequest>(uri, method));
  req->SetResponseStreamFactory(streamFactory);
  return req;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2008-2017 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * MRtrix 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.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "gui/mrview/tool/transform.h"

namespace MR
{
  namespace GUI
  {
    namespace MRView
    {
      namespace Tool
      {

        Transform::Transform (Dock* parent) :
          Base (parent)
        {
          VBoxLayout* main_box = new VBoxLayout (this);
          QLabel* label = new QLabel (
              "When active, all camera view manipulations will apply "
              "to the main image, rather than to the camera");
          label->setWordWrap (true);
          label->setAlignment (Qt::AlignHCenter);
          main_box->addWidget (label);

          activate_button = new QPushButton ("Activate",this);
          activate_button->setToolTip (tr ("Activate transform manipulation mode"));
          activate_button->setIcon (QIcon (":/rotate.svg"));
          activate_button->setCheckable (true);
          connect (activate_button, SIGNAL (clicked(bool)), this, SLOT (onActivate (bool)));
          main_box->addWidget (activate_button);

          main_box->addStretch ();
          show();
        }

        void Transform::setActive (bool onoff)
        {
          activate_button->setChecked (onoff);
          if (isVisible()) {
            if (onoff)
              activate_button->setText (tr ("on"));
            else
              activate_button->setText (tr ("off"));
          }
          window().register_camera_interactor ( (isVisible() && onoff) ? this : nullptr );
        }

        void Transform::onActivate (bool onoff)
        {
          setActive (onoff);
        }

        void Transform::showEvent (QShowEvent*)
        {
          setActive (false);
        }

        void Transform::closeEvent (QCloseEvent*)
        {
          setActive (false);
        }

        void Transform::hideEvent (QHideEvent*)
        {
          setActive (false);
        }

        bool Transform::slice_move_event (const ModelViewProjection& projection, float x)
        {
          const auto &header = window().image()->header();
          float increment = window().snap_to_image() ?
            x * header.spacing (window().plane()) :
            x * std::pow (header.spacing(0) * header.spacing(1) * header.spacing(2), 1.0f/3.0f);
          auto move = window().get_current_mode()->get_through_plane_translation (increment, projection);

          transform_type M = header.transform();
          M.translate (-move.cast<double>());

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();
          return true;
        }

        bool Transform::pan_event (const ModelViewProjection& projection)
        {
          auto move = projection.screen_to_model_direction (window().mouse_displacement(), window().target());

          transform_type M = window().image()->header().transform();
          M.pretranslate (move.cast<double>());

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();

          return true;
        }

        bool Transform::panthrough_event (const ModelViewProjection& projection)
        {
          auto move = window().get_current_mode()->get_through_plane_translation_FOV (window().mouse_displacement().y(), projection);

          transform_type M = window().image()->header().transform();
          M.pretranslate (-move.cast<double>());

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();

          return true;
        }

        bool Transform::tilt_event (const ModelViewProjection& projection)
        {
          if (window().snap_to_image())
            window().set_snap_to_image (false);

          const auto rot = window().get_current_mode()->get_tilt_rotation (projection).cast<double>();
          if (!rot.coeffs().allFinite())
            return true;

          const Eigen::Vector3d origin = window().focus().cast<double>();
          transform_type M = transform_type (rot).pretranslate (origin).translate (-origin) * window().image()->header().transform();

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();

          return true;
        }

        bool Transform::rotate_event (const ModelViewProjection& projection)
        {
          if (window().snap_to_image())
            window().set_snap_to_image (false);

          const auto rot = window().get_current_mode()->get_rotate_rotation (projection).cast<double>();
          if (!rot.coeffs().allFinite())
            return true;

          const Eigen::Vector3d origin = window().target().cast<double>();
          transform_type M = transform_type (rot).inverse().pretranslate (origin).translate (-origin) * window().image()->header().transform();

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();

          return true;
        }

      }
    }
  }
}

<commit_msg>mrview transform tool: fix tilt rotation<commit_after>/* Copyright (c) 2008-2017 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * MRtrix 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.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "gui/mrview/tool/transform.h"

namespace MR
{
  namespace GUI
  {
    namespace MRView
    {
      namespace Tool
      {

        Transform::Transform (Dock* parent) :
          Base (parent)
        {
          VBoxLayout* main_box = new VBoxLayout (this);
          QLabel* label = new QLabel (
              "When active, all camera view manipulations will apply "
              "to the main image, rather than to the camera");
          label->setWordWrap (true);
          label->setAlignment (Qt::AlignHCenter);
          main_box->addWidget (label);

          activate_button = new QPushButton ("Activate",this);
          activate_button->setToolTip (tr ("Activate transform manipulation mode"));
          activate_button->setIcon (QIcon (":/rotate.svg"));
          activate_button->setCheckable (true);
          connect (activate_button, SIGNAL (clicked(bool)), this, SLOT (onActivate (bool)));
          main_box->addWidget (activate_button);

          main_box->addStretch ();
          show();
        }

        void Transform::setActive (bool onoff)
        {
          activate_button->setChecked (onoff);
          if (isVisible()) {
            if (onoff)
              activate_button->setText (tr ("on"));
            else
              activate_button->setText (tr ("off"));
          }
          window().register_camera_interactor ( (isVisible() && onoff) ? this : nullptr );
        }

        void Transform::onActivate (bool onoff)
        {
          setActive (onoff);
        }

        void Transform::showEvent (QShowEvent*)
        {
          setActive (false);
        }

        void Transform::closeEvent (QCloseEvent*)
        {
          setActive (false);
        }

        void Transform::hideEvent (QHideEvent*)
        {
          setActive (false);
        }

        bool Transform::slice_move_event (const ModelViewProjection& projection, float x)
        {
          const auto &header = window().image()->header();
          float increment = window().snap_to_image() ?
            x * header.spacing (window().plane()) :
            x * std::pow (header.spacing(0) * header.spacing(1) * header.spacing(2), 1.0f/3.0f);
          auto move = window().get_current_mode()->get_through_plane_translation (increment, projection);

          transform_type M = header.transform();
          M.translate (-move.cast<double>());

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();
          return true;
        }

        bool Transform::pan_event (const ModelViewProjection& projection)
        {
          auto move = projection.screen_to_model_direction (window().mouse_displacement(), window().target());

          transform_type M = window().image()->header().transform();
          M.pretranslate (move.cast<double>());

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();

          return true;
        }

        bool Transform::panthrough_event (const ModelViewProjection& projection)
        {
          auto move = window().get_current_mode()->get_through_plane_translation_FOV (window().mouse_displacement().y(), projection);

          transform_type M = window().image()->header().transform();
          M.pretranslate (-move.cast<double>());

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();

          return true;
        }

        bool Transform::tilt_event (const ModelViewProjection& projection)
        {
          if (window().snap_to_image())
            window().set_snap_to_image (false);

          const auto rot = window().get_current_mode()->get_tilt_rotation (projection).cast<double>().inverse();
          if (!rot.coeffs().allFinite())
            return true;

          const Eigen::Vector3d origin = window().focus().cast<double>();
          transform_type M = transform_type (rot).pretranslate (origin).translate (-origin) * window().image()->header().transform();

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();

          return true;
        }

        bool Transform::rotate_event (const ModelViewProjection& projection)
        {
          if (window().snap_to_image())
            window().set_snap_to_image (false);

          const auto rot = window().get_current_mode()->get_rotate_rotation (projection).cast<double>();
          if (!rot.coeffs().allFinite())
            return true;

          const Eigen::Vector3d origin = window().target().cast<double>();
          transform_type M = transform_type (rot).inverse().pretranslate (origin).translate (-origin) * window().image()->header().transform();

          window().image()->header().transform() = M;
          window().image()->image.buffer->transform() = M;
          window().updateGL();

          return true;
        }

      }
    }
  }
}

<|endoftext|>


<commit_before><commit_msg>Made the Timing Path Tablew View columns resizeable<commit_after><|endoftext|>