<commit_before>//
//  Copyright (C) 2016  Clifford Wolf <clifford@clifford.at>
//
//  Permission to use, copy, modify, and/or distribute this software for any
//  purpose with or without fee is hereby granted, provided that the above
//  copyright notice and this permission notice appear in all copies.
//
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
//  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
//  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
//  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
//  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
//  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <sys/time.h>

#include <map>
#include <vector>
#include <string>
#include <fstream>
#include <iostream>

using std::map;
using std::pair;
using std::vector;
using std::string;
using std::ifstream;
using std::getline;

uint64_t x;
uint64_t xorshift64star(void) {
	x ^= x >> 12; // a
	x ^= x << 25; // b
	x ^= x >> 27; // c
	return x * UINT64_C(2685821657736338717);
}

void parse_hexfile_line(const char *filename, int linenr, vector<vector<bool>> &hexfile, string &line)
{
	vector<int> digits;

	for (char c : line) {
		if ('0' <= c && c <= '9')
			digits.push_back(c - '0');
		else if ('a' <= c && c <= 'f')
			digits.push_back(10 + c - 'a');
		else if ('A' <= c && c <= 'F')
			digits.push_back(10 + c - 'A');
		else goto error;
	}

	hexfile.push_back(vector<bool>(digits.size() * 4));

	for (int i = 0; i < int(digits.size()) * 4; i++)
		if ((digits.at(digits.size() - i/4 -1) & (1 << (i%4))) != 0)
			hexfile.back().at(i) = true;

	return;

error:
	fprintf(stderr, "Can't parse line %d of %s: %s\n", linenr, filename, line.c_str());
	exit(1);
}

void help(const char *cmd)
{
	printf("\n");
	printf("Usage: %s [options] <from_hexfile> <to_hexfile>\n", cmd);
	printf("       %s [options] -g <width> <depth>\n", cmd);
	printf("\n");
	printf("Replace BRAM initialization data in a .asc file. This can be used\n");
	printf("for example to replace firmware images without re-running synthesis\n");
	printf("and place&route.\n");
	printf("\n");
	printf("    -g\n");
	printf("        generate a hex file with random contents.\n");
	printf("        use this to generate the hex file used during synthesis, then\n");
	printf("        use the same file as <from_hexfile> later.\n");
	printf("\n");
	printf("    -v\n");
	printf("        verbose output\n");
	printf("\n");
	exit(1);
}

int main(int argc, char **argv)
{
	bool verbose = false;
	bool generate = false;

	int opt;
	while ((opt = getopt(argc, argv, "vg")) != -1)
	{
		switch (opt)
		{
		case 'v':
			verbose = true;
			break;
		case 'g':
			generate = true;
			break;
		default:
			help(argv[0]);
		}
	}

	if (generate)
	{
		if (optind+2 != argc)
			help(argv[0]);

		int width = atoi(argv[optind]);
		int depth = atoi(argv[optind+1]);

		if (width <= 0 || width % 4 != 0) {
			fprintf(stderr, "Hexfile width (%d bits) is not divisible by 4 or nonpositive!\n", width);
			exit(1);
		}

		if (depth <= 0 || depth % 256 != 0) {
			fprintf(stderr, "Hexfile number of words (%d) is not divisible by 256 or nonpositive!\n", depth);
			exit(1);
		}

		x = uint64_t(getpid()) << 32;
		x ^= uint64_t(depth) << 16;
		x ^= uint64_t(width) << 10;

		xorshift64star();
		xorshift64star();
		xorshift64star();

		struct timeval tv;
		gettimeofday(&tv, NULL);
		x ^= uint64_t(tv.tv_sec) << 20;
		x ^= uint64_t(tv.tv_usec);

		xorshift64star();
		xorshift64star();
		xorshift64star();

		for (int i = 0; i < depth; i++) {
			for (int j = 0; j < width / 4; j++) {
				int digit = xorshift64star() & 15;
				std::cout << "0123456789abcdef"[digit];
			}
			std::cout << std::endl;
		}

		exit(0);
	}

	if (optind+2 != argc)
		help(argv[0]);

	// -------------------------------------------------------
	// Load from_hexfile and to_hexfile

	const char *from_hexfile_n = argv[optind];
	ifstream from_hexfile_f(from_hexfile_n);
	vector<vector<bool>> from_hexfile;

	const char *to_hexfile_n = argv[optind+1];
	ifstream to_hexfile_f(to_hexfile_n);
	vector<vector<bool>> to_hexfile;

	string line;

	for (int i = 1; getline(from_hexfile_f, line); i++)
		parse_hexfile_line(from_hexfile_n, i, from_hexfile, line);

	for (int i = 1; getline(to_hexfile_f, line); i++)
		parse_hexfile_line(to_hexfile_n, i, to_hexfile, line);

	if (from_hexfile.size() != to_hexfile.size()) {
		fprintf(stderr, "Hexfiles have different number of words! (%d vs. %d)\n", int(from_hexfile.size()), int(to_hexfile.size()));
		exit(1);
	}

	if (from_hexfile.size() % 256 != 0) {
		fprintf(stderr, "Hexfile number of words (%d) is not divisible by 256!\n", int(from_hexfile.size()));
		exit(1);
	}

	for (size_t i = 1; i < from_hexfile.size(); i++)
		if (from_hexfile.at(i-1).size() != from_hexfile.at(i).size()) {
			fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i), from_hexfile_n);
			exit(1);
		}

	for (size_t i = 1; i < to_hexfile.size(); i++) {
		while (to_hexfile.at(i-1).size() > to_hexfile.at(i).size())
			to_hexfile.at(i).push_back(false);
		if (to_hexfile.at(i-1).size() != to_hexfile.at(i).size()) {
			fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i+1), to_hexfile_n);
			exit(1);
		}
	}

	if (from_hexfile.size() == 0 || from_hexfile.at(0).size() == 0) {
		fprintf(stderr, "Empty from/to hexfiles!\n");
		exit(1);
	}

	if (verbose)
		fprintf(stderr, "Loaded pattern for %d bits wide and %d words deep memory.\n", int(from_hexfile.at(0).size()), int(from_hexfile.size()));

	// -------------------------------------------------------
	// Create bitslices from pattern data

	map<vector<bool>, pair<vector<bool>, int>> pattern;

	for (int i = 0; i < int(from_hexfile.at(0).size()); i++)
	{
		vector<bool> pattern_from, pattern_to;

		for (int j = 0; j < int(from_hexfile.size()); j++)
		{
			pattern_from.push_back(from_hexfile.at(j).at(i));
			pattern_to.push_back(to_hexfile.at(j).at(i));

			if (pattern_from.size() == 256) {
				if (pattern.count(pattern_from)) {
					fprintf(stderr, "Conflicting from pattern for bit slice from_hexfile[%d:%d][%d]!\n", j, j-255, i);
					exit(1);
				}
				pattern[pattern_from] = std::make_pair(pattern_to, 0);
				pattern_from.clear(), pattern_to.clear();
			}
		}

		assert(pattern_from.empty());
		assert(pattern_to.empty());
	}

	if (verbose)
		fprintf(stderr, "Extracted %d bit slices from from/to hexfile data.\n", int(pattern.size()));

	// -------------------------------------------------------
	// Read ascfile from stdin

	vector<string> ascfile_lines;
	map<string, vector<vector<bool>>> ascfile_hexdata;

	for (int i = 1; getline(std::cin, line); i++)
	{
	next_asc_stmt:
		ascfile_lines.push_back(line);

		if (line.substr(0, 9) == ".ram_data")
		{
			auto &hexdata = ascfile_hexdata[line];

			for (; getline(std::cin, line); i++) {
				if (line.substr(0, 1) == ".")
					goto next_asc_stmt;
				parse_hexfile_line("stdin", i, hexdata, line);
			}
		}
	}

	if (verbose)
		fprintf(stderr, "Found %d initialized bram cells in asc file.\n", int(ascfile_hexdata.size()));

	// -------------------------------------------------------
	// Replace bram data

	int max_replace_cnt = 0;

	for (auto &bram_it : ascfile_hexdata)
	{
		auto &bram_data = bram_it.second;

		for (int i = 0; i < 16; i++)
		{
			vector<bool> from_bitslice;

			for (int j = 0; j < 256; j++)
				from_bitslice.push_back(bram_data.at(j / 16).at(16 * (j % 16) + i));

			auto p = pattern.find(from_bitslice);
			if (p != pattern.end())
			{
				auto &to_bitslice = p->second.first;

				for (int j = 0; j < 256; j++)
					bram_data.at(j / 16).at(16 * (j % 16) + i) = to_bitslice.at(j);

				max_replace_cnt = std::max(++p->second.second, max_replace_cnt);
			}
		}
	}

	int min_replace_cnt = max_replace_cnt;
	for (auto &it : pattern)
		min_replace_cnt = std::min(min_replace_cnt, it.second.second);

	if (min_replace_cnt != max_replace_cnt) {
		fprintf(stderr, "Found some bitslices up to %d times, others only %d times!\n", max_replace_cnt, min_replace_cnt);
		exit(1);
	}

	if (verbose)
		fprintf(stderr, "Found and replaced %d instances of the memory.\n", max_replace_cnt);

	// -------------------------------------------------------
	// Write ascfile to stdout

	for (size_t i = 0; i < ascfile_lines.size(); i++) {
		auto &line = ascfile_lines.at(i);
		std::cout << line << std::endl;
		if (ascfile_hexdata.count(line)) {
			for (auto &word : ascfile_hexdata.at(line)) {
				for (int k = word.size()-4; k >= 0; k -= 4) {
					int digit = (word[k+3] ? 8 : 0) + (word[k+2] ? 4 : 0) + (word[k+1] ? 2 : 0) + (word[k] ? 1 : 0);
					std::cout << "0123456789abcdef"[digit];
				}
				std::cout << std::endl;
			}
		}
	}

	return 0;
}
<commit_msg>Improve input parsing of icebram<commit_after>//
//  Copyright (C) 2016  Clifford Wolf <clifford@clifford.at>
//
//  Permission to use, copy, modify, and/or distribute this software for any
//  purpose with or without fee is hereby granted, provided that the above
//  copyright notice and this permission notice appear in all copies.
//
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
//  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
//  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
//  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
//  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
//  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <sys/time.h>

#include <map>
#include <vector>
#include <string>
#include <fstream>
#include <iostream>

using std::map;
using std::pair;
using std::vector;
using std::string;
using std::ifstream;
using std::getline;

uint64_t x;
uint64_t xorshift64star(void) {
	x ^= x >> 12; // a
	x ^= x << 25; // b
	x ^= x >> 27; // c
	return x * UINT64_C(2685821657736338717);
}

void push_back_bitvector(vector<vector<bool>> &hexfile, const vector<int> &digits)
{
	if (digits.empty())
		return;

	hexfile.push_back(vector<bool>(digits.size() * 4));

	for (int i = 0; i < int(digits.size()) * 4; i++)
		if ((digits.at(digits.size() - i/4 -1) & (1 << (i%4))) != 0)
			hexfile.back().at(i) = true;
}

