<commit_before>#include <iostream>
#include <memory>
#include <fstream>

#include "Game/Game.h"
#include "Game/Board.h"

#include "Moves/Move.h"

#include "Players/Genetic_AI.h"
#include "Players/Human_Player.h"
#include "Players/Random_AI.h"
#include "Players/Outside_Player.h"

#include "Genes/Gene_Pool.h"

#include "Exceptions/Illegal_Move_Exception.h"
#include "Exceptions/Game_Ending_Exception.h"

#include "Utility.h"
#include "Testing.h"

void print_help();
int find_last_id(const std::string& filename);

int main(int argc, char *argv[])
{
    try
    {
        run_tests();

        if(argc > 1)
        {
            if(std::string(argv[1]) == "-genepool")
            {
                std::string gene_pool_config_file_name;
                if(argc > 2)
                {
                    gene_pool_config_file_name = argv[2];
                }

                gene_pool(gene_pool_config_file_name);
            }
            else if(std::string(argv[1]) == "-replay")
            {
                if(argc > 2)
                {
                    Board board;
                    std::string file_name = argv[2];
                    std::ifstream ifs(file_name);
                    std::string line;
                    bool game_started = false;
                    while( ! board.game_has_ended() && std::getline(ifs, line))
                    {
                        line = String::trim_outer_whitespace(line);
                        line = String::strip_block_comment(line, '{', '}');
                        line = String::strip_comments(line, ';');
                        if(line.empty())
                        {
                            if(game_started)
                            {
                                break;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        if(line[0] == '[')
                        {
                            std::cout << line << std::endl;
                            continue;
                        }

                        for(const auto& s : String::split(line))
                        {
                            try
                            {
                                board.submit_move(board.get_complete_move(s));
                            }
                            catch(const Illegal_Move_Exception&)
                            {
                                std::cout << "Ignoring: " << s << std::endl;
                                continue;
                            }
                            catch(const Game_Ending_Exception& e)
                            {
                                std::cout << e.what() << std::endl;
                            }
                            board.ascii_draw(WHITE);
                            game_started = true;
                            std::cout << "Last move: ";
                            std::cout << (board.get_game_record().size() + 1)/2 << ". ";
                            std::cout << (board.whose_turn() == WHITE ? "... " : "");
                            std::cout << board.get_game_record().back() << std::endl;
                            if(board.game_has_ended())
                            {
                                break;
                            }

                            std::cout << "Enter \"y\" to play game from here: " << std::endl;
                            char response = std::cin.get();
                            if(std::tolower(response) == 'y')
                            {
                                play_game_with_board(Human_Player(),
                                                     Human_Player(),
                                                     0,
                                                     0,
                                                     0,
                                                     file_name + "_continued.pgn",
                                                     board);
                                 break;
                            }
                        }
                    }
                }
                else
                {
                    std::cerr << "-replay must be followed by a file name." << std::endl;
                    return 1;
                }
            }
            else
            {
                std::unique_ptr<Player> white;
                std::unique_ptr<Player> black;
                std::unique_ptr<Player> latest;

                int game_time = 0;
                int moves_per_reset = 0;
                int increment_time = 0;

                for(int i = 1; i < argc; ++i)
                {
                    std::string opt = argv[i];
                    if(opt == "-human")
                    {
                        latest.reset(new Human_Player());
                    }
                    else if(opt == "-random")
                    {
                        latest.reset(new Random_AI());
                    }
                    else if(opt == "-genetic")
                    {
                        Genetic_AI *genetic_ptr = nullptr;
                        std::string filename;
                        int id = -1;
                        if(i + 1 < argc)
                        {
                            filename = argv[i+1];
                            if(filename.front() == '-')
                            {
                                filename.clear();
                            }
                        }

                        if(i + 2 < argc)
                        {
                            try
                            {
                                id = std::stoi(argv[i+2]);
                            }
                            catch(const std::exception&)
                            {
                            }
                        }

                        if(filename.empty())
                        {
                            genetic_ptr = new Genetic_AI;
                            for(int j = 0; j < 100; ++j)
                            {
                                genetic_ptr->mutate();
                            }
                            genetic_ptr->print_genome("single_game_player.txt");
                        }
                        else
                        {
                            if(id < 0)
                            {
                                genetic_ptr = new Genetic_AI(filename, find_last_id(filename));
                                i += 1;
                            }
                            else
                            {
                                genetic_ptr = new Genetic_AI(filename, id);
                                i += 2;
                            }
                        }

                        latest.reset(genetic_ptr);
                    }
                    else if(opt == "-time")
                    {
                        game_time = std::stoi(argv[++i]);
                    }
                    else if(opt == "-reset_moves")
                    {
                        moves_per_reset = std::stoi(argv[++i]);
                    }
                    else if(opt == "-increment_time")
                    {
                        increment_time = std::stoi(argv[++i]);
                    }
                    else
                    {
                        throw std::runtime_error("Invalid option: " + opt);
                    }

                    if(latest)
                    {
                        if( ! white)
                        {
                            white = std::move(latest);
                            continue;
                        }
                        if( ! black)
                        {
                            black = std::move(latest);
                            continue;
                        }
                    }
                }

                std::string game_file_name = "game.pgn";

                if(black)
                {
                    play_game(*white, *black, game_time, moves_per_reset, increment_time, game_file_name);
                }
                else
                {
                    auto outside = connect_to_outside(*white);
                    game_time = outside->get_game_time();
                    moves_per_reset = outside->get_reset_moves();
                    increment_time = outside->get_increment();

                    if(outside->get_ai_color() == WHITE)
                    {
                        play_game(*white, *outside, game_time, moves_per_reset, increment_time, game_file_name);
                    }
                    else
                    {
                        play_game(*outside, *white, game_time, moves_per_reset, increment_time, game_file_name);
                    }
                }
            }
        }
        else
        {
            print_help();
        }
    }
    catch(const std::exception& e)
    {
        std::cerr << "\n\nERROR: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

void print_help()
{
    std::cout << "\n\nGenetic Chess" << std::endl
              << "=============" << std::endl << std::endl
              << "Options:" << std::endl
              << "\t-genepool [file name]" << std::endl
              << "\t\tStart a run of a gene pool with parameters set in the given\n\t\tfile name." << std::endl << std::endl
              << "\t-replay [filename]" << std::endl
              << "\t\tStep through a PGN game file, drawing the board after each\n\t\tmove with an option to begin playing at any time." << std::endl << std::endl
              << "The following options start a game with various players. If two players are\nspecified, the first plays white and the second black. If only one player is\nspecified, the program will wait for a CECP command from outside to start\nplaying." << std::endl << std::endl
              << "\t-human" << std::endl
              << "\t\tSpecify a human player for a game." << std::endl << std::endl
              << "\t-genetic [filename [number]]" << std::endl
              << "\t\tSpecify a genetic AI player for a game. Optional file name and\n\t\tID number to load an AI from a file." << std::endl << std::endl
              << "\t-random" << std::endl
              << "\t\tSpecify a player that makes random moves for a game." << std::endl << std::endl
              << "\t-time [number]" << std::endl
              << "\t\tSpecify the time each player has to play the game or to make\n\t\ta set number of moves (see -reset_moves option)." << std::endl << std::endl
              << "\t-reset_moves [number]" << std::endl
              << "\t\tSpecify the number of moves a player must make within the time\n\t\tlimit. The clock resets to the initial time every time this\n\t\tnumber of moves is made." << std::endl << std::endl
              << "\t-increment_time [number]" << std::endl
              << "\t\tSpecify seconds to add to time after each move." << std::endl << std::endl;
}

int find_last_id(const std::string& filename)
{
    std::ifstream ifs(filename);
    std::string line;
    std::string id_line;
    while(std::getline(ifs, line))
    {
        if(String::starts_with(line, "ID:"))
        {
            id_line = line;
        }
    }

    if(id_line.empty())
    {
        throw std::runtime_error("No Genetic AIs found in " + filename);
    }
    else
    {
        return std::stoi(String::split(id_line)[1]);
    }
}
<commit_msg>Explanatory comment<commit_after>#include <iostream>
#include <memory>
#include <fstream>

#include "Game/Game.h"
#include "Game/Board.h"

#include "Moves/Move.h"

#include "Players/Genetic_AI.h"
#include "Players/Human_Player.h"
#include "Players/Random_AI.h"
#include "Players/Outside_Player.h"

#include "Genes/Gene_Pool.h"

#include "Exceptions/Illegal_Move_Exception.h"
#include "Exceptions/Game_Ending_Exception.h"

#include "Utility.h"
#include "Testing.h"

void print_help();
int find_last_id(const std::string& filename);

int main(int argc, char *argv[])
{
    try
    {
        run_tests();

        if(argc > 1)
        {
            if(std::string(argv[1]) == "-genepool")
            {
                std::string gene_pool_config_file_name;
                if(argc > 2)
                {
                    gene_pool_config_file_name = argv[2];
                }

                gene_pool(gene_pool_config_file_name);
            }
            else if(std::string(argv[1]) == "-replay")
            {
                if(argc > 2)
                {
                    Board board;
                    std::string file_name = argv[2];
                    std::ifstream ifs(file_name);
                    std::string line;
                    bool game_started = false;
                    while( ! board.game_has_ended() && std::getline(ifs, line))
                    {
                        line = String::trim_outer_whitespace(line);
                        line = String::strip_block_comment(line, '{', '}');
                        line = String::strip_comments(line, ';');
                        if(line.empty())
                        {
                            if(game_started)
                            {
                                break;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        if(line[0] == '[')
                        {
                            std::cout << line << std::endl;
                            continue;
                        }

                        for(const auto& s : String::split(line))
                        {
                            try
                            {
                                board.submit_move(board.get_complete_move(s));
                            }
                            catch(const Illegal_Move_Exception&)
                            {
                                std::cout << "Ignoring: " << s << std::endl;
                                continue;
                            }
                            catch(const Game_Ending_Exception& e)
                            {
                                std::cout << e.what() << std::endl;
                            }
                            board.ascii_draw(WHITE);
                            game_started = true;
                            std::cout << "Last move: ";
                            std::cout << (board.get_game_record().size() + 1)/2 << ". ";
                            std::cout << (board.whose_turn() == WHITE ? "... " : "");
                            std::cout << board.get_game_record().back() << std::endl;
                            if(board.game_has_ended())
                            {
                                break;
                            }

                            std::cout << "Enter \"y\" to play game from here: " << std::endl;
                            char response = std::cin.get();
                            if(std::tolower(response) == 'y')
                            {
                                play_game_with_board(Human_Player(),
                                                     Human_Player(),
                                                     0,
                                                     0,
                                                     0,
                                                     file_name + "_continued.pgn",
                                                     board);
                                 break;
                            }
                        }
                    }
                }
                else
                {
                    std::cerr << "-replay must be followed by a file name." << std::endl;
                    return 1;
                }
            }
            else
            {
                // Use pointers since each player could be Human, Genetic, Random, etc.
                std::unique_ptr<Player> white;
                std::unique_ptr<Player> black;
                std::unique_ptr<Player> latest;

                int game_time = 0;
                int moves_per_reset = 0;
                int increment_time = 0;

                for(int i = 1; i < argc; ++i)
                {
                    std::string opt = argv[i];
                    if(opt == "-human")
                    {
                        latest.reset(new Human_Player());
                    }
                    else if(opt == "-random")
                    {
                        latest.reset(new Random_AI());
                    }
                    else if(opt == "-genetic")
                    {
                        Genetic_AI *genetic_ptr = nullptr;
                        std::string filename;
                        int id = -1;
                        if(i + 1 < argc)
                        {
                            filename = argv[i+1];
                            if(filename.front() == '-')
                            {
                                filename.clear();
                            }
                        }

                        if(i + 2 < argc)
                        {
                            try
                            {
                                id = std::stoi(argv[i+2]);
                            }
                            catch(const std::exception&)
                            {
                            }
                        }

                        if(filename.empty())
                        {
                            genetic_ptr = new Genetic_AI;
                            for(int j = 0; j < 100; ++j)
                            {
                                genetic_ptr->mutate();
                            }
                            genetic_ptr->print_genome("single_game_player.txt");
                        }
                        else
                        {
                            if(id < 0)
                            {
                                genetic_ptr = new Genetic_AI(filename, find_last_id(filename));
                                i += 1;
                            }
                            else
                            {
                                genetic_ptr = new Genetic_AI(filename, id);
                                i += 2;
                            }
                        }

                        latest.reset(genetic_ptr);
                    }
                    else if(opt == "-time")
                    {
                        game_time = std::stoi(argv[++i]);
                    }
                    else if(opt == "-reset_moves")
                    {
                        moves_per_reset = std::stoi(argv[++i]);
                    }
                    else if(opt == "-increment_time")
                    {
                        increment_time = std::stoi(argv[++i]);
                    }
                    else
                    {
                        throw std::runtime_error("Invalid option: " + opt);
                    }

                    if(latest)
                    {
                        if( ! white)
                        {
                            white = std::move(latest);
                            continue;
                        }
                        if( ! black)
                        {
                            black = std::move(latest);
                            continue;
                        }
                    }
                }

                std::string game_file_name = "game.pgn";

                if(black)
                {
                    play_game(*white, *black, game_time, moves_per_reset, increment_time, game_file_name);
                }
                else
                {
                    auto outside = connect_to_outside(*white);
                    game_time = outside->get_game_time();
                    moves_per_reset = outside->get_reset_moves();
                    increment_time = outside->get_increment();

                    if(outside->get_ai_color() == WHITE)
                    {
                        play_game(*white, *outside, game_time, moves_per_reset, increment_time, game_file_name);
                    }
                    else
                    {
                        play_game(*outside, *white, game_time, moves_per_reset, increment_time, game_file_name);
                    }
                }
            }
        }
        else
        {
            print_help();
        }
    }
    catch(const std::exception& e)
    {
        std::cerr << "\n\nERROR: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

void print_help()
{
    std::cout << "\n\nGenetic Chess" << std::endl
              << "=============" << std::endl << std::endl
              << "Options:" << std::endl
              << "\t-genepool [file name]" << std::endl
              << "\t\tStart a run of a gene pool with parameters set in the given\n\t\tfile name." << std::endl << std::endl
              << "\t-replay [filename]" << std::endl
              << "\t\tStep through a PGN game file, drawing the board after each\n\t\tmove with an option to begin playing at any time." << std::endl << std::endl
              << "The following options start a game with various players. If two players are\nspecified, the first plays white and the second black. If only one player is\nspecified, the program will wait for a CECP command from outside to start\nplaying." << std::endl << std::endl
              << "\t-human" << std::endl
              << "\t\tSpecify a human player for a game." << std::endl << std::endl
              << "\t-genetic [filename [number]]" << std::endl
              << "\t\tSpecify a genetic AI player for a game. Optional file name and\n\t\tID number to load an AI from a file." << std::endl << std::endl
              << "\t-random" << std::endl
              << "\t\tSpecify a player that makes random moves for a game." << std::endl << std::endl
              << "\t-time [number]" << std::endl
              << "\t\tSpecify the time each player has to play the game or to make\n\t\ta set number of moves (see -reset_moves option)." << std::endl << std::endl
              << "\t-reset_moves [number]" << std::endl
              << "\t\tSpecify the number of moves a player must make within the time\n\t\tlimit. The clock resets to the initial time every time this\n\t\tnumber of moves is made." << std::endl << std::endl
              << "\t-increment_time [number]" << std::endl
              << "\t\tSpecify seconds to add to time after each move." << std::endl << std::endl;
}

int find_last_id(const std::string& filename)
{
    std::ifstream ifs(filename);
    std::string line;
    std::string id_line;
    while(std::getline(ifs, line))
    {
        if(String::starts_with(line, "ID:"))
        {
            id_line = line;
        }
    }

    if(id_line.empty())
    {
        throw std::runtime_error("No Genetic AIs found in " + filename);
    }
    else
    {
        return std::stoi(String::split(id_line)[1]);
    }
}
<|endoftext|>


<commit_before>
// Copyright (c) 2013-2014 Quanta Research Cambridge, Inc.

// 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 <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <sys/mman.h>
#include <stdlib.h>
#include "sock_utils.h"

#define MAX_DMA_PORTS    4
#define MAX_DMA_IDS     32
typedef struct {
    int fd;
    unsigned char *buffer;
    uint32_t buffer_len;
    int size_accum;
} DMAINFO[MAX_DMA_IDS];
static DMAINFO dma_info[MAX_DMA_PORTS];
static int dma_trace ;//= 1;

#define BUFFER_CHECK \
    if (!dma_info[id][pref].buffer || offset >= dma_info[id][pref].buffer_len) { \
      fprintf(stderr, "BsimDma: buffer %p len %d; reference id %d pref %d offset %d\n", dma_info[id][pref].buffer, dma_info[id][pref].buffer_len, id, pref, offset); \
      exit(-1); \
    }

extern "C" void write_pareff32(uint32_t pref, uint32_t offset, unsigned int data)
{
    uint32_t id = pref>>5;
    pref -= id<<5;
    if (dma_trace)
      fprintf(stderr, "%s: %d %d %d\n", __FUNCTION__, id, pref, offset);
    BUFFER_CHECK
    *(unsigned int *)&dma_info[id][pref].buffer[offset] = data;
}

extern "C" unsigned int read_pareff32(uint32_t pref, uint32_t offset)
{
    uint32_t id = pref>>5;
    pref -= id<<5;
    if (dma_trace)
      fprintf(stderr, "%s: %d %d %d\n", __FUNCTION__, id, pref, offset);
    BUFFER_CHECK
    return *(unsigned int *)&dma_info[id][pref].buffer[offset];
}

extern "C" void write_pareff64(uint32_t pref, uint32_t offset, uint64_t data)
{
    uint32_t id = pref>>5;
    pref -= id<<5;
    if (dma_trace)
      fprintf(stderr, "%s: %d %d %d\n", __FUNCTION__, id, pref, offset);
    BUFFER_CHECK
    *(uint64_t *)&dma_info[id][pref].buffer[offset] = data;
}

extern "C" uint64_t read_pareff64(uint32_t pref, uint32_t offset)
{
    uint32_t id = pref>>5;
    pref -= id<<5;
    if (dma_trace)
      fprintf(stderr, "%s: %d %d %d buffer_len %d\n", __FUNCTION__, id, pref, offset, dma_info[id][pref].buffer_len);
    BUFFER_CHECK
    return *(uint64_t *)&dma_info[id][pref].buffer[offset];
}

extern "C" void pareff_initfd(uint32_t aid, uint32_t fd)
{
    uint32_t id = aid >> 16;
    uint32_t pref = aid & 0xffff;
    if (dma_trace)
      fprintf(stderr, "%s: id=%d pref=%d fd=%d\n", __FUNCTION__, id, pref, fd);
    dma_info[id][pref].fd = fd;
}
extern "C" void pareff_init(uint32_t id, uint32_t pref, uint32_t size)
{
    if (dma_trace)
      fprintf(stderr, "pareff_init: id=%d pref=%d, size=%08x size_accum=%08x\n", id, pref, size, dma_info[id][pref].size_accum);
    assert(pref < MAX_DMA_IDS);
    dma_info[id][pref].size_accum += size;
    if(size == 0){
      if (dma_trace)
          fprintf(stderr, "%s: id=%d pref=%d fd=%d\n", __FUNCTION__, id, pref, dma_info[id][pref].fd);
      dma_info[id][pref].buffer = (unsigned char *)mmap(0,
          dma_info[id][pref].size_accum, PROT_WRITE|PROT_WRITE|PROT_EXEC, MAP_SHARED, dma_info[id][pref].fd, 0);
      if (dma_info[id][pref].buffer == MAP_FAILED) {
	fprintf(stderr, "pareff_init: mmap failed fd %x buffer %p size %x errno %d\n", dma_info[id][pref].fd, dma_info[id][pref].buffer, size, errno);
	exit(-1);
      }
      dma_info[id][pref].buffer_len = dma_info[id][pref].size_accum;
    }
    if (dma_trace)
      fprintf(stderr, "pareff_init: done\n");
}
<commit_msg>added function name to BUFFER_CHECK message<commit_after>
// Copyright (c) 2013-2014 Quanta Research Cambridge, Inc.

// 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 <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <sys/mman.h>
#include <stdlib.h>
#include "sock_utils.h"

#define MAX_DMA_PORTS    4
#define MAX_DMA_IDS     32
typedef struct {
    int fd;
    unsigned char *buffer;
    uint32_t buffer_len;
    int size_accum;
} DMAINFO[MAX_DMA_IDS];
static DMAINFO dma_info[MAX_DMA_PORTS];
static int dma_trace ;//= 1;

#define BUFFER_CHECK \
    if (!dma_info[id][pref].buffer || offset >= dma_info[id][pref].buffer_len) { \
    fprintf(stderr, "BsimDma [%s:%d]: buffer %p len %d; reference id %d pref %d offset %d\n", __FUNCTION__, __LINE__, dma_info[id][pref].buffer, dma_info[id][pref].buffer_len, id, pref, offset); \
      exit(-1); \
    }

extern "C" void write_pareff32(uint32_t pref, uint32_t offset, unsigned int data)
{
    uint32_t id = pref>>5;
    pref -= id<<5;
    if (dma_trace)
      fprintf(stderr, "%s: %d %d %d\n", __FUNCTION__, id, pref, offset);
    BUFFER_CHECK
    *(unsigned int *)&dma_info[id][pref].buffer[offset] = data;
}

extern "C" unsigned int read_pareff32(uint32_t pref, uint32_t offset)
{
    uint32_t id = pref>>5;
    pref -= id<<5;
    if (dma_trace)
      fprintf(stderr, "%s: %d %d %d\n", __FUNCTION__, id, pref, offset);
    BUFFER_CHECK
    return *(unsigned int *)&dma_info[id][pref].buffer[offset];
}

extern "C" void write_pareff64(uint32_t pref, uint32_t offset, uint64_t data)
{
    uint32_t id = pref>>5;
    pref -= id<<5;
    if (dma_trace)
      fprintf(stderr, "%s: %d %d %d\n", __FUNCTION__, id, pref, offset);
    BUFFER_CHECK
    *(uint64_t *)&dma_info[id][pref].buffer[offset] = data;
}

extern "C" uint64_t read_pareff64(uint32_t pref, uint32_t offset)
{
    uint32_t id = pref>>5;
    pref -= id<<5;
    if (dma_trace)
      fprintf(stderr, "%s: %d %d %d buffer_len %d\n", __FUNCTION__, id, pref, offset, dma_info[id][pref].buffer_len);
    BUFFER_CHECK
    return *(uint64_t *)&dma_info[id][pref].buffer[offset];
}

extern "C" void pareff_initfd(uint32_t aid, uint32_t fd)
{
    uint32_t id = aid >> 16;
    uint32_t pref = aid & 0xffff;
    if (dma_trace)
      fprintf(stderr, "%s: id=%d pref=%d fd=%d\n", __FUNCTION__, id, pref, fd);
    dma_info[id][pref].fd = fd;
}
extern "C" void pareff_init(uint32_t id, uint32_t pref, uint32_t size)
{
    if (dma_trace)
      fprintf(stderr, "pareff_init: id=%d pref=%d, size=%08x size_accum=%08x\n", id, pref, size, dma_info[id][pref].size_accum);
    assert(pref < MAX_DMA_IDS);
    dma_info[id][pref].size_accum += size;
    if(size == 0){
      if (dma_trace)
          fprintf(stderr, "%s: id=%d pref=%d fd=%d\n", __FUNCTION__, id, pref, dma_info[id][pref].fd);
      dma_info[id][pref].buffer = (unsigned char *)mmap(0,
          dma_info[id][pref].size_accum, PROT_WRITE|PROT_WRITE|PROT_EXEC, MAP_SHARED, dma_info[id][pref].fd, 0);
      if (dma_info[id][pref].buffer == MAP_FAILED) {
	fprintf(stderr, "pareff_init: mmap failed fd %x buffer %p size %x errno %d\n", dma_info[id][pref].fd, dma_info[id][pref].buffer, size, errno);
	exit(-1);
      }
      dma_info[id][pref].buffer_len = dma_info[id][pref].size_accum;
    }
    if (dma_trace)
      fprintf(stderr, "pareff_init: done\n");
}
<|endoftext|>


<commit_before>#include "session.h"

#include <functional>

#include <curl/curl.h>

#include "curlholder.h"
#include "util.h"

class Session::Impl {
  public:
    Impl();

    void SetUrl(Url url);
    void SetUrl(Url url, Parameters parameters);
    void SetHeader(Header header);
    void SetTimeout(Timeout timeout);
    void SetAuth(Authentication auth);
    void SetPayload(Payload payload);
    void SetRedirect(bool redirect);
    void SetMaxRedirects(long max_redirects);
    // void SetCookie(); Unimplemented
    // void SetCookies(); Unimplemented

    Response Get();
    Response Post();

  private:
    std::unique_ptr<CurlHolder, std::function<void(CurlHolder*)>> curl_;

    static void freeHolder(CurlHolder* holder);
    static CurlHolder* newHolder();
};

Session::Impl::Impl() {
    curl_ = std::unique_ptr<CurlHolder, std::function<void(CurlHolder*)>>(newHolder(), &Impl::freeHolder);
    auto curl = curl_->handle;
    if (curl) {
        // Set up some sensible defaults
        auto version_info = curl_version_info(CURLVERSION_NOW);
        auto version = std::string{"curl/"} + std::string{version_info->version};
        curl_easy_setopt(curl, CURLOPT_USERAGENT, version.data());
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_->error);
#if LIBCURL_VERSION_MAJOR >= 7
#if LIBCURL_VERSION_MINOR >= 25
#if LIBCURL_VERSION_PATCH >= 0
        curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
#endif
#endif
#endif
    }
}

void Session::Impl::freeHolder(CurlHolder* holder) {
    curl_easy_cleanup(holder->handle);
    curl_slist_free_all(holder->chunk);
}

CurlHolder* Session::Impl::newHolder() {
    CurlHolder* holder = new CurlHolder();
    holder->handle = curl_easy_init();
    return holder;
}

void Session::Impl::SetUrl(Url url) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.data());
    }
}

void Session::Impl::SetUrl(Url url, Parameters parameters) {
    auto curl = curl_->handle;
    if (curl) {
        Url new_url{url + "?"};
        for(auto parameter = parameters.cbegin(); parameter != parameters.cend(); ++parameter) {
            new_url += parameter->first + "=" + parameter->second + "&";
        }
        new_url = new_url.substr(0, new_url.size() - 1);
        curl_easy_setopt(curl, CURLOPT_URL, new_url.data());
    }
}

void Session::Impl::SetHeader(Header header) {
    auto curl = curl_->handle;
    if (curl) {
        struct curl_slist* chunk = NULL;
        for (auto item = header.cbegin(); item != header.cend(); ++item) {
            auto header_string = std::string{item->first};
            if (item->second.empty()) {
                header_string += ";";
            } else {
                header_string += ": " + item->second;
            }
            chunk = curl_slist_append(chunk, header_string.data());
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
            curl_->chunk = chunk;
        }
    }
}

void Session::Impl::SetTimeout(long timeout) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, timeout);
    }
}

void Session::Impl::SetAuth(Authentication auth) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_easy_setopt(curl, CURLOPT_USERPWD, auth.GetAuthString());
    }
}

void Session::Impl::SetPayload(Payload payload) {
    auto curl = curl_->handle;
    if (curl) {
        struct curl_slist* chunk = NULL;
        auto payload_string = std::string{};
        for (auto item = payload.cbegin(); item != payload.cend(); ++item) {
            if (!payload_string.empty()) {
                payload_string += "&";
            }
            payload_string += item->first + "=" + item->second;
        }
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload_string.length());
        curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, payload_string.data());
    }
}

void Session::Impl::SetRedirect(bool redirect) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, long(redirect));
    }
}

void Session::Impl::SetMaxRedirects(long max_redirects) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, max_redirects);
    }
}

Response Session::Impl::Get() {
    auto curl = curl_->handle;
    CURLcode res;
    Response response{0, "Curl could not start", Header{}, Url{}, 0.0};

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
        curl_easy_setopt(curl, CURLOPT_POST, 0L);
        std::string response_string;
        std::string header_string;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_string);

        res = curl_easy_perform(curl);

        char* raw_url;
        long response_code;
        double elapsed;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed);
        curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &raw_url);
        auto header = cpr::util::parseHeader(header_string);
        response_string = cpr::util::parseResponse(response_string);
        response = {response_code, response_string, header, raw_url, elapsed};
    }

    return response;
}