void parse_hexfile_line(const char *filename, int linenr, vector<vector<bool>> &hexfile, string &line)
{
	vector<int> digits;

	for (char c : line) {
		if ('0' <= c && c <= '9')
			digits.push_back(c - '0');
		else if ('a' <= c && c <= 'f')
			digits.push_back(10 + c - 'a');
		else if ('A' <= c && c <= 'F')
			digits.push_back(10 + c - 'A');
		else if ('x' == c || 'X' == c ||
			 'z' == c || 'Z' == c)
			digits.push_back(0);
		else if ('_' == c)
			;
		else if (' ' == c || '\t' == c || '\r' == c) {
			push_back_bitvector(hexfile, digits);
			digits.clear();
		} else goto error;
	}

	push_back_bitvector(hexfile, digits);

	return;

error:
	fprintf(stderr, "Can't parse line %d of %s: %s\n", linenr, filename, line.c_str());
	exit(1);
}

void help(const char *cmd)
{
	printf("\n");
	printf("Usage: %s [options] <from_hexfile> <to_hexfile>\n", cmd);
	printf("       %s [options] -g <width> <depth>\n", cmd);
	printf("\n");
	printf("Replace BRAM initialization data in a .asc file. This can be used\n");
	printf("for example to replace firmware images without re-running synthesis\n");
	printf("and place&route.\n");
	printf("\n");
	printf("    -g\n");
	printf("        generate a hex file with random contents.\n");
	printf("        use this to generate the hex file used during synthesis, then\n");
	printf("        use the same file as <from_hexfile> later.\n");
	printf("\n");
	printf("    -v\n");
	printf("        verbose output\n");
	printf("\n");
	exit(1);
}

int main(int argc, char **argv)
{
	bool verbose = false;
	bool generate = false;

	int opt;
	while ((opt = getopt(argc, argv, "vg")) != -1)
	{
		switch (opt)
		{
		case 'v':
			verbose = true;
			break;
		case 'g':
			generate = true;
			break;
		default:
			help(argv[0]);
		}
	}

	if (generate)
	{
		if (optind+2 != argc)
			help(argv[0]);

		int width = atoi(argv[optind]);
		int depth = atoi(argv[optind+1]);

		if (width <= 0 || width % 4 != 0) {
			fprintf(stderr, "Hexfile width (%d bits) is not divisible by 4 or nonpositive!\n", width);
			exit(1);
		}

		if (depth <= 0 || depth % 256 != 0) {
			fprintf(stderr, "Hexfile number of words (%d) is not divisible by 256 or nonpositive!\n", depth);
			exit(1);
		}

		x = uint64_t(getpid()) << 32;
		x ^= uint64_t(depth) << 16;
		x ^= uint64_t(width) << 10;

		xorshift64star();
		xorshift64star();
		xorshift64star();

		struct timeval tv;
		gettimeofday(&tv, NULL);
		x ^= uint64_t(tv.tv_sec) << 20;
		x ^= uint64_t(tv.tv_usec);

		xorshift64star();
		xorshift64star();
		xorshift64star();

		for (int i = 0; i < depth; i++) {
			for (int j = 0; j < width / 4; j++) {
				int digit = xorshift64star() & 15;
				std::cout << "0123456789abcdef"[digit];
			}
			std::cout << std::endl;
		}

		exit(0);
	}

	if (optind+2 != argc)
		help(argv[0]);

	// -------------------------------------------------------
	// Load from_hexfile and to_hexfile

	const char *from_hexfile_n = argv[optind];
	ifstream from_hexfile_f(from_hexfile_n);
	vector<vector<bool>> from_hexfile;

	const char *to_hexfile_n = argv[optind+1];
	ifstream to_hexfile_f(to_hexfile_n);
	vector<vector<bool>> to_hexfile;

	string line;

	for (int i = 1; getline(from_hexfile_f, line); i++)
		parse_hexfile_line(from_hexfile_n, i, from_hexfile, line);

	for (int i = 1; getline(to_hexfile_f, line); i++)
		parse_hexfile_line(to_hexfile_n, i, to_hexfile, line);

	if (to_hexfile.size() > 0 && from_hexfile.size() > to_hexfile.size()) {
		if (verbose)
			fprintf(stderr, "Padding to_hexfile from %d words to %d\n",
				int(to_hexfile.size()), int(from_hexfile.size()));
		do
			to_hexfile.push_back(vector<bool>(to_hexfile.at(0).size()));
		while (from_hexfile.size() > to_hexfile.size());
	}

	if (from_hexfile.size() != to_hexfile.size()) {
		fprintf(stderr, "Hexfiles have different number of words! (%d vs. %d)\n", int(from_hexfile.size()), int(to_hexfile.size()));
		exit(1);
	}

	if (from_hexfile.size() % 256 != 0) {
		fprintf(stderr, "Hexfile number of words (%d) is not divisible by 256!\n", int(from_hexfile.size()));
		exit(1);
	}

	for (size_t i = 1; i < from_hexfile.size(); i++)
		if (from_hexfile.at(i-1).size() != from_hexfile.at(i).size()) {
			fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i), from_hexfile_n);
			exit(1);
		}

	for (size_t i = 1; i < to_hexfile.size(); i++) {
		while (to_hexfile.at(i-1).size() > to_hexfile.at(i).size())
			to_hexfile.at(i).push_back(false);
		if (to_hexfile.at(i-1).size() != to_hexfile.at(i).size()) {
			fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i+1), to_hexfile_n);
			exit(1);
		}
	}

	if (from_hexfile.size() == 0 || from_hexfile.at(0).size() == 0) {
		fprintf(stderr, "Empty from/to hexfiles!\n");
		exit(1);
	}

	if (verbose)
		fprintf(stderr, "Loaded pattern for %d bits wide and %d words deep memory.\n", int(from_hexfile.at(0).size()), int(from_hexfile.size()));

	// -------------------------------------------------------
	// Create bitslices from pattern data

	map<vector<bool>, pair<vector<bool>, int>> pattern;

	for (int i = 0; i < int(from_hexfile.at(0).size()); i++)
	{
		vector<bool> pattern_from, pattern_to;

		for (int j = 0; j < int(from_hexfile.size()); j++)
		{
			pattern_from.push_back(from_hexfile.at(j).at(i));
			pattern_to.push_back(to_hexfile.at(j).at(i));

			if (pattern_from.size() == 256) {
				if (pattern.count(pattern_from)) {
					fprintf(stderr, "Conflicting from pattern for bit slice from_hexfile[%d:%d][%d]!\n", j, j-255, i);
					exit(1);
				}
				pattern[pattern_from] = std::make_pair(pattern_to, 0);
				pattern_from.clear(), pattern_to.clear();
			}
		}

		assert(pattern_from.empty());
		assert(pattern_to.empty());
	}

	if (verbose)
		fprintf(stderr, "Extracted %d bit slices from from/to hexfile data.\n", int(pattern.size()));

	// -------------------------------------------------------
	// Read ascfile from stdin

	vector<string> ascfile_lines;
	map<string, vector<vector<bool>>> ascfile_hexdata;

	for (int i = 1; getline(std::cin, line); i++)
	{
	next_asc_stmt:
		ascfile_lines.push_back(line);

		if (line.substr(0, 9) == ".ram_data")
		{
			auto &hexdata = ascfile_hexdata[line];

			for (; getline(std::cin, line); i++) {
				if (line.substr(0, 1) == ".")
					goto next_asc_stmt;
				parse_hexfile_line("stdin", i, hexdata, line);
			}
		}
	}

	if (verbose)
		fprintf(stderr, "Found %d initialized bram cells in asc file.\n", int(ascfile_hexdata.size()));

	// -------------------------------------------------------
	// Replace bram data

	int max_replace_cnt = 0;

	for (auto &bram_it : ascfile_hexdata)
	{
		auto &bram_data = bram_it.second;

		for (int i = 0; i < 16; i++)
		{
			vector<bool> from_bitslice;

			for (int j = 0; j < 256; j++)
				from_bitslice.push_back(bram_data.at(j / 16).at(16 * (j % 16) + i));

			auto p = pattern.find(from_bitslice);
			if (p != pattern.end())
			{
				auto &to_bitslice = p->second.first;

				for (int j = 0; j < 256; j++)
					bram_data.at(j / 16).at(16 * (j % 16) + i) = to_bitslice.at(j);

				max_replace_cnt = std::max(++p->second.second, max_replace_cnt);
			}
		}
	}

	int min_replace_cnt = max_replace_cnt;
	for (auto &it : pattern)
		min_replace_cnt = std::min(min_replace_cnt, it.second.second);

	if (min_replace_cnt != max_replace_cnt) {
		fprintf(stderr, "Found some bitslices up to %d times, others only %d times!\n", max_replace_cnt, min_replace_cnt);
		exit(1);
	}

	if (verbose)
		fprintf(stderr, "Found and replaced %d instances of the memory.\n", max_replace_cnt);

	// -------------------------------------------------------
	// Write ascfile to stdout

	for (size_t i = 0; i < ascfile_lines.size(); i++) {
		auto &line = ascfile_lines.at(i);
		std::cout << line << std::endl;
		if (ascfile_hexdata.count(line)) {
			for (auto &word : ascfile_hexdata.at(line)) {
				for (int k = word.size()-4; k >= 0; k -= 4) {
					int digit = (word[k+3] ? 8 : 0) + (word[k+2] ? 4 : 0) + (word[k+1] ? 2 : 0) + (word[k] ? 1 : 0);
					std::cout << "0123456789abcdef"[digit];
				}
				std::cout << std::endl;
			}
		}
	}

	return 0;
}
<|endoftext|>


<commit_before>// @(#)root/memstat:$Id$
// Author: Anar Manafov (A.Manafov@gsi.de) 2008-03-02