Response Session::Impl::Post() {
    auto curl = curl_->handle;
    CURLcode res;
    Response response{0, "Curl could not start", Header{}, Url{}, 0.0};

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L);
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        std::string response_string;
        std::string header_string;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_string);

        res = curl_easy_perform(curl);

        char* raw_url;
        long response_code;
        double elapsed;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed);
        curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &raw_url);
        auto header = cpr::util::parseHeader(header_string);
        response_string = cpr::util::parseResponse(response_string);
        response = {response_code, response_string, header, raw_url, elapsed};
    }

    return response;
}

Session::Session() : pimpl_{ new Impl{} } {}
Session::~Session() {}
void Session::SetUrl(Url url) { pimpl_->SetUrl(url); }
void Session::SetUrl(Url url, Parameters parameters) { pimpl_->SetUrl(url, parameters); }
void Session::SetHeader(Header header) { pimpl_->SetHeader(header); }
void Session::SetTimeout(Timeout timeout) { pimpl_->SetTimeout(timeout); }
void Session::SetAuth(Authentication auth) { pimpl_->SetAuth(auth); }
void Session::SetPayload(Payload payload) { pimpl_->SetPayload(payload); }
void Session::SetRedirect(bool redirect) { pimpl_->SetRedirect(redirect); }
void Session::SetMaxRedirects(long max_redirects) { pimpl_->SetMaxRedirects(max_redirects); }
// void SetCookie(); Unimplemented
// void SetCookies(); Unimplemented
Response Session::Get() { return pimpl_->Get(); }
Response Session::Post() { return pimpl_->Post(); }
<commit_msg>Consolidate common code into a makeRequest method<commit_after>#include "session.h"

#include <functional>

#include <curl/curl.h>

#include "curlholder.h"
#include "util.h"

class Session::Impl {
  public:
    Impl();

    void SetUrl(Url url);
    void SetUrl(Url url, Parameters parameters);
    void SetHeader(Header header);
    void SetTimeout(Timeout timeout);
    void SetAuth(Authentication auth);
    void SetPayload(Payload payload);
    void SetRedirect(bool redirect);
    void SetMaxRedirects(long max_redirects);
    // void SetCookie(); Unimplemented
    // void SetCookies(); Unimplemented

    Response Get();
    Response Post();

  private:
    std::unique_ptr<CurlHolder, std::function<void(CurlHolder*)>> curl_;

    Response makeRequest(CURL* curl);
    static void freeHolder(CurlHolder* holder);
    static CurlHolder* newHolder();
};

Session::Impl::Impl() {
    curl_ = std::unique_ptr<CurlHolder, std::function<void(CurlHolder*)>>(newHolder(), &Impl::freeHolder);
    auto curl = curl_->handle;
    if (curl) {
        // Set up some sensible defaults
        auto version_info = curl_version_info(CURLVERSION_NOW);
        auto version = std::string{"curl/"} + std::string{version_info->version};
        curl_easy_setopt(curl, CURLOPT_USERAGENT, version.data());
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_->error);
#if LIBCURL_VERSION_MAJOR >= 7
#if LIBCURL_VERSION_MINOR >= 25
#if LIBCURL_VERSION_PATCH >= 0
        curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
#endif
#endif
#endif
    }
}

void Session::Impl::freeHolder(CurlHolder* holder) {
    curl_easy_cleanup(holder->handle);
    curl_slist_free_all(holder->chunk);
}

CurlHolder* Session::Impl::newHolder() {
    CurlHolder* holder = new CurlHolder();
    holder->handle = curl_easy_init();
    return holder;
}