/*************************************************************************
* Copyright (C) 1995-2010, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/
// STD
#include <cstdlib>
// ROOT
#include "TSystem.h"
#include "TEnv.h"
#include "TError.h"
#include "Riostream.h"
#include "TObject.h"
#include "TFile.h"
#include "TTree.h"
#include "TArrayL64.h"
#include "TH1.h"
#include "TMD5.h"
// Memstat
#include "TMemStatBacktrace.h"
#include "TMemStatMng.h"

using namespace memstat;

ClassImp(TMemStatMng)

TMemStatMng* TMemStatMng::fgInstance = NULL;

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

TMemStatMng::TMemStatMng():
   TObject(),
#if !defined(__APPLE__)
   fPreviousMallocHook(TMemStatHook::GetMallocHook()),
   fPreviousFreeHook(TMemStatHook::GetFreeHook()),
#endif
   fDumpTree(NULL),
   fUseGNUBuiltinBacktrace(kFALSE),
   fBeginTime(0),
   fPos(0),
   fTimems(0),
   fNBytes(0),
   fN(0),
   fBtID(0),
   fBTCount(0)
{
   // Default constructor
}

//______________________________________________________________________________
void TMemStatMng::Init()
{
   //Initialize MemStat manager - used only by instance method

   fBeginTime = fTimeStamp.AsDouble();

   //fDumpFile = new TFile(Form("yams_%d.root", gSystem->GetPid()), "recreate");
   fDumpFile = new TFile(g_cszFileName, "recreate");
   Int_t opt = 200000;
   if(!fDumpTree) {
      fDumpTree = new TTree("T", "Memory Statistics");
      fDumpTree->Branch("pos",   &fPos,   "pos/l", opt);
      fDumpTree->Branch("time",  &fTimems, "time/I", opt);
      fDumpTree->Branch("nbytes", &fNBytes, "nbytes/I", opt);
      fDumpTree->Branch("btid",  &fBtID,  "btid/I", opt);
   }

   fBTCount = 0;

   fBTIDCount = 0;

   fFAddrsList = new TObjArray();
   fFAddrsList->SetOwner(kTRUE);

   fHbtids  = new TH1I("btids", "table of btids", 10000, 0, 1);   //where fHbtids is a member of the manager class
   fHbtids->SetDirectory(0);
    // save the histogram to a tree header
   fDumpTree->GetUserInfo()->Add(fHbtids);
}

//______________________________________________________________________________
TMemStatMng* TMemStatMng::GetInstance()
{
   // GetInstance - a static function
   // Initialize a singleton of MemStat manager

   if(!fgInstance) {
      fgInstance = new TMemStatMng;
      fgInstance->Init();
   }
   return fgInstance;
}

//______________________________________________________________________________
void TMemStatMng::Close()
{
   // Close - a static function
   // This method stops the manager,
   // flashes all the buffered data and closes the output tree.

   // TODO: This is a temporary solution until we find a properalgorithm for SaveData
   fgInstance->fDumpFile->WriteObject(fgInstance->fFAddrsList, "FAddrsList");

   // to be documented
   fgInstance->fDumpTree->AutoSave();

   delete fgInstance->fFAddrsList;

   delete fgInstance;
   fgInstance = NULL;
}

//______________________________________________________________________________
TMemStatMng::~TMemStatMng()
{
   // if an instance is destructed - the hooks are reseted to old hooks

   if(this != TMemStatMng::GetInstance())
      return;

   Info("~TMemStatMng", ">>> All free/malloc calls count: %d", fBTIDCount);
   Info("~TMemStatMng", ">>> Unique BTIDs count: %zu", fBTChecksums.size());

   Disable();
}

//______________________________________________________________________________
void TMemStatMng::Enable()
{
   // Enable memory hooks

   if(this != GetInstance())
      return;
#if defined(__APPLE__)
   TMemStatHook::trackZoneMalloc(MacAllocHook, MacFreeHook);
#else
   // set hook to our functions
   TMemStatHook::SetMallocHook(AllocHook);
   TMemStatHook::SetFreeHook(FreeHook);
#endif
}

//______________________________________________________________________________
void TMemStatMng::Disable()
{
   // Disble memory hooks

   if(this != GetInstance())
      return;
#if defined(__APPLE__)
   TMemStatHook::untrackZoneMalloc();
#else
   // set hook to our functions
   TMemStatHook::SetMallocHook(fPreviousMallocHook);
   TMemStatHook::SetFreeHook(fPreviousFreeHook);
#endif
}

//______________________________________________________________________________
void TMemStatMng::MacAllocHook(void *ptr, size_t size)
{
   // AllocHook - a static function
   // a special memory hook for Mac OS X memory zones.
   // Triggered when memory is allocated.

   TMemStatMng* instance = TMemStatMng::GetInstance();
   // Restore all old hooks
   instance->Disable();

   // Call our routine
   instance->AddPointer(ptr, Int_t(size));

   // Restore our own hooks
   instance->Enable();
}

//______________________________________________________________________________
void TMemStatMng::MacFreeHook(void *ptr)
{
   // AllocHook - a static function
   // a special memory hook for Mac OS X memory zones.
   // Triggered when memory is deallocated.

   TMemStatMng* instance = TMemStatMng::GetInstance();
   // Restore all old hooks
   instance->Disable();

   // Call our routine
   instance->AddPointer(ptr, -1);

   // Restore our own hooks
   instance->Enable();
}

//______________________________________________________________________________
void *TMemStatMng::AllocHook(size_t size, const void* /*caller*/)
{
   // AllocHook - a static function
   // A glibc memory allocation hook.

   TMemStatMng* instance = TMemStatMng::GetInstance();
   // Restore all old hooks
   instance->Disable();

   // Call recursively
   void *result = malloc(size);
   // Call our routine
   instance->AddPointer(result, Int_t(size));
   //  TTimer::SingleShot(0, "TYamsMemMng", instance, "SaveData()");

   // Restore our own hooks
   instance->Enable();

   return result;
}

//______________________________________________________________________________
void TMemStatMng::FreeHook(void* ptr, const void* /*caller*/)
{
   // FreeHook - a static function
   // A glibc memory deallocation hook.

   TMemStatMng* instance = TMemStatMng::GetInstance();
   // Restore all old hooks
   instance->Disable();

   // Call recursively
   free(ptr);

   // Call our routine
   instance->AddPointer(ptr, -1);

   // Restore our own hooks
   instance->Enable();
}

//______________________________________________________________________________
void TMemStatMng::AddPointer(void *ptr, Int_t size)
{
   // Add pointer to table.
   // This method is called every time when any of the hooks are triggered.
   // The memory de-/allocation information will is recorded.

   void *stptr[g_BTStackLevel + 1];
   const int stackentries = getBacktrace(stptr, g_BTStackLevel, fUseGNUBuiltinBacktrace);

   // save only unique BTs
   TMD5 md5;
   md5.Update(reinterpret_cast<UChar_t*>(stptr), sizeof(void*) * stackentries);
   md5.Final();
   string crc_digest(md5.AsString());

   // for Debug. A counter of all (de)allacations.
   ++fBTIDCount;

   CRCSet_t::const_iterator found = fBTChecksums.find(crc_digest);
   // TODO: define a proper default value
   Int_t btid = -1;
   if(fBTChecksums.end() == found) {

      // check the size of the BT array container
      const int nbins = fHbtids->GetNbinsX();
      //check that the current allocation in fHbtids is enough, otherwise expend it with
      if(fBTCount + stackentries + 1 >= nbins) {
         fHbtids->SetBins(nbins * 2, 0, 1);
      }

      int *btids = fHbtids->GetArray();
      // A first value is a number of entries in a given stack
      btids[fBTCount++] = stackentries;
      btid = fBTCount;
      if(stackentries <= 0) {
         Warning("AddPointer",
                 "A number of stack entries is equal or less than zero. For btid %d", btid);
      }

      // add new BT's CRC value
      pair<CRCSet_t::iterator, bool> res = fBTChecksums.insert(CRCSet_t::value_type(crc_digest, btid));
      if(!res.second)
         Error("AddPointer", "Can't added a new BTID to the container.");

      // save all symbols of this BT
      for(int i = 0; i < stackentries; ++i) {
         pointer_t func_addr = reinterpret_cast<pointer_t>(stptr[i]);

         Int_t idx = fFAddrs.find(func_addr);
         // check, whether it's a new symbol
         if(idx < 0) {
            TString strFuncAddr;
            strFuncAddr += func_addr;
            TString strSymbolInfo;
            getSymbolFullInfo(stptr[i], &strSymbolInfo);

            TNamed *nm = new TNamed(strFuncAddr, strSymbolInfo);
            fFAddrsList->Add(nm);
            idx = fFAddrsList->GetSize() - 1;
            // TODO: more detailed error message...
            if(!fFAddrs.add(func_addr, idx))
               Error("AddPointer", "Can't add a function return address to the container");
         }

         //TODO: in the error code prtint the address.
         // Acutally there must not be a case, when we can't find an index
         if(idx < 0)
            Error("AddPointer", "There is no index for a given BT function return address.");
         // even if we have -1 as an index we add it to the container
         btids[fBTCount++] = idx;
      }

   } else {
      // reuse an existing BT
      btid = found->second;
   }

   if(btid <= 0)
      Error("AddPointer", "bad BT id");

   fTimeStamp.Set();
   Double_t CurTime = fTimeStamp.AsDouble();
   fTimems = Int_t(10000.*(CurTime - fBeginTime));
   fPos    =  reinterpret_cast<pointer_t>(ptr);
   fNBytes = size;
   fN      = 0;
   fBtID   = btid;
   fDumpTree->Fill();
}

<commit_msg>removed a legacy code<commit_after>// @(#)root/memstat:$Id$
// Author: Anar Manafov (A.Manafov@gsi.de) 2008-03-02