void Session::Impl::SetUrl(Url url) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.data());
    }
}

void Session::Impl::SetUrl(Url url, Parameters parameters) {
    auto curl = curl_->handle;
    if (curl) {
        Url new_url{url + "?"};
        for(auto parameter = parameters.cbegin(); parameter != parameters.cend(); ++parameter) {
            new_url += parameter->first + "=" + parameter->second + "&";
        }
        new_url = new_url.substr(0, new_url.size() - 1);
        curl_easy_setopt(curl, CURLOPT_URL, new_url.data());
    }
}

void Session::Impl::SetHeader(Header header) {
    auto curl = curl_->handle;
    if (curl) {
        struct curl_slist* chunk = NULL;
        for (auto item = header.cbegin(); item != header.cend(); ++item) {
            auto header_string = std::string{item->first};
            if (item->second.empty()) {
                header_string += ";";
            } else {
                header_string += ": " + item->second;
            }
            chunk = curl_slist_append(chunk, header_string.data());
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
            curl_->chunk = chunk;
        }
    }
}

void Session::Impl::SetTimeout(long timeout) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, timeout);
    }
}

void Session::Impl::SetAuth(Authentication auth) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_easy_setopt(curl, CURLOPT_USERPWD, auth.GetAuthString());
    }
}

void Session::Impl::SetPayload(Payload payload) {
    auto curl = curl_->handle;
    if (curl) {
        struct curl_slist* chunk = NULL;
        auto payload_string = std::string{};
        for (auto item = payload.cbegin(); item != payload.cend(); ++item) {
            if (!payload_string.empty()) {
                payload_string += "&";
            }
            payload_string += item->first + "=" + item->second;
        }
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload_string.length());
        curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, payload_string.data());
    }
}

void Session::Impl::SetRedirect(bool redirect) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, long(redirect));
    }
}

void Session::Impl::SetMaxRedirects(long max_redirects) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, max_redirects);
    }
}

Response Session::Impl::Get() {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
        curl_easy_setopt(curl, CURLOPT_POST, 0L);
    }

    return makeRequest(curl);
}

Response Session::Impl::Post() {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L);
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
    }

    return makeRequest(curl);
}

Response Session::Impl::makeRequest(CURL* curl) {
    std::string response_string;
    std::string header_string;
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_string);

    curl_easy_perform(curl);

    char* raw_url;
    long response_code;
    double elapsed;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
    curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed);
    curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &raw_url);
    auto header = cpr::util::parseHeader(header_string);
    response_string = cpr::util::parseResponse(response_string);
    return Response{response_code, response_string, header, raw_url, elapsed};
}

Session::Session() : pimpl_{ new Impl{} } {}
Session::~Session() {}
void Session::SetUrl(Url url) { pimpl_->SetUrl(url); }
void Session::SetUrl(Url url, Parameters parameters) { pimpl_->SetUrl(url, parameters); }
void Session::SetHeader(Header header) { pimpl_->SetHeader(header); }
void Session::SetTimeout(Timeout timeout) { pimpl_->SetTimeout(timeout); }
void Session::SetAuth(Authentication auth) { pimpl_->SetAuth(auth); }
void Session::SetPayload(Payload payload) { pimpl_->SetPayload(payload); }
void Session::SetRedirect(bool redirect) { pimpl_->SetRedirect(redirect); }
void Session::SetMaxRedirects(long max_redirects) { pimpl_->SetMaxRedirects(max_redirects); }
// void SetCookie(); Unimplemented
// void SetCookies(); Unimplemented
Response Session::Get() { return pimpl_->Get(); }
Response Session::Post() { return pimpl_->Post(); }
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <fstream>
#include <iomanip>

#include "sim/param.hh"
#include "encumbered/cpu/full/dyn_inst.hh"
#include "encumbered/cpu/full/spec_state.hh"
#include "encumbered/cpu/full/issue.hh"
#include "cpu/exetrace.hh"
#include "cpu/exec_context.hh"
#include "base/loader/symtab.hh"
#include "cpu/base.hh"
#include "cpu/static_inst.hh"

using namespace std;

////////////////////////////////////////////////////////////////////////
//
//  Methods for the InstRecord object
//

void
Trace::InstRecord::dump(ostream &outs)
{
    if (flags[INTEL_FORMAT]) {
        if (cpu->system->name() == trace_system) {
            ccprintf(outs, "%7d ) ", cycle);
            outs << "0x" << hex << PC << ":\t";
            if (staticInst->isLoad()) {
                outs << "<RD 0x" << hex << addr;
                outs << ">";
            } else if (staticInst->isStore()) {
                outs << "<WR 0x" << hex << addr;
                outs << ">";
            }
            outs << endl;
        }
    } else {
        if (flags[PRINT_CYCLE])
            ccprintf(outs, "%7d: ", cycle);

        outs << cpu->name() << " ";

        if (flags[TRACE_MISSPEC])
            outs << (misspeculating ? "-" : "+") << " ";

        if (flags[PRINT_THREAD_NUM])
            outs << "T" << thread << " : ";

        std::string sym_str;
        Addr sym_addr;
        if (debugSymbolTable
            && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)) {
            if (PC != sym_addr)
                sym_str += csprintf("+%d", PC - sym_addr);
            outs << "@" << sym_str << " : ";
        }
        else {
            outs << "0x" << hex << PC << " : ";
        }

        //
        //  Print decoded instruction
        //

#if defined(__GNUC__) && (__GNUC__ < 3)
        // There's a bug in gcc 2.x library that prevents setw()
        // from working properly on strings
        string mc(staticInst->disassemble(PC, debugSymbolTable));
        while (mc.length() < 26)
            mc += " ";
        outs << mc;
#else
        outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
#endif

        outs << " : ";

        if (flags[PRINT_OP_CLASS]) {
            outs << opClassStrings[staticInst->opClass()] << " : ";
        }

        if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
            outs << " D=";
#if 0
            if (data_status == DataDouble)
                ccprintf(outs, "%f", data.as_double);
            else
                ccprintf(outs, "%#018x", data.as_int);
#else
            ccprintf(outs, "%#018x", data.as_int);
#endif
        }

        if (flags[PRINT_EFF_ADDR] && addr_valid)
            outs << " A=0x" << hex << addr;

        if (flags[PRINT_INT_REGS] && regs_valid) {
            for (int i = 0; i < 32;)
                for (int j = i + 1; i <= j; i++)
                    ccprintf(outs, "r%02d = %#018x%s", i, iregs->regs[i],
                             ((i == j) ? "\n" : "    "));
            outs << "\n";
        }

        if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
            outs << "  FetchSeq=" << dec << fetch_seq;

        if (flags[PRINT_CP_SEQ] && cp_seq_valid)
            outs << "  CPSeq=" << dec << cp_seq;

        //
        //  End of line...
        //
        outs << endl;
    }
}

vector<bool> Trace::InstRecord::flags(NUM_BITS);
string Trace::InstRecord::trace_system;

////////////////////////////////////////////////////////////////////////
//
// Parameter space for per-cycle execution address tracing options.
// Derive from ParamContext so we can override checkParams() function.
//
class ExecutionTraceParamContext : public ParamContext
{
  public:
    ExecutionTraceParamContext(const string &_iniSection)
        : ParamContext(_iniSection)
        {
        }

    void checkParams();	// defined at bottom of file
};

ExecutionTraceParamContext exeTraceParams("exetrace");

Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
                           "capture speculative instructions", true);

Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
                                  "print cycle number", true);
Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
                                  "print op class", true);
Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
                                  "print thread number", true);
Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
                                  "print effective address", true);
Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
                                  "print result data", true);
Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
                                  "print all integer regs", false);
Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
                                  "print fetch sequence number", false);
Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
                                  "print correct-path sequence number", false);
Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
                                   "print trace in intel compatible format", false);
Param<string> exe_trace_system(&exeTraceParams, "trace_system",
                                   "print trace of which system (client or server)",
                                   "client");

//
// Helper function for ExecutionTraceParamContext::checkParams() just
// to get us into the InstRecord namespace
//
void
Trace::InstRecord::setParams()
{
    flags[TRACE_MISSPEC]     = exe_trace_spec;

    flags[PRINT_CYCLE]       = exe_trace_print_cycle;
    flags[PRINT_OP_CLASS]    = exe_trace_print_opclass;
    flags[PRINT_THREAD_NUM]  = exe_trace_print_thread;
    flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
    flags[PRINT_EFF_ADDR]    = exe_trace_print_data;
    flags[PRINT_INT_REGS]    = exe_trace_print_iregs;
    flags[PRINT_FETCH_SEQ]   = exe_trace_print_fetchseq;
    flags[PRINT_CP_SEQ]      = exe_trace_print_cp_seq;
    flags[INTEL_FORMAT]      = exe_trace_intel_format;
    trace_system	     = exe_trace_system;
}

void
ExecutionTraceParamContext::checkParams()
{
    Trace::InstRecord::setParams();
}

<commit_msg>Fix Lisa's CPU trace system check for syscall emulation.<commit_after>/*
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <fstream>
#include <iomanip>

#include "sim/param.hh"
#include "encumbered/cpu/full/dyn_inst.hh"
#include "encumbered/cpu/full/spec_state.hh"
#include "encumbered/cpu/full/issue.hh"
#include "cpu/exetrace.hh"
#include "cpu/exec_context.hh"
#include "base/loader/symtab.hh"
#include "cpu/base.hh"
#include "cpu/static_inst.hh"

using namespace std;

////////////////////////////////////////////////////////////////////////
//
//  Methods for the InstRecord object
//

void
Trace::InstRecord::dump(ostream &outs)
{
    if (flags[INTEL_FORMAT]) {
#if FULL_SYSTEM
        bool is_trace_system = (cpu->system->name() == trace_system);
#else
        bool is_trace_system = true;
#endif
        if (is_trace_system) {
            ccprintf(outs, "%7d ) ", cycle);
            outs << "0x" << hex << PC << ":\t";
            if (staticInst->isLoad()) {
                outs << "<RD 0x" << hex << addr;
                outs << ">";
            } else if (staticInst->isStore()) {
                outs << "<WR 0x" << hex << addr;
                outs << ">";
            }
            outs << endl;
        }
    } else {
        if (flags[PRINT_CYCLE])
            ccprintf(outs, "%7d: ", cycle);

        outs << cpu->name() << " ";

        if (flags[TRACE_MISSPEC])
            outs << (misspeculating ? "-" : "+") << " ";

        if (flags[PRINT_THREAD_NUM])
            outs << "T" << thread << " : ";

        std::string sym_str;
        Addr sym_addr;
        if (debugSymbolTable
            && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)) {
            if (PC != sym_addr)
                sym_str += csprintf("+%d", PC - sym_addr);
            outs << "@" << sym_str << " : ";
        }
        else {
            outs << "0x" << hex << PC << " : ";
        }

        //
        //  Print decoded instruction
        //

#if defined(__GNUC__) && (__GNUC__ < 3)
        // There's a bug in gcc 2.x library that prevents setw()
        // from working properly on strings
        string mc(staticInst->disassemble(PC, debugSymbolTable));
        while (mc.length() < 26)
            mc += " ";
        outs << mc;
#else
        outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
#endif

        outs << " : ";

        if (flags[PRINT_OP_CLASS]) {
            outs << opClassStrings[staticInst->opClass()] << " : ";
        }

        if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
            outs << " D=";
#if 0
            if (data_status == DataDouble)
                ccprintf(outs, "%f", data.as_double);
            else
                ccprintf(outs, "%#018x", data.as_int);
#else
            ccprintf(outs, "%#018x", data.as_int);
#endif
        }

        if (flags[PRINT_EFF_ADDR] && addr_valid)
            outs << " A=0x" << hex << addr;

        if (flags[PRINT_INT_REGS] && regs_valid) {
            for (int i = 0; i < 32;)
                for (int j = i + 1; i <= j; i++)
                    ccprintf(outs, "r%02d = %#018x%s", i, iregs->regs[i],
                             ((i == j) ? "\n" : "    "));
            outs << "\n";
        }

        if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
            outs << "  FetchSeq=" << dec << fetch_seq;

        if (flags[PRINT_CP_SEQ] && cp_seq_valid)
            outs << "  CPSeq=" << dec << cp_seq;

        //
        //  End of line...
        //
        outs << endl;
    }
}

vector<bool> Trace::InstRecord::flags(NUM_BITS);
string Trace::InstRecord::trace_system;

////////////////////////////////////////////////////////////////////////
//
// Parameter space for per-cycle execution address tracing options.
// Derive from ParamContext so we can override checkParams() function.
//
class ExecutionTraceParamContext : public ParamContext
{
  public:
    ExecutionTraceParamContext(const string &_iniSection)
        : ParamContext(_iniSection)
        {
        }

    void checkParams();	// defined at bottom of file
};

ExecutionTraceParamContext exeTraceParams("exetrace");

Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
                           "capture speculative instructions", true);

Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
                                  "print cycle number", true);
Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
                                  "print op class", true);
Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
                                  "print thread number", true);
Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
                                  "print effective address", true);
Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
                                  "print result data", true);
Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
                                  "print all integer regs", false);
Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
                                  "print fetch sequence number", false);
Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
                                  "print correct-path sequence number", false);
Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
                                   "print trace in intel compatible format", false);
Param<string> exe_trace_system(&exeTraceParams, "trace_system",
                                   "print trace of which system (client or server)",
                                   "client");

//
// Helper function for ExecutionTraceParamContext::checkParams() just
// to get us into the InstRecord namespace
//
void
Trace::InstRecord::setParams()
{
    flags[TRACE_MISSPEC]     = exe_trace_spec;

    flags[PRINT_CYCLE]       = exe_trace_print_cycle;
    flags[PRINT_OP_CLASS]    = exe_trace_print_opclass;
    flags[PRINT_THREAD_NUM]  = exe_trace_print_thread;
    flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
    flags[PRINT_EFF_ADDR]    = exe_trace_print_data;
    flags[PRINT_INT_REGS]    = exe_trace_print_iregs;
    flags[PRINT_FETCH_SEQ]   = exe_trace_print_fetchseq;
    flags[PRINT_CP_SEQ]      = exe_trace_print_cp_seq;
    flags[INTEL_FORMAT]      = exe_trace_intel_format;
    trace_system	     = exe_trace_system;
}

void
ExecutionTraceParamContext::checkParams()
{
    Trace::InstRecord::setParams();
}

<|endoftext|>