/*************************************************************************
* Copyright (C) 1995-2010, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/
// STD
#include <cstdlib>
// ROOT
#include "TSystem.h"
#include "TEnv.h"
#include "TError.h"
#include "Riostream.h"
#include "TObject.h"
#include "TFile.h"
#include "TTree.h"
#include "TArrayL64.h"
#include "TH1.h"
#include "TMD5.h"
// Memstat
#include "TMemStatBacktrace.h"
#include "TMemStatMng.h"

using namespace memstat;

ClassImp(TMemStatMng)

TMemStatMng* TMemStatMng::fgInstance = NULL;

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

TMemStatMng::TMemStatMng():
   TObject(),
#if !defined(__APPLE__)
   fPreviousMallocHook(TMemStatHook::GetMallocHook()),
   fPreviousFreeHook(TMemStatHook::GetFreeHook()),
#endif
   fDumpTree(NULL),
   fUseGNUBuiltinBacktrace(kFALSE),
   fBeginTime(0),
   fPos(0),
   fTimems(0),
   fNBytes(0),
   fN(0),
   fBtID(0),
   fBTCount(0)
{
   // Default constructor
}

//______________________________________________________________________________
void TMemStatMng::Init()
{
   //Initialize MemStat manager - used only by instance method

   fBeginTime = fTimeStamp.AsDouble();

   //fDumpFile = new TFile(Form("yams_%d.root", gSystem->GetPid()), "recreate");
   fDumpFile = new TFile(g_cszFileName, "recreate");
   Int_t opt = 200000;
   if(!fDumpTree) {
      fDumpTree = new TTree("T", "Memory Statistics");
      fDumpTree->Branch("pos",   &fPos,   "pos/l", opt);
      fDumpTree->Branch("time",  &fTimems, "time/I", opt);
      fDumpTree->Branch("nbytes", &fNBytes, "nbytes/I", opt);
      fDumpTree->Branch("btid",  &fBtID,  "btid/I", opt);
   }

   fBTCount = 0;

   fBTIDCount = 0;

   fFAddrsList = new TObjArray();
   fFAddrsList->SetOwner(kTRUE);

   fHbtids  = new TH1I("btids", "table of btids", 10000, 0, 1);   //where fHbtids is a member of the manager class
   fHbtids->SetDirectory(0);
   // save the histogram to a tree header
   fDumpTree->GetUserInfo()->Add(fHbtids);
}

//______________________________________________________________________________
TMemStatMng* TMemStatMng::GetInstance()
{
   // GetInstance - a static function
   // Initialize a singleton of MemStat manager

   if(!fgInstance) {
      fgInstance = new TMemStatMng;
      fgInstance->Init();
   }
   return fgInstance;
}

//______________________________________________________________________________
void TMemStatMng::Close()
{
   // Close - a static function
   // This method stops the manager,
   // flashes all the buffered data and closes the output tree.

   // TODO: This is a temporary solution until we find a properalgorithm for SaveData
   fgInstance->fDumpFile->WriteObject(fgInstance->fFAddrsList, "FAddrsList");

   // to be documented
   fgInstance->fDumpTree->AutoSave();

   delete fgInstance->fFAddrsList;

   delete fgInstance;
   fgInstance = NULL;
}

//______________________________________________________________________________
TMemStatMng::~TMemStatMng()
{
   // if an instance is destructed - the hooks are reseted to old hooks

   if(this != TMemStatMng::GetInstance())
      return;

   Info("~TMemStatMng", ">>> All free/malloc calls count: %d", fBTIDCount);
   Info("~TMemStatMng", ">>> Unique BTIDs count: %zu", fBTChecksums.size());

   Disable();
}

//______________________________________________________________________________
void TMemStatMng::Enable()
{
   // Enable memory hooks

   if(this != GetInstance())
      return;
#if defined(__APPLE__)
   TMemStatHook::trackZoneMalloc(MacAllocHook, MacFreeHook);
#else
   // set hook to our functions
   TMemStatHook::SetMallocHook(AllocHook);
   TMemStatHook::SetFreeHook(FreeHook);
#endif
}

//______________________________________________________________________________
void TMemStatMng::Disable()
{
   // Disble memory hooks

   if(this != GetInstance())
      return;
#if defined(__APPLE__)
   TMemStatHook::untrackZoneMalloc();
#else
   // set hook to our functions
   TMemStatHook::SetMallocHook(fPreviousMallocHook);
   TMemStatHook::SetFreeHook(fPreviousFreeHook);
#endif
}

//______________________________________________________________________________
void TMemStatMng::MacAllocHook(void *ptr, size_t size)
{
   // AllocHook - a static function
   // a special memory hook for Mac OS X memory zones.
   // Triggered when memory is allocated.

   TMemStatMng* instance = TMemStatMng::GetInstance();
   // Restore all old hooks
   instance->Disable();

   // Call our routine
   instance->AddPointer(ptr, Int_t(size));

   // Restore our own hooks
   instance->Enable();
}

//______________________________________________________________________________
void TMemStatMng::MacFreeHook(void *ptr)
{
   // AllocHook - a static function
   // a special memory hook for Mac OS X memory zones.
   // Triggered when memory is deallocated.

   TMemStatMng* instance = TMemStatMng::GetInstance();
   // Restore all old hooks
   instance->Disable();

   // Call our routine
   instance->AddPointer(ptr, -1);

   // Restore our own hooks
   instance->Enable();
}

//______________________________________________________________________________
void *TMemStatMng::AllocHook(size_t size, const void* /*caller*/)
{
   // AllocHook - a static function
   // A glibc memory allocation hook.

   TMemStatMng* instance = TMemStatMng::GetInstance();
   // Restore all old hooks
   instance->Disable();

   // Call recursively
   void *result = malloc(size);
   // Call our routine
   instance->AddPointer(result, Int_t(size));
   //  TTimer::SingleShot(0, "TYamsMemMng", instance, "SaveData()");

   // Restore our own hooks
   instance->Enable();

   return result;
}

//______________________________________________________________________________
void TMemStatMng::FreeHook(void* ptr, const void* /*caller*/)
{
   // FreeHook - a static function
   // A glibc memory deallocation hook.

   TMemStatMng* instance = TMemStatMng::GetInstance();
   // Restore all old hooks
   instance->Disable();

   // Call recursively
   free(ptr);

   // Call our routine
   instance->AddPointer(ptr, -1);

   // Restore our own hooks
   instance->Enable();
}

//______________________________________________________________________________
void TMemStatMng::AddPointer(void *ptr, Int_t size)
{
   // Add pointer to table.
   // This method is called every time when any of the hooks are triggered.
   // The memory de-/allocation information will is recorded.

   void *stptr[g_BTStackLevel + 1];
   const int stackentries = getBacktrace(stptr, g_BTStackLevel, fUseGNUBuiltinBacktrace);

   // save only unique BTs
   TMD5 md5;
   md5.Update(reinterpret_cast<UChar_t*>(stptr), sizeof(void*) * stackentries);
   md5.Final();
   string crc_digest(md5.AsString());

   // for Debug. A counter of all (de)allacations.
   ++fBTIDCount;

   CRCSet_t::const_iterator found = fBTChecksums.find(crc_digest);
   // TODO: define a proper default value
   Int_t btid = -1;
   if(fBTChecksums.end() == found) {

      // check the size of the BT array container
      const int nbins = fHbtids->GetNbinsX();
      //check that the current allocation in fHbtids is enough, otherwise expend it with
      if(fBTCount + stackentries + 1 >= nbins) {
         fHbtids->SetBins(nbins * 2, 0, 1);
      }

      int *btids = fHbtids->GetArray();
      // A first value is a number of entries in a given stack
      btids[fBTCount++] = stackentries;
      btid = fBTCount;
      if(stackentries <= 0) {
         Warning("AddPointer",
                 "A number of stack entries is equal or less than zero. For btid %d", btid);
      }

      // add new BT's CRC value
      pair<CRCSet_t::iterator, bool> res = fBTChecksums.insert(CRCSet_t::value_type(crc_digest, btid));
      if(!res.second)
         Error("AddPointer", "Can't added a new BTID to the container.");

      // save all symbols of this BT
      for(int i = 0; i < stackentries; ++i) {
         pointer_t func_addr = reinterpret_cast<pointer_t>(stptr[i]);

         Int_t idx = fFAddrs.find(func_addr);
         // check, whether it's a new symbol
         if(idx < 0) {
            TString strFuncAddr;
            strFuncAddr += func_addr;
            TString strSymbolInfo;
            getSymbolFullInfo(stptr[i], &strSymbolInfo);

            TNamed *nm = new TNamed(strFuncAddr, strSymbolInfo);
            fFAddrsList->Add(nm);
            idx = fFAddrsList->GetSize() - 1;
            // TODO: more detailed error message...
            if(!fFAddrs.add(func_addr, idx))
               Error("AddPointer", "Can't add a function return address to the container");
         }

         // even if we have -1 as an index we add it to the container
         btids[fBTCount++] = idx;
      }

   } else {
      // reuse an existing BT
      btid = found->second;
   }

   if(btid <= 0)
      Error("AddPointer", "bad BT id");

   fTimeStamp.Set();
   Double_t CurTime = fTimeStamp.AsDouble();
   fTimems = Int_t(10000.*(CurTime - fBeginTime));
   fPos    =  reinterpret_cast<pointer_t>(ptr);
   fNBytes = size;
   fN      = 0;
   fBtID   = btid;
   fDumpTree->Fill();
}

<|endoftext|>


<commit_before>#ifndef MJOLNIR_LOCAL_FORCE_FIELD
#define MJOLNIR_LOCAL_FORCE_FIELD
#include "LocalInteractionBase.hpp"
#include <utility>
#include <vector>
#include <array>
#include <memory>

namespace mjolnir
{

template<typename traitsT>
class LocalForceField
{
  public:
    typedef traitsT traits_type;
    typedef typename traits_type::time_type       time_type;
    typedef typename traits_type::real_type       real_type;
    typedef typename traits_type::coordinate_type coordinate_type;
    typedef Particle<coordinate_type>             particle_type;
    typedef ParticleContainer<traits_type>        particle_container_type;
    typedef LocalInteractionBase<traitsT>         interaction_type;
    typedef std::unique_ptr<interaction_type>     interaction_ptr;
    typedef std::vector<interaction_ptr>          container_type;

  public:

    LocalForceField() = default;
    ~LocalForceField() = default;
    LocalForceField(LocalForceField const&) = delete;
    LocalForceField(LocalForceField&&)      = default;
    LocalForceField& operator=(LocalForceField const&) = delete;
    LocalForceField& operator=(LocalForceField&&)      = default;

    void emplace(interaction_ptr&& interaction);

    void      calc_force(particle_container_type& pcon);
    real_type calc_energy(const particle_container_type& pcon) const;

    void reset_parameter(const std::string&, const real_type);

  private:

    container_type interactions_;
};

template<typename traitsT>
inline void LocalForceField<traitsT>::emplace(
        interaction_ptr&& interaction)
{
    interactions_.emplace_back(std::forward<interaction_ptr>(interaction));
    return;
}

template<typename traitsT>
void LocalForceField<traitsT>::calc_force(particle_container_type& pcon)
{
    for(auto iter = interactions_.cbegin(); iter != interactions_.cend(); ++iter)
        (*iter)->calc_force(pcon);
    return;
}

template<typename traitsT>
typename LocalForceField<traitsT>::real_type
LocalForceField<traitsT>::calc_energy(const particle_container_type& pcon) const
{
    real_type energy = 0.0;
    for(auto iter = interactions_.cbegin(); iter != interactions_.cend(); ++iter)
        energy += (*iter)->calc_energy(pcon);
    return energy;
}

template<typename traitsT>
void LocalForceField<traitsT>::reset_parameter(
        const std::string& name, const real_type val)
{
    for(auto iter = interactions_.begin(); iter != interactions_.end(); ++iter)
        (*iter)->reset_parameter(name, val);
    return;
}

} // mjolnir
#endif /* MJOLNIR_LOCAL_FORCE_FIELD */
<commit_msg>add LOG output to LocalForceField<commit_after>#ifndef MJOLNIR_LOCAL_FORCE_FIELD
#define MJOLNIR_LOCAL_FORCE_FIELD
#include "LocalInteractionBase.hpp"
#include <mjolnir/util/logger.hpp>
#include <utility>
#include <vector>
#include <array>
#include <memory>

namespace mjolnir
{

template<typename traitsT>
class LocalForceField
{
  public:
    typedef traitsT traits_type;
    typedef typename traits_type::time_type       time_type;
    typedef typename traits_type::real_type       real_type;
    typedef typename traits_type::coordinate_type coordinate_type;
    typedef Particle<coordinate_type>             particle_type;
    typedef ParticleContainer<traits_type>        particle_container_type;
    typedef LocalInteractionBase<traitsT>         interaction_type;
    typedef std::unique_ptr<interaction_type>     interaction_ptr;
    typedef std::vector<interaction_ptr>          container_type;

  public:

    LocalForceField() = default;
    ~LocalForceField() = default;
    LocalForceField(LocalForceField const&) = delete;
    LocalForceField(LocalForceField&&)      = default;
    LocalForceField& operator=(LocalForceField const&) = delete;
    LocalForceField& operator=(LocalForceField&&)      = default;

    void emplace(interaction_ptr&& interaction);