<commit_before>/*
  Copyright (C) 2014 Marcus Soll
  All rights reserved.

  You may use this file under the terms of BSD license as follows:

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the Jolla Ltd nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

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

#include <QDebug>
#include <QList>
#include <QTime>
#include <QString>
#include <QtAlgorithms>
#include "getscore.h"
#include "gene.h"
#include "omp.h"

// Parameters of learning
int rounds = 100;
int population = 32;
int children = 32;
int mutationRate = 0.1;
int redoTests = 5;

struct TestScenario {
    QString player1;
    QString player2;
    int player;
};

QList<TestScenario> getScenarios();

int main(int argc, char *argv[])
{
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

    omp_set_num_threads(omp_get_num_procs()*2);

    QList<Gene> currentPopulation;
    QList<TestScenario> scenatios = getScenarios();
    GetScore calc;

    for(int i = 0; i < population; ++i)
    {
        currentPopulation.append(Gene(mutationRate));
    }

    for(int round = 1; round <= rounds; ++round)
    {
        qDebug() << "Current round: " << round;

        QList<Gene> newPopulation = currentPopulation;
        for(int i = 0; i < children; ++i)
        {
            Gene children = currentPopulation[qrand()%population];
            children.mutate();
            newPopulation.append(children);
        }

        for(int testnr=0; testnr < population+children; ++testnr)
        {
            qDebug() << "\tGene " << testnr;
            int score = 0;
            newPopulation[testnr].saveFiles();
#pragma omp parallel for private(calc) reduction(+:score)
            for(int test = 0; test < scenatios.size(); ++test)
            {
                calc.startTest(scenatios[test].player1, scenatios[test].player2,scenatios[test].player);
                while(calc.scoreCalculated()) {qDebug() << "Waiting";}
                score += calc.getScore();
            }
            newPopulation[testnr].saveScore(score);
        }

        currentPopulation.clear();
        qSort(newPopulation);
        for(int i = 0; i < population; ++i)
        {
            currentPopulation.append(newPopulation[i]);
        }

        qDebug() << "++++++++++\nBest score: " << currentPopulation[0].getScore() << "\n++++++++++\n";
        currentPopulation[0].saveFiles("./inputToHidden.endOfRound.txt", "./hiddenToOutput.endOfRound.txt");
    }

    currentPopulation[0].saveFiles();
    qDebug() << "Finished";
}

QList<TestScenario> getScenarios()
{
    QList<TestScenario> scenarios;

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Greedy AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Greedy AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Tree AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Tree AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Balanced AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Balanced AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Static Rule AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Static Rule AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Adaptive Tree AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Adaptive Tree AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Control AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Control AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Assembly AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Assembly AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    return scenarios;
}
<commit_msg>Improved parallel running<commit_after>/*
  Copyright (C) 2014 Marcus Soll
  All rights reserved.

  You may use this file under the terms of BSD license as follows:

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the Jolla Ltd nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

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

#include <QDebug>
#include <QList>
#include <QTime>
#include <QString>
#include <QtAlgorithms>
#include "getscore.h"
#include "gene.h"
#include "omp.h"

// Parameters of learning
int rounds = 100;
int population = 32;
int children = 32;
int mutationRate = 0.1;
int redoTests = 5;

struct TestScenario {
    QString player1;
    QString player2;
    int player;
};

QList<TestScenario> getScenarios();

int main(int argc, char *argv[])
{
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

    omp_set_num_threads(omp_get_num_procs()*2);

    QList<Gene> currentPopulation;
    QList<TestScenario> scenatios = getScenarios();
    GetScore calc;

    for(int i = 0; i < population; ++i)
    {
        currentPopulation.append(Gene(mutationRate));
    }

    for(int round = 1; round <= rounds; ++round)
    {
        qDebug() << "Current round: " << round;

        QList<Gene> newPopulation = currentPopulation;
        for(int i = 0; i < children; ++i)
        {
            Gene children = currentPopulation[qrand()%population];
            children.mutate();
            newPopulation.append(children);
        }

        for(int testnr=0; testnr < population+children; ++testnr)
        {
            qDebug() << "\tGene " << testnr;
            int score = 0;
            newPopulation[testnr].saveFiles();
#pragma omp parallel for schedule(dynamic) private(calc) reduction(+:score)
            for(int test = 0; test < scenatios.size(); ++test)
            {
                calc.startTest(scenatios[test].player1, scenatios[test].player2,scenatios[test].player);
                while(calc.scoreCalculated()) {qDebug() << "Waiting";}
                score += calc.getScore();
            }
            newPopulation[testnr].saveScore(score);
        }

        currentPopulation.clear();
        qSort(newPopulation);
        for(int i = 0; i < population; ++i)
        {
            currentPopulation.append(newPopulation[i]);
        }

        qDebug() << "++++++++++\nBest score: " << currentPopulation[0].getScore() << "\n++++++++++\n";
        currentPopulation[0].saveFiles("./inputToHidden.endOfRound.txt", "./hiddenToOutput.endOfRound.txt");
    }

    currentPopulation[0].saveFiles();
    qDebug() << "Finished";
}

QList<TestScenario> getScenarios()
{
    QList<TestScenario> scenarios;

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Greedy AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Greedy AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Tree AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Tree AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Balanced AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Balanced AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Static Rule AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Static Rule AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Adaptive Tree AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Adaptive Tree AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Control AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Control AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player1 = "Assembly AI";
        test.player2 = "Neural Network AI";
        test.player = 2;
        scenarios.append(test);
    }
    for(int i=0; i<redoTests; ++i)
    {
        TestScenario test;
        test.player2 = "Assembly AI";
        test.player1 = "Neural Network AI";
        test.player = 1;
        scenarios.append(test);
    }

    return scenarios;
}
<|endoftext|>


<commit_before>#include "common.th"

// c <- multiplicand
// d <- multiplier
// b -> product
.global imul
imul:
    pushall(h,i,j,k)

    i <- d == 0
    jnzrel(i, L_done)
    h <- 1
    b <- 0

    j <- c >> 31    // save sign bit in j
    j <- -j         // convert sign to flag
    c <- c ^ j      // adjust multiplicand
    c <- c - j

    k <- d >> 31    // save sign bit in k
    k <- -k         // convert sign to flag
    d <- d ^ k      // adjust multiplier
    d <- d - k

    j <- j ^ k      // final flip flag is in j

L_top:
    // use constant 1 in h to combine instructions
    i <- d & h - 1
    i <- c &~ i
    b <- b + i
    c <- c << 1
    d <- d >> 1
    i <- d <> 0
    jnzrel(i, L_top)

L_done:
    b <- b ^ j      // adjust product for signed math
    b <- b - j

    popall(h,i,j,k)
    ret

<commit_msg>Simplify imul (no need to check both signs)<commit_after>#include "common.th"

// c <- multiplicand
// d <- multiplier
// b -> product
.global imul
imul:
    pushall(h,i,j)

    i <- d == 0
    jnzrel(i, L_done)
    h <- 1
    b <- 0

    j <- d >> 31    // save sign bit in j
    j <- -j         // convert sign to flag
    d <- d ^ j      // adjust multiplier
    d <- d - j

L_top:
    // use constant 1 in h to combine instructions
    i <- d & h - 1
    i <- c &~ i
    b <- b + i
    c <- c << 1
    d <- d >> 1
    i <- d <> 0
    jnzrel(i, L_top)

L_done:
    b <- b ^ j      // adjust product for signed math
    b <- b - j

    popall(h,i,j)
    ret

<|endoftext|>


<commit_before><commit_msg>fixed race condition on session termination<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

/* This must be included before anything else */
#if HAVE_CONFIG_H
#  include <config.h>
#endif

#include <yajr/internal/comms.hpp>
#include <yajr/rpc/methods.hpp>
#include <yajr/rpc/rpc.hpp>

#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>