    void      calc_force(particle_container_type& pcon);
    real_type calc_energy(const particle_container_type& pcon) const;

    void reset_parameter(const std::string&, const real_type);

  private:

    container_type interactions_;
    static
    Logger& logger_;
};

template<typename traitsT>
Logger& LocalForceField<traitsT>::logger_ =
    LoggerManager<char>::get_logger("LocalForceField");

template<typename traitsT>
inline void LocalForceField<traitsT>::emplace(
        interaction_ptr&& interaction)
{
    interactions_.emplace_back(std::forward<interaction_ptr>(interaction));
    return;
}

template<typename traitsT>
void LocalForceField<traitsT>::calc_force(particle_container_type& pcon)
{
    for(auto iter = interactions_.cbegin(); iter != interactions_.cend(); ++iter)
        (*iter)->calc_force(pcon);
    return;
}

template<typename traitsT>
typename LocalForceField<traitsT>::real_type
LocalForceField<traitsT>::calc_energy(const particle_container_type& pcon) const
{
    real_type energy = 0.0;
    for(auto iter = interactions_.cbegin(); iter != interactions_.cend(); ++iter)
    {
        const real_type e = (*iter)->calc_energy(pcon);
        MJOLNIR_LOG_DEBUG("calculate energy", e);
        energy += e;
    }
    return energy;
}

template<typename traitsT>
void LocalForceField<traitsT>::reset_parameter(
        const std::string& name, const real_type val)
{
    for(auto iter = interactions_.begin(); iter != interactions_.end(); ++iter)
        (*iter)->reset_parameter(name, val);
    return;
}

} // mjolnir
#endif /* MJOLNIR_LOCAL_FORCE_FIELD */
<|endoftext|>


<commit_before>#ifndef MJOLNIR_DEFAULT_TRAITS
#define MJOLNIR_DEFAULT_TRAITS
#include <mjolnir/math/Vector.hpp>

namespace mjolnir
{

template<typename realT, typename boundaryT>
struct SimulatorTraitsBase
{
    typedef realT                real_type;
    typedef Vector<real_type, 3> coordinate_type;
    typedef coordinate_type      position_type;
    typedef boundaryT            boundary_type;
};

} // mjolnir
#endif /* MJOLNIR_DEFAULT_TRAITS */
<commit_msg>assume number of template argument of boundary_type<commit_after>#ifndef MJOLNIR_DEFAULT_TRAITS
#define MJOLNIR_DEFAULT_TRAITS
#include <mjolnir/math/Vector.hpp>

namespace mjolnir
{

template<typename realT, template<typename, typename> class boundaryT>
struct SimulatorTraitsBase
{
    typedef realT                                 real_type;
    typedef Vector<real_type, 3>                  coordinate_type;
    typedef coordinate_type                       position_type;
    typedef boundaryT<real_type, coordinate_type> boundary_type;
};

} // mjolnir
#endif /* MJOLNIR_DEFAULT_TRAITS */
<|endoftext|>


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

#include "content/renderer/gpu/gpu_channel_host.h"

#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "content/common/child_process.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/renderer/gpu/command_buffer_proxy.h"
#include "content/renderer/gpu/transport_texture_service.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_thread.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_sync_message_filter.h"

using base::AutoLock;
using base::MessageLoopProxy;

GpuChannelHost::Listener::Listener(
    base::WeakPtr<IPC::Channel::Listener> listener,
    scoped_refptr<base::MessageLoopProxy> loop)
    : listener_(listener),
      loop_(loop) {

}

GpuChannelHost::Listener::~Listener() {

}

void GpuChannelHost::Listener::DispatchMessage(const IPC::Message& msg) {
  if (listener_.get())
    listener_->OnMessageReceived(msg);
}

void GpuChannelHost::Listener::DispatchError() {
  if (listener_.get())
    listener_->OnChannelError();
}

GpuChannelHost::MessageFilter::MessageFilter(GpuChannelHost* parent)
    : parent_(parent) {
}

GpuChannelHost::MessageFilter::~MessageFilter() {

}

void GpuChannelHost::MessageFilter::AddRoute(
    int route_id,
    base::WeakPtr<IPC::Channel::Listener> listener,
    scoped_refptr<MessageLoopProxy> loop) {
  DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
  DCHECK(listeners_.find(route_id) == listeners_.end());
  listeners_[route_id] = new GpuChannelHost::Listener(listener, loop);
}

void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) {
  DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
  ListenerMap::iterator it = listeners_.find(route_id);
  if (it != listeners_.end())
    listeners_.erase(it);
}

bool GpuChannelHost::MessageFilter::OnMessageReceived(
    const IPC::Message& message) {
  DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
  // Never handle sync message replies or we will deadlock here.
  if (message.is_reply())
    return false;

  DCHECK(message.routing_id() != MSG_ROUTING_CONTROL);

  ListenerMap::iterator it = listeners_.find(message.routing_id());

  if (it != listeners_.end()) {
    const scoped_refptr<GpuChannelHost::Listener>& listener = it->second;
    listener->loop()->PostTask(
        FROM_HERE,
        NewRunnableMethod(
            listener.get(),
            &GpuChannelHost::Listener::DispatchMessage,
            message));
  }

  return true;
}

void GpuChannelHost::MessageFilter::OnChannelError() {
  DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
  // Inform all the proxies that an error has occurred. This will be reported
  // via OpenGL as a lost context.
  for (ListenerMap::iterator it = listeners_.begin();
       it != listeners_.end();
       it++) {
    const scoped_refptr<GpuChannelHost::Listener>& listener = it->second;
    listener->loop()->PostTask(
        FROM_HERE,
        NewRunnableMethod(
            listener.get(),
            &GpuChannelHost::Listener::DispatchError));
  }

  listeners_.clear();

  ChildThread* main_thread = RenderProcess::current()->main_thread();
  MessageLoop* main_loop = main_thread->message_loop();
  main_loop->PostTask(FROM_HERE,
                      NewRunnableMethod(parent_,
                                        &GpuChannelHost::OnChannelError));
}

GpuChannelHost::GpuChannelHost()
    : state_(kUnconnected),
      transport_texture_service_(new TransportTextureService()) {
}

GpuChannelHost::~GpuChannelHost() {
}

void GpuChannelHost::Connect(
    const IPC::ChannelHandle& channel_handle,
    base::ProcessHandle renderer_process_for_gpu) {
  DCHECK(RenderThread::current());
  // Open a channel to the GPU process. We pass NULL as the main listener here
  // since we need to filter everything to route it to the right thread.
  channel_.reset(new IPC::SyncChannel(
      channel_handle, IPC::Channel::MODE_CLIENT, NULL,
      ChildProcess::current()->io_message_loop_proxy(), true,
      ChildProcess::current()->GetShutDownEvent()));

  sync_filter_ = new IPC::SyncMessageFilter(
      ChildProcess::current()->GetShutDownEvent());

  channel_->AddFilter(sync_filter_.get());

  channel_->AddFilter(transport_texture_service_.get());

  channel_filter_ = new MessageFilter(this);

  // Install the filter last, because we intercept all leftover
  // messages.
  channel_->AddFilter(channel_filter_.get());

  // It is safe to send IPC messages before the channel completes the connection
  // and receives the hello message from the GPU process. The messages get
  // cached.
  state_ = kConnected;

  // Notify the GPU process of our process handle. This gives it the ability
  // to map renderer handles into the GPU process.
  Send(new GpuChannelMsg_Initialize(renderer_process_for_gpu));
}

void GpuChannelHost::set_gpu_info(const GPUInfo& gpu_info) {
  gpu_info_ = gpu_info;
}

const GPUInfo& GpuChannelHost::gpu_info() const {
  return gpu_info_;
}

void GpuChannelHost::SetStateLost() {
  state_ = kLost;
}

void GpuChannelHost::OnChannelError() {
  state_ = kLost;

  // Channel is invalid and will be reinitialized if this host is requested
  // again.
  channel_.reset();
}

bool GpuChannelHost::Send(IPC::Message* message) {
  // The GPU process never sends synchronous IPCs so clear the unblock flag to
  // preserve order.
  message->set_unblock(false);

  // Unfortunately a sync filter cannot be used on the main (listener) thread.
  // TODO: Is that true even when we don't install a listener?
  if (RenderThread::current()) {
    if (channel_.get())
      return channel_->Send(message);
  } else {
    return sync_filter_->Send(message);
  }

  // Callee takes ownership of message, regardless of whether Send is
  // successful. See IPC::Message::Sender.
  delete message;
  return false;
}

CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer(
    int render_view_id,
    CommandBufferProxy* share_group,
    const std::string& allowed_extensions,
    const std::vector<int32>& attribs,
    const GURL& active_url) {
#if defined(ENABLE_GPU)
  AutoLock lock(context_lock_);
  // An error occurred. Need to get the host again to reinitialize it.
  if (!channel_.get())
    return NULL;

  GPUCreateCommandBufferConfig init_params;
  init_params.share_group_id =
      share_group ? share_group->route_id() : MSG_ROUTING_NONE;
  init_params.allowed_extensions = allowed_extensions;
  init_params.attribs = attribs;
  init_params.active_url = active_url;
  int32 route_id;
  if (!RenderThread::current()->Send(
      new GpuHostMsg_CreateViewCommandBuffer(
          render_view_id,
          init_params,
          &route_id))) {
    return NULL;
  }

  if (route_id == MSG_ROUTING_NONE)
    return NULL;

  CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id);
  AddRoute(route_id, command_buffer->AsWeakPtr());
  proxies_[route_id] = command_buffer;
  return command_buffer;
#else
  return NULL;
#endif
}

GpuVideoDecodeAcceleratorHost* GpuChannelHost::CreateVideoDecoder(
    int command_buffer_route_id,
    media::VideoDecodeAccelerator::Profile profile,
    media::VideoDecodeAccelerator::Client* client) {
  AutoLock lock(context_lock_);
  ProxyMap::iterator it = proxies_.find(command_buffer_route_id);
  DCHECK(it != proxies_.end());
  CommandBufferProxy* proxy = it->second;
  return proxy->CreateVideoDecoder(profile, client);
}

CommandBufferProxy* GpuChannelHost::CreateOffscreenCommandBuffer(
    const gfx::Size& size,
    CommandBufferProxy* share_group,
    const std::string& allowed_extensions,
    const std::vector<int32>& attribs,
    const GURL& active_url) {
#if defined(ENABLE_GPU)
  AutoLock lock(context_lock_);
  // An error occurred. Need to get the host again to reinitialize it.
  if (!channel_.get())
    return NULL;

  GPUCreateCommandBufferConfig init_params;
  init_params.share_group_id =
      share_group ? share_group->route_id() : MSG_ROUTING_NONE;
  init_params.allowed_extensions = allowed_extensions;
  init_params.attribs = attribs;
  init_params.active_url = active_url;
  int32 route_id;
  if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size,
                                                           init_params,
                                                           &route_id))) {
    return NULL;
  }

  if (route_id == MSG_ROUTING_NONE)
    return NULL;

  CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id);
  AddRoute(route_id, command_buffer->AsWeakPtr());
  proxies_[route_id] = command_buffer;
  return command_buffer;
#else
  return NULL;
#endif
}

void GpuChannelHost::DestroyCommandBuffer(CommandBufferProxy* command_buffer) {
#if defined(ENABLE_GPU)
  AutoLock lock(context_lock_);
  Send(new GpuChannelMsg_DestroyCommandBuffer(command_buffer->route_id()));

  // Check the proxy has not already been removed after a channel error.
  int route_id = command_buffer->route_id();
  if (proxies_.find(command_buffer->route_id()) != proxies_.end())
    proxies_.erase(route_id);
  RemoveRoute(route_id);
  delete command_buffer;
#endif
}

void GpuChannelHost::AddRoute(
    int route_id, base::WeakPtr<IPC::Channel::Listener> listener) {
  DCHECK(MessageLoopProxy::current());

  MessageLoopProxy* io_loop = RenderProcess::current()->io_message_loop_proxy();
  io_loop->PostTask(FROM_HERE,
                    NewRunnableMethod(
                        channel_filter_.get(),
                        &GpuChannelHost::MessageFilter::AddRoute,
                        route_id, listener, MessageLoopProxy::current()));
}

void GpuChannelHost::RemoveRoute(int route_id) {
  MessageLoopProxy* io_loop = RenderProcess::current()->io_message_loop_proxy();
  io_loop->PostTask(FROM_HERE,
                    NewRunnableMethod(
                        channel_filter_.get(),
                        &GpuChannelHost::MessageFilter::RemoveRoute,
                        route_id));
}
<commit_msg>Fix logic in GpuChannelHost::Send() during shutdown.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/gpu/gpu_channel_host.h"

#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "content/common/child_process.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/renderer/gpu/command_buffer_proxy.h"
#include "content/renderer/gpu/transport_texture_service.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_thread.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_sync_message_filter.h"

using base::AutoLock;
using base::MessageLoopProxy;

GpuChannelHost::Listener::Listener(
    base::WeakPtr<IPC::Channel::Listener> listener,
    scoped_refptr<base::MessageLoopProxy> loop)
    : listener_(listener),
      loop_(loop) {

}

GpuChannelHost::Listener::~Listener() {

}

void GpuChannelHost::Listener::DispatchMessage(const IPC::Message& msg) {
  if (listener_.get())
    listener_->OnMessageReceived(msg);
}

void GpuChannelHost::Listener::DispatchError() {
  if (listener_.get())
    listener_->OnChannelError();
}

GpuChannelHost::MessageFilter::MessageFilter(GpuChannelHost* parent)
    : parent_(parent) {
}

GpuChannelHost::MessageFilter::~MessageFilter() {

}

void GpuChannelHost::MessageFilter::AddRoute(
    int route_id,
    base::WeakPtr<IPC::Channel::Listener> listener,
    scoped_refptr<MessageLoopProxy> loop) {
  DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
  DCHECK(listeners_.find(route_id) == listeners_.end());
  listeners_[route_id] = new GpuChannelHost::Listener(listener, loop);
}

void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) {
  DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
  ListenerMap::iterator it = listeners_.find(route_id);
  if (it != listeners_.end())
    listeners_.erase(it);
}

bool GpuChannelHost::MessageFilter::OnMessageReceived(
    const IPC::Message& message) {
  DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
  // Never handle sync message replies or we will deadlock here.
  if (message.is_reply())
    return false;

  DCHECK(message.routing_id() != MSG_ROUTING_CONTROL);

  ListenerMap::iterator it = listeners_.find(message.routing_id());

  if (it != listeners_.end()) {
    const scoped_refptr<GpuChannelHost::Listener>& listener = it->second;
    listener->loop()->PostTask(
        FROM_HERE,
        NewRunnableMethod(
            listener.get(),
            &GpuChannelHost::Listener::DispatchMessage,
            message));
  }

  return true;
}

void GpuChannelHost::MessageFilter::OnChannelError() {
  DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
  // Inform all the proxies that an error has occurred. This will be reported
  // via OpenGL as a lost context.
  for (ListenerMap::iterator it = listeners_.begin();
       it != listeners_.end();
       it++) {
    const scoped_refptr<GpuChannelHost::Listener>& listener = it->second;
    listener->loop()->PostTask(
        FROM_HERE,
        NewRunnableMethod(
            listener.get(),
            &GpuChannelHost::Listener::DispatchError));
  }

  listeners_.clear();

  ChildThread* main_thread = RenderProcess::current()->main_thread();
  MessageLoop* main_loop = main_thread->message_loop();
  main_loop->PostTask(FROM_HERE,
                      NewRunnableMethod(parent_,
                                        &GpuChannelHost::OnChannelError));
}

GpuChannelHost::GpuChannelHost()
    : state_(kUnconnected),
      transport_texture_service_(new TransportTextureService()) {
}

GpuChannelHost::~GpuChannelHost() {
}

void GpuChannelHost::Connect(
    const IPC::ChannelHandle& channel_handle,
    base::ProcessHandle renderer_process_for_gpu) {
  DCHECK(RenderThread::current());
  // Open a channel to the GPU process. We pass NULL as the main listener here
  // since we need to filter everything to route it to the right thread.
  channel_.reset(new IPC::SyncChannel(
      channel_handle, IPC::Channel::MODE_CLIENT, NULL,
      ChildProcess::current()->io_message_loop_proxy(), true,
      ChildProcess::current()->GetShutDownEvent()));

  sync_filter_ = new IPC::SyncMessageFilter(
      ChildProcess::current()->GetShutDownEvent());

  channel_->AddFilter(sync_filter_.get());

  channel_->AddFilter(transport_texture_service_.get());

  channel_filter_ = new MessageFilter(this);

  // Install the filter last, because we intercept all leftover
  // messages.
  channel_->AddFilter(channel_filter_.get());

  // It is safe to send IPC messages before the channel completes the connection
  // and receives the hello message from the GPU process. The messages get
  // cached.
  state_ = kConnected;

  // Notify the GPU process of our process handle. This gives it the ability
  // to map renderer handles into the GPU process.
  Send(new GpuChannelMsg_Initialize(renderer_process_for_gpu));
}

void GpuChannelHost::set_gpu_info(const GPUInfo& gpu_info) {
  gpu_info_ = gpu_info;
}

const GPUInfo& GpuChannelHost::gpu_info() const {
  return gpu_info_;
}

void GpuChannelHost::SetStateLost() {
  state_ = kLost;
}

void GpuChannelHost::OnChannelError() {
  state_ = kLost;

  // Channel is invalid and will be reinitialized if this host is requested
  // again.
  channel_.reset();
}

bool GpuChannelHost::Send(IPC::Message* message) {
  // The GPU process never sends synchronous IPCs so clear the unblock flag to
  // preserve order.
  message->set_unblock(false);

  // Currently we need to choose between two different mechanisms for sending.
  // On the main thread we use the regular channel Send() method, on another
  // thread we use SyncMessageFilter. We also have to be careful interpreting
  // RenderThread::current() since it might return NULL during shutdown, while
  // we are actually calling from the main thread (discard message then).
  //
  // TODO: Can we just always use sync_filter_ since we setup the channel
  //       without a main listener?
  if (RenderThread::current()) {
    if (channel_.get())
      return channel_->Send(message);
  } else if (MessageLoop::current()) {
    return sync_filter_->Send(message);
  }

  // Callee takes ownership of message, regardless of whether Send is
  // successful. See IPC::Message::Sender.
  delete message;
  return false;
}

CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer(
    int render_view_id,
    CommandBufferProxy* share_group,
    const std::string& allowed_extensions,
    const std::vector<int32>& attribs,
    const GURL& active_url) {
#if defined(ENABLE_GPU)
  AutoLock lock(context_lock_);
  // An error occurred. Need to get the host again to reinitialize it.
  if (!channel_.get())
    return NULL;

  GPUCreateCommandBufferConfig init_params;
  init_params.share_group_id =
      share_group ? share_group->route_id() : MSG_ROUTING_NONE;
  init_params.allowed_extensions = allowed_extensions;
  init_params.attribs = attribs;
  init_params.active_url = active_url;
  int32 route_id;
  if (!RenderThread::current()->Send(
      new GpuHostMsg_CreateViewCommandBuffer(
          render_view_id,
          init_params,
          &route_id))) {
    return NULL;
  }

  if (route_id == MSG_ROUTING_NONE)
    return NULL;

  CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id);
  AddRoute(route_id, command_buffer->AsWeakPtr());
  proxies_[route_id] = command_buffer;
  return command_buffer;
#else
  return NULL;
#endif
}

GpuVideoDecodeAcceleratorHost* GpuChannelHost::CreateVideoDecoder(
    int command_buffer_route_id,
    media::VideoDecodeAccelerator::Profile profile,
    media::VideoDecodeAccelerator::Client* client) {
  AutoLock lock(context_lock_);
  ProxyMap::iterator it = proxies_.find(command_buffer_route_id);
  DCHECK(it != proxies_.end());
  CommandBufferProxy* proxy = it->second;
  return proxy->CreateVideoDecoder(profile, client);
}

CommandBufferProxy* GpuChannelHost::CreateOffscreenCommandBuffer(
    const gfx::Size& size,
    CommandBufferProxy* share_group,
    const std::string& allowed_extensions,
    const std::vector<int32>& attribs,
    const GURL& active_url) {
#if defined(ENABLE_GPU)
  AutoLock lock(context_lock_);
  // An error occurred. Need to get the host again to reinitialize it.
  if (!channel_.get())
    return NULL;

  GPUCreateCommandBufferConfig init_params;
  init_params.share_group_id =
      share_group ? share_group->route_id() : MSG_ROUTING_NONE;
  init_params.allowed_extensions = allowed_extensions;
  init_params.attribs = attribs;
  init_params.active_url = active_url;
  int32 route_id;
  if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size,
                                                           init_params,
                                                           &route_id))) {
    return NULL;
  }

  if (route_id == MSG_ROUTING_NONE)
    return NULL;

  CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id);
  AddRoute(route_id, command_buffer->AsWeakPtr());
  proxies_[route_id] = command_buffer;
  return command_buffer;
#else
  return NULL;
#endif
}

void GpuChannelHost::DestroyCommandBuffer(CommandBufferProxy* command_buffer) {
#if defined(ENABLE_GPU)
  AutoLock lock(context_lock_);
  Send(new GpuChannelMsg_DestroyCommandBuffer(command_buffer->route_id()));

  // Check the proxy has not already been removed after a channel error.
  int route_id = command_buffer->route_id();
  if (proxies_.find(command_buffer->route_id()) != proxies_.end())
    proxies_.erase(route_id);
  RemoveRoute(route_id);
  delete command_buffer;
#endif
}