namespace yajr {
    namespace rpc {

Message::PayloadKeys Message::kPayloadKey = {
    "params",
    "result",
    "error"
};

bool operator< (rapidjson::Value const & l, rapidjson::Value const & r) {

    rapidjson::Type lt = l.GetType();
    rapidjson::Type rt = r.GetType();

    if (lt < rt) {
        return true;
    }

    if (lt > rt) {
        return false;
    }

    /* same type */
    std::size_t lh = hash_value(l);
    std::size_t rh = hash_value(r);

    return (lh < rh);
}

bool OutboundMessage::Accept(yajr::rpc::SendHandler& handler) {

    VLOG(5);

    return handler.StartObject()

        && handler.String("id")
        && emitId(handler)

        && emitMethod(handler)

        && handler.String(getPayloadKey())
        && payloadGenerator_(handler)

        && handler.EndObject()

    ;

}

bool OutboundMessage::send() {

    VLOG(5);

    ::yajr::comms::internal::CommunicationPeer const * cP =
        dynamic_cast< ::yajr::comms::internal::CommunicationPeer const * >
        (peer_);

    assert(cP &&
            "peer needs to be set "
            "to a proper communication peer "
            "before outbound messages are sent");

    unsigned char connected = cP->connected_;

    assert(connected);

    if (!connected) {
        return false;
    }

    assert(cP->__checkInvariants());

    Accept(cP->getWriter());

    assert(cP->__checkInvariants());

    cP->delimitFrame();

    assert(cP->__checkInvariants());

    cP->write();

    assert(cP->__checkInvariants());

    return true;

}

bool OutboundRequest::send(
        ::yajr::Peer const & peer
    ) {

    VLOG(3);

    setPeer(&peer);

    return send();
}

InboundResponse::InboundResponse(
    yajr::Peer const & peer,             /**< [in] where we received from */
    rapidjson::Value const & response,/**< [in] the error/result received */
    rapidjson::Value const & id          /**< [in] the id of this message */
    )
    :
      InboundMessage(peer, response),
      LocalIdentifier(
              MessageFactory::lookupMethod(
                  id[rapidjson::SizeType(0)].GetString()
                ),
              id[1].GetUint64()
          )
    {}

uv_loop_t const *
yajr::rpc::Message::getUvLoop() const {
    return dynamic_cast< ::yajr::comms::internal::CommunicationPeer const * >
        (getPeer())->getUvLoop();
}

std::size_t hash_value(rapidjson::Value const& v) {

    /* switch(v.GetType()) { <-- would be more efficient but would have to
                                 rely on private stuff from Value */

    if(v.IsDouble()) {
        return boost::hash<double>()(v.GetDouble());
    }

    if(v.IsUint64()) {
        return boost::hash<uint64_t>()(v.GetUint64());
    }

    if(v.IsInt64()) {
        return boost::hash<int64_t>()(v.GetInt64());
    }

    if(v.IsBool()) {
        return boost::hash<bool>()(v.GetBool());
    }

    if(v.IsNull()) {
        return boost::hash<uintptr_t>()(0);
    }

    if(v.IsArray()) {
        std::size_t h = 0;

        for (rapidjson::Value::ConstValueIterator
                itr = v.Begin(); itr != v.End(); ++itr) {
            h ^= hash_value(*itr);
        }

        return h;
    }

    if(v.IsObject()) {
        std::size_t h = 0;

        for (rapidjson::Value::ConstMemberIterator
                itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {
            h ^= boost::hash<char const *>()(itr->name.GetString());
            h ^= hash_value(itr->value);
        }

        return h;
    }

    if (v.IsString()) {
        return boost::hash<std::string>()(std::string(v.GetString()));
    }

    assert(0);

    return 0;
}

std::size_t hash_value(yajr::rpc::LocalId const & id) {
    return
        boost::hash<MethodName*>()(id.methodName_)
    ^
        boost::hash<uint64_t>()(id.id_)
    ;
}

std::size_t hash_value(yajr::rpc::LocalIdentifier const & id) {
    return boost::hash<yajr::rpc::LocalId>()(id.getLocalId());
}

std::size_t hash_value(yajr::rpc::RemoteIdentifier const & id) {
    return hash_value(id.getRemoteId());
}

MethodName method::unknown("unknown");
MethodName method::echo("echo");
MethodName method::send_identity("send_identity");
MethodName method::policy_resolve("policy_resolve");
MethodName method::policy_unresolve("policy_unresolve");
MethodName method::policy_update("policy_update");
MethodName method::endpoint_declare("endpoint_declare");
MethodName method::endpoint_undeclare("endpoint_undeclare");
MethodName method::endpoint_resolve("endpoint_resolve");
MethodName method::endpoint_unresolve("endpoint_unresolve");
MethodName method::endpoint_update("endpoint_update");
MethodName method::state_report("state_report");

} /* yajr::rpc namespace */
} /* yajr namespace */

<commit_msg>return UV_ENOTCONN when a message is being sent to an offline peer<commit_after>/*
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

/* This must be included before anything else */
#if HAVE_CONFIG_H
#  include <config.h>
#endif

#include <yajr/internal/comms.hpp>
#include <yajr/rpc/methods.hpp>
#include <yajr/rpc/rpc.hpp>

#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>

namespace yajr {
    namespace rpc {

Message::PayloadKeys Message::kPayloadKey = {
    "params",
    "result",
    "error"
};

bool operator< (rapidjson::Value const & l, rapidjson::Value const & r) {

    rapidjson::Type lt = l.GetType();
    rapidjson::Type rt = r.GetType();

    if (lt < rt) {
        return true;
    }

    if (lt > rt) {
        return false;
    }

    /* same type */
    std::size_t lh = hash_value(l);
    std::size_t rh = hash_value(r);

    return (lh < rh);
}

bool OutboundMessage::Accept(yajr::rpc::SendHandler& handler) {

    VLOG(5);

    return handler.StartObject()

        && handler.String("id")
        && emitId(handler)

        && emitMethod(handler)

        && handler.String(getPayloadKey())
        && payloadGenerator_(handler)

        && handler.EndObject()

    ;

}

bool OutboundMessage::send() {

    VLOG(5);

    ::yajr::comms::internal::CommunicationPeer const * cP =
        dynamic_cast< ::yajr::comms::internal::CommunicationPeer const * >
        (peer_);

    assert(cP &&
            "peer needs to be set "
            "to a proper communication peer "
            "before outbound messages are sent");

    unsigned char connected = cP->connected_;

    if (!connected) {
        cP->onError(UV_ENOTCONN);

        assert(connected);

        return false;
    }

    assert(cP->__checkInvariants());

    Accept(cP->getWriter());

    assert(cP->__checkInvariants());

    cP->delimitFrame();

    assert(cP->__checkInvariants());

    cP->write();

    assert(cP->__checkInvariants());

    return true;

}

bool OutboundRequest::send(
        ::yajr::Peer const & peer
    ) {

    VLOG(3);

    setPeer(&peer);

    return send();
}

InboundResponse::InboundResponse(
    yajr::Peer const & peer,             /**< [in] where we received from */
    rapidjson::Value const & response,/**< [in] the error/result received */
    rapidjson::Value const & id          /**< [in] the id of this message */
    )
    :
      InboundMessage(peer, response),
      LocalIdentifier(
              MessageFactory::lookupMethod(
                  id[rapidjson::SizeType(0)].GetString()
                ),
              id[1].GetUint64()
          )
    {}

uv_loop_t const *
yajr::rpc::Message::getUvLoop() const {
    return dynamic_cast< ::yajr::comms::internal::CommunicationPeer const * >
        (getPeer())->getUvLoop();
}

std::size_t hash_value(rapidjson::Value const& v) {

    /* switch(v.GetType()) { <-- would be more efficient but would have to
                                 rely on private stuff from Value */

    if(v.IsDouble()) {
        return boost::hash<double>()(v.GetDouble());
    }

    if(v.IsUint64()) {
        return boost::hash<uint64_t>()(v.GetUint64());
    }

    if(v.IsInt64()) {
        return boost::hash<int64_t>()(v.GetInt64());
    }

    if(v.IsBool()) {
        return boost::hash<bool>()(v.GetBool());
    }

    if(v.IsNull()) {
        return boost::hash<uintptr_t>()(0);
    }

    if(v.IsArray()) {
        std::size_t h = 0;

        for (rapidjson::Value::ConstValueIterator
                itr = v.Begin(); itr != v.End(); ++itr) {
            h ^= hash_value(*itr);
        }

        return h;
    }

    if(v.IsObject()) {
        std::size_t h = 0;

        for (rapidjson::Value::ConstMemberIterator
                itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {
            h ^= boost::hash<char const *>()(itr->name.GetString());
            h ^= hash_value(itr->value);
        }

        return h;
    }

    if (v.IsString()) {
        return boost::hash<std::string>()(std::string(v.GetString()));
    }

    assert(0);

    return 0;
}

std::size_t hash_value(yajr::rpc::LocalId const & id) {
    return
        boost::hash<MethodName*>()(id.methodName_)
    ^
        boost::hash<uint64_t>()(id.id_)
    ;
}

std::size_t hash_value(yajr::rpc::LocalIdentifier const & id) {
    return boost::hash<yajr::rpc::LocalId>()(id.getLocalId());
}

std::size_t hash_value(yajr::rpc::RemoteIdentifier const & id) {
    return hash_value(id.getRemoteId());
}

MethodName method::unknown("unknown");
MethodName method::echo("echo");
MethodName method::send_identity("send_identity");
MethodName method::policy_resolve("policy_resolve");
MethodName method::policy_unresolve("policy_unresolve");
MethodName method::policy_update("policy_update");
MethodName method::endpoint_declare("endpoint_declare");
MethodName method::endpoint_undeclare("endpoint_undeclare");
MethodName method::endpoint_resolve("endpoint_resolve");
MethodName method::endpoint_unresolve("endpoint_unresolve");
MethodName method::endpoint_update("endpoint_update");
MethodName method::state_report("state_report");

} /* yajr::rpc namespace */
} /* yajr namespace */

<|endoftext|>