void GpuChannelHost::AddRoute(
    int route_id, base::WeakPtr<IPC::Channel::Listener> listener) {
  DCHECK(MessageLoopProxy::current());

  MessageLoopProxy* io_loop = RenderProcess::current()->io_message_loop_proxy();
  io_loop->PostTask(FROM_HERE,
                    NewRunnableMethod(
                        channel_filter_.get(),
                        &GpuChannelHost::MessageFilter::AddRoute,
                        route_id, listener, MessageLoopProxy::current()));
}

void GpuChannelHost::RemoveRoute(int route_id) {
  MessageLoopProxy* io_loop = RenderProcess::current()->io_message_loop_proxy();
  io_loop->PostTask(FROM_HERE,
                    NewRunnableMethod(
                        channel_filter_.get(),
                        &GpuChannelHost::MessageFilter::RemoveRoute,
                        route_id));
}
<|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2019 Ryo Suzuki
//	Copyright (c) 2016-2019 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/Camera3D.hpp>
# include <Siv3D/Print.hpp>

namespace s3d::experimental
{
	BasicCamera3D::BasicCamera3D(const Size& sceneSize, const double fov, const Vec3& eyePosition, const Vec3& focusPosition, const Vec3& upDirection) noexcept
		: m_eyePosition(eyePosition)
		, m_focusPosition(focusPosition)
		, m_upDirection(upDirection)
		, m_sceneSize(sceneSize)
		, m_fov(fov)
	{
		updateProj();
		updateView();
		updateViewProj();
	}

	void BasicCamera3D::setProjection(const Size& sceneSize, const double fov, const double nearClip, const double farClip)
	{
		m_sceneSize	= sceneSize;
		m_fov		= fov;
		m_nearClip	= nearClip;
		m_farClip	= farClip;

		updateProj();
		updateViewProj();
	}

	void BasicCamera3D::setView(const Vec3& eyePosition, const Vec3& focusPosition, const Vec3& upDirection) noexcept
	{
		m_eyePosition	= eyePosition;
		m_focusPosition	= focusPosition;
		m_upDirection	= upDirection;

		updateView();
		updateViewProj();
	}

	Float3 BasicCamera3D::worldToScreenPoint(const Float3& pos) const noexcept
	{
		Float3 v = SIMD::Vector3TransformCoord(SIMD_Float4(pos, 0.0f), m_viewProj).xyz();
		v.x += 1.0f;
		v.y += 1.0f;
		v.x *= 0.5f * m_sceneSize.x;
		v.y *= 0.5f;
		v.y = 1.0f - v.y;
		v.y *= m_sceneSize.y;
		return v;
	}

	Float3 BasicCamera3D::screenToWorldPoint(const Float2& pos, float depth) const noexcept
	{
		Float3 v(pos, depth);
		v.x /= (m_sceneSize.x * 0.5f);
		v.y /= (m_sceneSize.y * 0.5f);
		v.x -= 1.0f;
		v.y -= 1.0f;
		v.y *= -1.0f;

		const __m128 worldPos = SIMD::Vector3TransformCoord(SIMD_Float4(v, 0.0f), m_invViewProj);

		Float3 result;
		SIMD::StoreFloat3(&result, worldPos);

		return result;
	}

	Ray BasicCamera3D::screenToRay(const Vec2& pos) const noexcept
	{
		const Vec3 rayEnd = screenToWorldPoint(pos, 0.9f);

		return Ray(m_eyePosition, (rayEnd - m_eyePosition).normalized());
	}

	void BasicCamera3D::updateProj()
	{
		const float aspectRatio	= static_cast<float>(m_sceneSize.x) / m_sceneSize.y;
		const float fov			= static_cast<float>(m_fov);
		const float nearClip	= static_cast<float>(m_nearClip);
		const float farClip		= static_cast<float>(m_farClip);
		m_proj = Mat4x4::PerspectiveFovLH_ZO(fov, aspectRatio, nearClip, farClip);
	}

	void BasicCamera3D::updateView()
	{
		const SIMD_Float4 eyePosition(m_eyePosition, 0.0f);
		const SIMD_Float4 focusPosition(m_focusPosition, 0.0f);
		const SIMD_Float4 upDirection(m_upDirection, 0.0f);
		m_view = Mat4x4::LookAtLH(eyePosition, focusPosition, upDirection);
	}

	void BasicCamera3D::updateViewProj()
	{
		m_viewProj = m_view * m_proj;
		m_invViewProj = m_viewProj.inverse();
	}
}
<commit_msg>fix warning<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2019 Ryo Suzuki
//	Copyright (c) 2016-2019 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/Camera3D.hpp>
# include <Siv3D/Print.hpp>

namespace s3d::experimental
{
	BasicCamera3D::BasicCamera3D(const Size& sceneSize, const double fov, const Vec3& eyePosition, const Vec3& focusPosition, const Vec3& upDirection) noexcept
		: m_sceneSize(sceneSize)
		, m_fov(fov)
		, m_eyePosition(eyePosition)
		, m_focusPosition(focusPosition)
		, m_upDirection(upDirection)
	{
		updateProj();
		updateView();
		updateViewProj();
	}

	void BasicCamera3D::setProjection(const Size& sceneSize, const double fov, const double nearClip, const double farClip)
	{
		m_sceneSize	= sceneSize;
		m_fov		= fov;
		m_nearClip	= nearClip;
		m_farClip	= farClip;

		updateProj();
		updateViewProj();
	}

	void BasicCamera3D::setView(const Vec3& eyePosition, const Vec3& focusPosition, const Vec3& upDirection) noexcept
	{
		m_eyePosition	= eyePosition;
		m_focusPosition	= focusPosition;
		m_upDirection	= upDirection;

		updateView();
		updateViewProj();
	}

	Float3 BasicCamera3D::worldToScreenPoint(const Float3& pos) const noexcept
	{
		Float3 v = SIMD::Vector3TransformCoord(SIMD_Float4(pos, 0.0f), m_viewProj).xyz();
		v.x += 1.0f;
		v.y += 1.0f;
		v.x *= 0.5f * m_sceneSize.x;
		v.y *= 0.5f;
		v.y = 1.0f - v.y;
		v.y *= m_sceneSize.y;
		return v;
	}

	Float3 BasicCamera3D::screenToWorldPoint(const Float2& pos, float depth) const noexcept
	{
		Float3 v(pos, depth);
		v.x /= (m_sceneSize.x * 0.5f);
		v.y /= (m_sceneSize.y * 0.5f);
		v.x -= 1.0f;
		v.y -= 1.0f;
		v.y *= -1.0f;

		const __m128 worldPos = SIMD::Vector3TransformCoord(SIMD_Float4(v, 0.0f), m_invViewProj);

		Float3 result;
		SIMD::StoreFloat3(&result, worldPos);

		return result;
	}

	Ray BasicCamera3D::screenToRay(const Vec2& pos) const noexcept
	{
		const Vec3 rayEnd = screenToWorldPoint(pos, 0.9f);

		return Ray(m_eyePosition, (rayEnd - m_eyePosition).normalized());
	}

	void BasicCamera3D::updateProj()
	{
		const float aspectRatio	= static_cast<float>(m_sceneSize.x) / m_sceneSize.y;
		const float fov			= static_cast<float>(m_fov);
		const float nearClip	= static_cast<float>(m_nearClip);
		const float farClip		= static_cast<float>(m_farClip);
		m_proj = Mat4x4::PerspectiveFovLH_ZO(fov, aspectRatio, nearClip, farClip);
	}

	void BasicCamera3D::updateView()
	{
		const SIMD_Float4 eyePosition(m_eyePosition, 0.0f);
		const SIMD_Float4 focusPosition(m_focusPosition, 0.0f);
		const SIMD_Float4 upDirection(m_upDirection, 0.0f);
		m_view = Mat4x4::LookAtLH(eyePosition, focusPosition, upDirection);
	}

	void BasicCamera3D::updateViewProj()
	{
		m_viewProj = m_view * m_proj;
		m_invViewProj = m_viewProj.inverse();
	}
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <map>
#include <math.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

#include <fj_tool/fapp.h>
#include <fjcoll.h>

using namespace std;

#include "pearson-3d.h"

bool EXTEND_MISSION=false;
int T_MAX;
int T_MONITOR;
int mpi_my_rank;
const double PI=3.14159265358979323846;

float frand() {
  return rand() / float(RAND_MAX);
}

double wctime() {
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return (double)tv.tv_sec + (double)tv.tv_usec*1e-6;
}
/*
  void init() {
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
  for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
  for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
  double x = double(navi.offset_x + ix)/NX;
  double y = double(navi.offset_y + iy)/NY;
  double z = double(navi.offset_z + iz)/NZ;
  U[ix][iy][iz] = 1.0;
  V[ix][iy][iz] = 0.0;
  if (z > 0.49 && z < 0.51 && x > 0.4 && x < 0.6) {
  U[ix][iy][iz] = 0.5;
  V[ix][iy][iz] = 0.25;
  }
  }
  }
  }
  }*/

double gaussian(double x, double y,double z) {
  return exp(- (x*x+y*y+z*z) / 25.0);
}

typedef pair<int,pair<int,int> > Key;
void init() {
  if (NZ<500){
    for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
      for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
        for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
          U[ix][iy][iz] = 1.0;
          V[ix][iy][iz] = 0.0;
          int oy = 131;
          double g
            = gaussian(iz-50, ix-230 ,iy-oy)
            + gaussian(iz-80, ix-80  ,iy-oy)
            + gaussian(iz-120,ix-40  ,iy-oy)
            + gaussian(iz-190,ix-170 ,iy-oy);

          U[ix][iy][iz] -= 0.5 *g;
          V[ix][iy][iz] += 0.5 *g*(1 + 0.01*frand());

        }
      }
    }
  }else{
    map<Key ,double> seeds;
    for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
      for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
        for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
          Key k (ix/16, pair<int,int>(iy/16, iz/16));
          U[ix][iy][iz] = 1.0;
          V[ix][iy][iz] = 0.0;
          double s = seeds[k];
          if (s==0) {
            s = frand();
            seeds[k]=s;
          }
          if (s < 0.1 ) {
            U[ix][iy][iz] = 0.5;
            V[ix][iy][iz] = 0.25;
          }
        }
      }
    }
  }
}
void write_monitor() {
  int global_position[6];
  global_position[0] = navi.offset_x + navi.lower_x;
  global_position[1] = navi.offset_y + navi.lower_y;
  global_position[2] = navi.offset_z + navi.lower_z;
  global_position[3] = navi.upper_x - navi.lower_x;
  global_position[4] = navi.upper_y - navi.lower_y;
  global_position[5] = navi.upper_z - navi.lower_z;
  int x_size = navi.upper_x - navi.lower_x;
  int y_size = navi.upper_y - navi.lower_y;
  int z_size = navi.upper_z - navi.lower_z;

  if (navi.offset_x + navi.lower_x == 0) {
    char fn[256];
    sprintf(fn, "out/monitorX-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int x=navi.lower_x + x_size/2;
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

  if (navi.offset_y + navi.lower_y == 0) {
    char fn[256];
    sprintf(fn, "out/monitorY-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int y=navi.lower_y + y_size/2;
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

}

int main (int argc, char **argv) {
  MPI_Init(&argc, &argv);
  Formura_Init(&navi, MPI_COMM_WORLD);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_rank);
  srand(time(NULL)+mpi_my_rank*65537);

  if (argc <= 1) {
    T_MAX=8192;
  }else{
    sscanf(argv[1], "%d",  &T_MAX);
  }
  if (argc <= 2) {
    T_MONITOR=8192;
  }else{
    sscanf(argv[2], "%d",  &T_MONITOR);
  }
  if (argc >= 4) {
    EXTEND_MISSION = true;
  }

  init();

  double t_begin = wctime(), t_end;

  int last_monitor_t = -T_MONITOR;
  char benchmark_name[256];
  sprintf(benchmark_name,"main");
  for(;;){
    double t = wctime();
    bool monitor_flag = navi.time_step >= last_monitor_t + T_MONITOR;
    if(monitor_flag || navi.time_step <= 3 * T_MONITOR ) {
      if(mpi_my_rank==0){
        printf("marked %d step @ %lf sec\n", navi.time_step, t-t_begin);
      }
    }
    if(monitor_flag) {
      write_monitor();
      if(mpi_my_rank==0){
        printf("monitor %d step @ %lf sec\n", navi.time_step, t-t_begin);
      }
    }
    if(monitor_flag) {
      last_monitor_t += T_MONITOR;
    }

    if (navi.time_step >= T_MAX) {
      if (EXTEND_MISSION){
        T_MAX*=2;
        T_MONITOR*=2;
        sprintf(benchmark_name,"extend-%d",T_MAX);
        //start_collection(benchmark_name);
        fapp_start(benchmark_name, 0,0);
      }else{
        break;
      }

    }
    if (navi.time_step == 0) {
      t_begin = wctime();
      //start_collection(benchmark_name);
      fapp_start(benchmark_name, 0,0);
    }

    Formura_Forward(&navi); // navi.time_step increases
    MPI_Barrier(MPI_COMM_WORLD); // TODO: test the effect of synchronization

    if (navi.time_step >= T_MAX) {
      t_end = wctime();
      //stop_collection(benchmark_name);
      fapp_stop(benchmark_name, 0,0);
    }
  }
  //printf("total wct = %lf sec\n",t_end - t_begin);

  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();
}
<commit_msg>make the initial colony bigger<commit_after>#include <algorithm>
#include <map>
#include <math.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

#include <fj_tool/fapp.h>
#include <fjcoll.h>

using namespace std;

#include "pearson-3d.h"

bool EXTEND_MISSION=false;
int T_MAX;
int T_MONITOR;
int mpi_my_rank;
const double PI=3.14159265358979323846;

float frand() {
  return rand() / float(RAND_MAX);
}

double wctime() {
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return (double)tv.tv_sec + (double)tv.tv_usec*1e-6;
}
/*
  void init() {
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
  for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
  for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
  double x = double(navi.offset_x + ix)/NX;
  double y = double(navi.offset_y + iy)/NY;
  double z = double(navi.offset_z + iz)/NZ;
  U[ix][iy][iz] = 1.0;
  V[ix][iy][iz] = 0.0;
  if (z > 0.49 && z < 0.51 && x > 0.4 && x < 0.6) {
  U[ix][iy][iz] = 0.5;
  V[ix][iy][iz] = 0.25;
  }
  }
  }
  }
  }*/

double gaussian(double x, double y,double z) {
  return exp(- (x*x+y*y+z*z) / 100.0);
}

typedef pair<int,pair<int,int> > Key;
void init() {
  if (NZ<500){
    for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
      for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
        for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
          U[ix][iy][iz] = 1.0;
          V[ix][iy][iz] = 0.0;
          int oy = 131;
          double g
            = gaussian(iz-50, ix-230 ,iy-oy)
            + gaussian(iz-80, ix-80  ,iy-oy)
            + gaussian(iz-120,ix-40  ,iy-oy)
            + gaussian(iz-190,ix-170 ,iy-oy);

          U[ix][iy][iz] -= 0.5 *g;
          V[ix][iy][iz] += 0.5 *g*(1 + 0.01*frand());

        }
      }
    }
  }else{
    map<Key ,double> seeds;
    for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
      for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
        for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
          Key k (ix/16, pair<int,int>(iy/16, iz/16));
          U[ix][iy][iz] = 1.0;
          V[ix][iy][iz] = 0.0;
          double s = seeds[k];
          if (s==0) {
            s = frand();
            seeds[k]=s;
          }
          if (s < 0.1 ) {
            U[ix][iy][iz] = 0.5;
            V[ix][iy][iz] = 0.25;
          }
        }
      }
    }
  }
}
void write_monitor() {
  int global_position[6];
  global_position[0] = navi.offset_x + navi.lower_x;
  global_position[1] = navi.offset_y + navi.lower_y;
  global_position[2] = navi.offset_z + navi.lower_z;
  global_position[3] = navi.upper_x - navi.lower_x;
  global_position[4] = navi.upper_y - navi.lower_y;
  global_position[5] = navi.upper_z - navi.lower_z;
  int x_size = navi.upper_x - navi.lower_x;
  int y_size = navi.upper_y - navi.lower_y;
  int z_size = navi.upper_z - navi.lower_z;

  if (navi.offset_x + navi.lower_x == 0) {
    char fn[256];
    sprintf(fn, "out/monitorX-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int x=navi.lower_x + x_size/2;
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

  if (navi.offset_y + navi.lower_y == 0) {
    char fn[256];
    sprintf(fn, "out/monitorY-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int y=navi.lower_y + y_size/2;
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

}

int main (int argc, char **argv) {
  MPI_Init(&argc, &argv);
  Formura_Init(&navi, MPI_COMM_WORLD);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_rank);
  srand(time(NULL)+mpi_my_rank*65537);

  if (argc <= 1) {
    T_MAX=8192;
  }else{
    sscanf(argv[1], "%d",  &T_MAX);
  }
  if (argc <= 2) {
    T_MONITOR=8192;
  }else{
    sscanf(argv[2], "%d",  &T_MONITOR);
  }
  if (argc >= 4) {
    EXTEND_MISSION = true;
  }

  init();

  double t_begin = wctime(), t_end;

  int last_monitor_t = -T_MONITOR;
  char benchmark_name[256];
  sprintf(benchmark_name,"main");
  for(;;){
    double t = wctime();
    bool monitor_flag = navi.time_step >= last_monitor_t + T_MONITOR;
    if(monitor_flag || navi.time_step <= 3 * T_MONITOR ) {
      if(mpi_my_rank==0){
        printf("marked %d step @ %lf sec\n", navi.time_step, t-t_begin);
      }
    }
    if(monitor_flag) {
      write_monitor();
      if(mpi_my_rank==0){
        printf("monitor %d step @ %lf sec\n", navi.time_step, t-t_begin);
      }
    }
    if(monitor_flag) {
      last_monitor_t += T_MONITOR;
    }

    if (navi.time_step >= T_MAX) {
      if (EXTEND_MISSION){
        T_MAX*=2;
        T_MONITOR*=2;
        sprintf(benchmark_name,"extend-%d",T_MAX);
        //start_collection(benchmark_name);
        fapp_start(benchmark_name, 0,0);
      }else{
        break;
      }

    }
    if (navi.time_step == 0) {
      t_begin = wctime();
      //start_collection(benchmark_name);
      fapp_start(benchmark_name, 0,0);
    }

    Formura_Forward(&navi); // navi.time_step increases
    MPI_Barrier(MPI_COMM_WORLD); // TODO: test the effect of synchronization

    if (navi.time_step >= T_MAX) {
      t_end = wctime();
      //stop_collection(benchmark_name);
      fapp_stop(benchmark_name, 0,0);
    }
  }
  //printf("total wct = %lf sec\n",t_end - t_begin);

  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();
}
<|endoftext|>


<commit_before>#include "Python.h"
#include "sqlite3.h"
#include <cstdint>
#include <pybind11/pybind11.h>

namespace py = pybind11;

// Assume the pysqlite_Connection object's first non-PyObject member is the
// sqlite3 database
struct Connection {
  PyObject_HEAD sqlite3 *db;
};

PYBIND11_MODULE(cslumba, m) {
  m.attr("SQLITE_NULL") = SQLITE_NULL;
  m.attr("SQLITE_OK") = SQLITE_OK;
  m.attr("SQLITE_DETERMINISTIC") = SQLITE_DETERMINISTIC;
  m.attr("SQLITE_UTF8") = SQLITE_UTF8;
  m.attr("SQLITE_VERSION") = SQLITE_VERSION;

  m.def(
      "get_sqlite_db",
      [](py::object connection) {
        return reinterpret_cast<std::intptr_t>(
            reinterpret_cast<Connection *>(connection.ptr())->db);
      },
      "Get the address of the sqlite3* db instance", py::arg("connection"));
}
<commit_msg>fix: fix the pointer type of the connection pointer<commit_after>#include "Python.h"
#include "sqlite3.h"
#include <cstdint>
#include <pybind11/pybind11.h>

namespace py = pybind11;

// Assume the pysqlite_Connection object's first non-PyObject member is the
// sqlite3 database
struct Connection {
  PyObject_HEAD sqlite3 *db;
};

PYBIND11_MODULE(cslumba, m) {
  m.attr("SQLITE_NULL") = SQLITE_NULL;
  m.attr("SQLITE_OK") = SQLITE_OK;
  m.attr("SQLITE_DETERMINISTIC") = SQLITE_DETERMINISTIC;
  m.attr("SQLITE_UTF8") = SQLITE_UTF8;
  m.attr("SQLITE_VERSION") = SQLITE_VERSION;

  m.def(
      "get_sqlite_db",
      [](py::object connection) {
        return reinterpret_cast<std::uintptr_t>(
            reinterpret_cast<Connection *>(connection.ptr())->db);
      },
      "Get the address of the sqlite3* db instance", py::arg("connection"));
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014-2015 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#ifndef CONSTANTS_HPP_
#define CONSTANTS_HPP_

/** Minimum width/length of game board */
const int MIN_WIDTH = 3;

/** Maximum width/length of game board */
const int MAX_WIDTH = 16;

#endif
<commit_msg>Add min/max number of minutes; score to constants<commit_after>/*
 * Copyright (C) 2014-2015 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#ifndef CONSTANTS_HPP_
#define CONSTANTS_HPP_

/** Minimum width/length of game board */
const int MIN_WIDTH = 3;

/** Maximum width/length of game board */
const int MAX_WIDTH = 16;

/** Minimum number of minutes to play */
const int MIN_TIME = 1;

/** Maximum number of minutes to play */
const int MAX_TIME = 1000;

/** Minimum winning score */
const int MIN_SCORE = 10;

/** Maximum winning score */
const int MAX_SCORE = 9999999;

#endif
<|endoftext|>


<commit_before><commit_msg>Enable configuration checkbox "Warn if my sender address is not in included in the certificate I want to use for signing.<commit_after><|endoftext|>