<commit_before>#ifndef SAVE_STATE_H
# define SAVE_STATE_H
# pragma once

struct statebuf
{
  void* sp;
  void* label;
};

#if defined(__GNUC__)
inline bool __attribute__((always_inline)) savestate(statebuf& ssb) noexcept
{
	bool volatile r;

#if defined(i386) || defined(__i386) || defined(__i386__)
	asm volatile (
		"movl %%esp, %0\n\t" // store sp
		"movl $1f, %1\n\t" // store label
		"movb $0, %2\n\t" // return false
		"jmp 2f\n\t"
		"1:movb $1, %2\n\t" // return true
		"2:"
		: "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
		:
		: "memory"
	);
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
	asm volatile (
		"movq %%rsp, %0\n\t" // store sp
		"movq $1f, %1\n\t" // store label
		"movb $0, %2\n\t" // return false
		"jmp 2f\n\t"
		"1:movb $1, %2\n\t" // return true
		"2:"
		: "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
		:
		: "memory"
	);
#elif defined(__arm__)
  asm volatile (
    "push {r11}\n\t" // push r0
    "str sp, %0\n\t" // store sp
    "ldr r0, =1f\n\t" // load label into r0
    "str r0, %1\n\t" // store r0 into label
    "mov %2, $0\n\t" // store 0 into result
    "b 2f\n\t"
    "1:pop {r11}\n\t"
    "mov %2, $1\n\t" // store 1 into result
    "2:"
    : "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
    :
    : "memory"
  );
#endif

	return r;
}
#elif defined(_MSC_VER)
__forceinline bool savestate(statebuf& ssb) noexcept
{
	bool volatile r;

	__asm {
		push ebp
		mov ebx, ssb
		mov [ebx]ssb.sp, esp
		mov [ebx]ssb.label, offset _1f
		mov r, 0x0
		jmp _2f
		_1f: pop ebp
			 mov r, 0x1
		_2f:
	}

	return r;
}
#else
# error "unsupported compiler"
#endif

#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
#define restorestate(SSB)          \
  asm volatile (                   \
    "movl %0, %%esp\n\t"           \
    "jmp *%1"                      \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
#define restorestate(SSB)          \
  asm volatile (                   \
    "movq %0, %%rsp\n\t"           \
    "jmp *%1"                      \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#elif defined(__arm__)
#define restorestate(SSB)          \
  asm volatile (                   \
    "ldr sp, %0\n\t"               \
    "ldr pc, %1"                   \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#else
# error "unsupported architecture"
#endif
#elif defined(_MSC_VER)
#define restorestate(SSB)   \
  __asm mov ebx, this       \
  __asm add ebx, [SSB]      \
  __asm mov esp, [ebx]SSB.sp\
  __asm jmp [ebx]SSB.label
#else
# error "unsupported compiler"
#endif

#endif // SAVE_STATE_H
<commit_msg>some fixes<commit_after>#ifndef SAVE_STATE_H
# define SAVE_STATE_H
# pragma once

struct statebuf
{
  void* sp;
  void* label;
};

#if defined(__GNUC__)
inline bool __attribute__((always_inline)) savestate(statebuf& ssb) noexcept
{
	bool r;

#if defined(i386) || defined(__i386) || defined(__i386__)
	asm volatile (
		"movl %%esp, %0\n\t" // store sp
		"movl $1f, %1\n\t" // store label
		"movb $0, %2\n\t" // return false
		"jmp 2f\n\t"
		"1:movb $1, %2\n\t" // return true
		"2:"
		: "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
		:
		: "memory"
	);
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
	asm volatile (
		"movq %%rsp, %0\n\t" // store sp
		"movq $1f, %1\n\t" // store label
		"movb $0, %2\n\t" // return false
		"jmp 2f\n\t"
		"1:movb $1, %2\n\t" // return true
		"2:"
		: "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
		:
		: "memory"
	);
#elif defined(__arm__)
  asm volatile (
    "push {r11}\n\t" // push r0
    "str sp, %0\n\t" // store sp
    "ldr r0, =1f\n\t" // load label into r0
    "str r0, %1\n\t" // store r0 into label
    "mov %2, $0\n\t" // store 0 into result
    "b 2f\n\t"
    "1:pop {r11}\n\t"
    "mov %2, $1\n\t" // store 1 into result
    "2:"
    : "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
    :
    : "memory"
  );
#endif

	return r;
}
#elif defined(_MSC_VER)
__forceinline bool savestate(statebuf& ssb) noexcept
{
	bool r;

	__asm {
		push ebp
		mov ebx, ssb
		mov [ebx]ssb.sp, esp
		mov [ebx]ssb.label, offset _1f
		mov r, 0x0
		jmp _2f
		_1f: pop ebp
			 mov r, 0x1
		_2f:
	}

	return r;
}
#else
# error "unsupported compiler"
#endif

#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
#define restorestate(SSB)          \
  asm volatile (                   \
    "movl %0, %%esp\n\t"           \
    "jmp *%1"                      \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
#define restorestate(SSB)          \
  asm volatile (                   \
    "movq %0, %%rsp\n\t"           \
    "jmp *%1"                      \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#elif defined(__arm__)
#define restorestate(SSB)          \
  asm volatile (                   \
    "ldr sp, %0\n\t"               \
    "ldr pc, %1"                   \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#else
# error "unsupported architecture"
#endif
#elif defined(_MSC_VER)
#define restorestate(SSB)   \
  __asm mov ebx, this       \
  __asm add ebx, [SSB]      \
  __asm mov esp, [ebx]SSB.sp\
  __asm jmp [ebx]SSB.label
#else
# error "unsupported compiler"
#endif

#endif // SAVE_STATE_H
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
/// \file  string.cpp
//------------------------------------------------------------------------------
/// \brief Implementation of general purpose functions for string processing
//------------------------------------------------------------------------------
// Copyright (c) 2010 Serge Aleynikov <saleyn@gmail.com>
// Created: 2010-05-06
//------------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file is part of the utxx open-source project.

Copyright (C) 2010 Serge Aleynikov <saleyn@gmail.com>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

***** END LICENSE BLOCK *****
*/

#include <utxx/string.hpp>
#include <utxx/print_opts.hpp>

namespace utxx {

std::string to_bin_string(const char* buf, size_t sz,
                          bool hex, bool readable, bool eol)
{
    std::stringstream out;
    const char* begin = buf, *end = buf + sz;
    print_opts  opts  = hex
                      ? (readable ? print_opts::printable_or_hex : print_opts::hex)
                      : (readable ? print_opts::printable_or_dec : print_opts::dec);
    output(out, begin, end, opts, ",", "", "\"", "<<", ">>");
    if (eol) out << std::endl;
    return out.str();
}

bool wildcard_match(const char* a_input, const char* a_pattern)
{
    const char* ip = nullptr, *pp = nullptr;

    // Match until the first '*' or '?':
    for(; *a_input && *a_pattern != '*'; ++a_pattern, ++a_input)
        if ((*a_pattern != *a_input) && (*a_pattern != '?'))
            return false;

    // Pattern match on everything that follows '*', and exit
    // at the end of the input string
    while (*a_input) {
        if (*a_pattern == '*') {
            if (!*++a_pattern)
                return true;
            // Store state after '*':
            pp = a_pattern;
            ip = a_input+1;
        } else if ((*a_pattern == *a_input) || (*a_pattern == '?')) {
            // Continue successful match
            a_pattern++;
            a_input++;
        } else {
            // Match failed - restore state of pattern after '*':
            a_pattern = pp;
            a_input = ip++;
        }
    }

    // Skip trailing '*' in the pattern, since they don't affect the outcome:
    while (*a_pattern == '*') a_pattern++;

    // Are both input and pattern complete?
    return !*a_pattern;
}

} // namespace utxx
<commit_msg>Move closer to use<commit_after>//------------------------------------------------------------------------------
/// \file  string.cpp
//------------------------------------------------------------------------------
/// \brief Implementation of general purpose functions for string processing
//------------------------------------------------------------------------------
// Copyright (c) 2010 Serge Aleynikov <saleyn@gmail.com>
// Created: 2010-05-06
//------------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file is part of the utxx open-source project.

Copyright (C) 2010 Serge Aleynikov <saleyn@gmail.com>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

***** END LICENSE BLOCK *****
*/

#include <utxx/string.hpp>
#include <utxx/print_opts.hpp>

namespace utxx {

std::string to_bin_string(const char* buf, size_t sz,
                          bool hex, bool readable, bool eol)
{
    std::stringstream out;
    const char* begin = buf, *end = buf + sz;
    print_opts  opts  = hex
                      ? (readable ? print_opts::printable_or_hex : print_opts::hex)
                      : (readable ? print_opts::printable_or_dec : print_opts::dec);
    output(out, begin, end, opts, ",", "", "\"", "<<", ">>");
    if (eol) out << std::endl;
    return out.str();
}

bool wildcard_match(const char* a_input, const char* a_pattern)
{
    // Match until the first '*' or '?':
    for(; *a_input && *a_pattern != '*'; ++a_pattern, ++a_input)
        if ((*a_pattern != *a_input) && (*a_pattern != '?'))
            return false;

    const char* ip = nullptr, *pp = nullptr;

    // Pattern match on everything that follows '*', and exit
    // at the end of the input string
    while (*a_input) {
        if (*a_pattern == '*') {
            if (!*++a_pattern)
                return true;
            // Store state after '*':
            pp = a_pattern;
            ip = a_input+1;
        } else if ((*a_pattern == *a_input) || (*a_pattern == '?')) {
            // Continue successful match
            a_pattern++;
            a_input++;
        } else {
            // Match failed - restore state of pattern after '*':
            a_pattern = pp;
            a_input = ip++;
        }
    }

    // Skip trailing '*' in the pattern, since they don't affect the outcome:
    while (*a_pattern == '*') a_pattern++;

    // Are both input and pattern complete?
    return !*a_pattern;
}

} // namespace utxx
<|endoftext|>


<commit_before>#include "subcommand.hpp"
#include "../vg.hpp"
#include "../utility.hpp"
#include "../counter.hpp"
#include "../stream.hpp"

#include <unistd.h>
#include <getopt.h>

using namespace vg;
using namespace vg::subcommand;

void help_count(char** argv) {
    cerr << "usage: " << argv[0] << " count [options]" << endl
         << "options:" << endl
         << "    -x, --xg FILE          use this basis graph" << endl
         << "    -o, --counts-out FILE  write compressed coverage counts to this output file" << endl
         << "    -i, --counts-in FILE   begin by summing coverage counts from each provided FILE" << endl
         << "    -g, --gam FILE         read alignments from this file (could be '-' for stdin)" << endl
         << "    -d, --as-table         write table on stdout representing counts" << endl
         << "    -n, --no-edits         don't record or write edits, just graph-matching coverage" << endl
         << "    -t, --threads N        use N threads (defaults to numCPUs)" << endl;
}

int main_count(int argc, char** argv) {

    string xg_name;
    vector<string> counts_in;
    string counts_out;
    string gam_in;
    bool write_table = false;
    int thread_count = 1;
    bool record_edits = true;

    if (argc == 2) {
        help_count(argv);
        return 1;
    }

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"help", no_argument, 0, 'h'},
            {"xg", required_argument,0, 'x'},
            {"counts-out", required_argument,0, 'o'},
            {"count-in", required_argument, 0, 'i'},
            {"gam", required_argument, 0, 'g'},
            {"as-table", no_argument, 0, 'd'},
            {"threads", required_argument, 0, 't'},
            {"no-edits", no_argument, 0, 'n'},
            {0, 0, 0, 0}

        };
        int option_index = 0;
        c = getopt_long (argc, argv, "hx:o:i:g:dt:n",
                long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {

        case '?':
        case 'h':
            help_count(argv);
            return 1;
        case 'x':
            xg_name = optarg;
            break;
        case 'o':
            counts_out = optarg;
            break;
        case 'i':
            counts_in.push_back(optarg);
            break;
        case 'g':
            gam_in = optarg;
            break;
        case 'd':
            write_table = true;
            break;
        case 'n':
            record_edits = false;
            break;
        case 't':
            thread_count = atoi(optarg);
            break;

        default:
            abort();
        }
    }

    omp_set_num_threads(thread_count);

    xg::XG xgidx;
    if (xg_name.empty()) {
        cerr << "No XG index given. An XG index must be provided." << endl;
        exit(1);
    } else {
        ifstream in(xg_name.c_str());
        xgidx.load(in);
    }

    // todo one counter per thread and merge
    vg::Counter counter(&xgidx);
    if (!counts_in.empty()) {
        counter.load_from_file(counts_in.front());
    }

    if (!gam_in.empty()) {
        ifstream gam_stream(gam_in);
        std::function<void(Alignment&)> lambda = [&counter,&record_edits](Alignment& aln) { counter.add(aln, record_edits); };
        stream::for_each(gam_stream, lambda);
        gam_stream.close();
    }
    if (!counts_out.empty()) {
        counter.save_to_file(counts_out);
    }
    if (write_table) {
        counter.make_compact();
        counter.as_table(cout, record_edits);
    }

    return 0;
}

// Register subcommand
static Subcommand vg_count("count", "count features on the graph", main_count);
<commit_msg>count: enable reading gam from stdin<commit_after>#include "subcommand.hpp"
#include "../vg.hpp"
#include "../utility.hpp"
#include "../counter.hpp"
#include "../stream.hpp"

#include <unistd.h>
#include <getopt.h>

using namespace vg;
using namespace vg::subcommand;

void help_count(char** argv) {
    cerr << "usage: " << argv[0] << " count [options]" << endl
         << "options:" << endl
         << "    -x, --xg FILE          use this basis graph" << endl
         << "    -o, --counts-out FILE  write compressed coverage counts to this output file" << endl
         << "    -i, --counts-in FILE   begin by summing coverage counts from each provided FILE" << endl
         << "    -g, --gam FILE         read alignments from this file (could be '-' for stdin)" << endl
         << "    -d, --as-table         write table on stdout representing counts" << endl
         << "    -n, --no-edits         don't record or write edits, just graph-matching coverage" << endl
         << "    -t, --threads N        use N threads (defaults to numCPUs)" << endl;
}

int main_count(int argc, char** argv) {

    string xg_name;
    vector<string> counts_in;
    string counts_out;
    string gam_in;
    bool write_table = false;
    int thread_count = 1;
    bool record_edits = true;

    if (argc == 2) {
        help_count(argv);
        return 1;
    }

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"help", no_argument, 0, 'h'},
            {"xg", required_argument,0, 'x'},
            {"counts-out", required_argument,0, 'o'},
            {"count-in", required_argument, 0, 'i'},
            {"gam", required_argument, 0, 'g'},
            {"as-table", no_argument, 0, 'd'},
            {"threads", required_argument, 0, 't'},
            {"no-edits", no_argument, 0, 'n'},
            {0, 0, 0, 0}

        };
        int option_index = 0;
        c = getopt_long (argc, argv, "hx:o:i:g:dt:n",
                long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {

        case '?':
        case 'h':
            help_count(argv);
            return 1;
        case 'x':
            xg_name = optarg;
            break;
        case 'o':
            counts_out = optarg;
            break;
        case 'i':
            counts_in.push_back(optarg);
            break;
        case 'g':
            gam_in = optarg;
            break;
        case 'd':
            write_table = true;
            break;
        case 'n':
            record_edits = false;
            break;
        case 't':
            thread_count = atoi(optarg);
            break;

        default:
            abort();
        }
    }

    omp_set_num_threads(thread_count);

    xg::XG xgidx;
    if (xg_name.empty()) {
        cerr << "No XG index given. An XG index must be provided." << endl;
        exit(1);
    } else {
        ifstream in(xg_name.c_str());
        xgidx.load(in);
    }

    // todo one counter per thread and merge
    vg::Counter counter(&xgidx);
    if (!counts_in.empty()) {
        counter.load_from_file(counts_in.front());
    }

    if (!gam_in.empty()) {
        std::function<void(Alignment&)> lambda = [&counter,&record_edits](Alignment& aln) { counter.add(aln, record_edits); };
        if (gam_in == "-") {
            stream::for_each(std::cin, lambda);
        } else {
            ifstream gam_stream(gam_in);
            stream::for_each(gam_stream, lambda);
            gam_stream.close();
        }
    }
    if (!counts_out.empty()) {
        counter.save_to_file(counts_out);
    }
    if (write_table) {
        counter.make_compact();
        counter.as_table(cout, record_edits);
    }

    return 0;
}

// Register subcommand
static Subcommand vg_count("count", "count features on the graph", main_count);
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// File: cmnserver.hpp
//
// Desc: Common HTTP server - HTTP server for all application
//
// Copyright (c) 2014-2018 opencvr.com. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __VSC_CMN_SERVER__H_
#define __VSC_CMN_SERVER__H_
#include "utility.hpp"
#include "debug.hpp"
#include <QThread>

#include "XSDK/XHash.h"
#include "XSDK/TimeUtils.h"
#include "XSDK/XSocket.h"
#include "XSDK/XSSLSocket.h"
#include "Webby/ClientSideRequest.h"
#include "Webby/ClientSideResponse.h"
#include "Webby/ServerSideRequest.h"
#include "Webby/ServerSideResponse.h"
#include "Webby/WebbyException.h"

using namespace std;
using namespace XSDK;
using namespace WEBBY;

/* each app can register a http REST path can move
   the socket to itself, for streaming, it it for performance.
*/

using namespace UtilityLib;

class CmnHttpServer:public QThread
{
	Q_OBJECT
public:
	inline CmnHttpServer(u16 port);
	inline ~CmnHttpServer();

public:
	void Lock()
	{
		m_Lock.lock();
	}
	void UnLock()
	{
		m_Lock.unlock();
	}
public:
	inline void run();

private:
	fast_mutex m_Lock;
	u16 m_port;
};

class CmnHttpsServer:public QThread
{
	Q_OBJECT
public:
	inline CmnHttpsServer(u16 port);
	inline ~CmnHttpsServer();

public:
	void Lock()
	{
		m_Lock.lock();
	}
	void UnLock()
	{
		m_Lock.unlock();
	}
public:
	inline void run();

private:
	fast_mutex m_Lock;
	u16 m_port;
};

typedef CmnHttpServer* LPCmnHttpServer;
typedef CmnHttpsServer* LPCmnHttpsServer;

#include "cmnserverimpl.hpp"

#endif /* __VSC_CMN_SERVER__H_ */

<commit_msg>add oapi.hpp<commit_after>//------------------------------------------------------------------------------
// File: cmnserver.hpp
//
// Desc: Common HTTP server - HTTP server for all application
//
// Copyright (c) 2014-2018 opencvr.com. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __VSC_CMN_SERVER__H_
#define __VSC_CMN_SERVER__H_
#include "utility.hpp"
#include "debug.hpp"
#include <QThread>

#include "XSDK/XHash.h"
#include "XSDK/TimeUtils.h"
#include "XSDK/XSocket.h"
#include "XSDK/XSSLSocket.h"
#include "Webby/ClientSideRequest.h"
#include "Webby/ClientSideResponse.h"
#include "Webby/ServerSideRequest.h"
#include "Webby/ServerSideResponse.h"
#include "Webby/WebbyException.h"

#include "oapi.hpp"

using namespace std;
using namespace XSDK;
using namespace WEBBY;

/* each app can register a http REST path can move
   the socket to itself, for streaming, it it for performance.
*/

using namespace UtilityLib;

class CmnHttpServer:public QThread
{
	Q_OBJECT
public:
	inline CmnHttpServer(u16 port);
	inline ~CmnHttpServer();

public:
	void Lock()
	{
		m_Lock.lock();
	}
	void UnLock()
	{
		m_Lock.unlock();
	}
public:
	inline void run();

private:
	fast_mutex m_Lock;
	u16 m_port;
};

class CmnHttpsServer:public QThread
{
	Q_OBJECT
public:
	inline CmnHttpsServer(u16 port);
	inline ~CmnHttpsServer();

public:
	void Lock()
	{
		m_Lock.lock();
	}
	void UnLock()
	{
		m_Lock.unlock();
	}
public:
	inline void run();

private:
	fast_mutex m_Lock;
	u16 m_port;
};

typedef CmnHttpServer* LPCmnHttpServer;
typedef CmnHttpsServer* LPCmnHttpsServer;

#include "cmnserverimpl.hpp"

#endif /* __VSC_CMN_SERVER__H_ */

<|endoftext|>


<commit_before>// Prints the tag of a audio file
// mp3, m4a ogg and flac supported

// Bilal Hussain

// install:
//  g++ `taglib-config  --cflags --libs`  taginfo.cpp  -o taginfo
// or
// g++ -ltag -I/usr/local/include/taglib -L/usr/local/lib  taginfo.cpp  -o taginfo
// if no taglib-config

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <tag.h>
#include <fileref.h>

void usage() {
	fprintf(stderr, "taginfo \n");
	fprintf(stderr, "Usage: taginfo <file(s)>\n");
	fprintf(stderr, "Usage: taginfo --short   <file>\n");
	fprintf(stderr, "Usage: taginfo --info    <file>\n");
	fprintf(stderr, "Usage: taginfo --details <file> <current_secs>\n");
	fprintf(stderr, "Usage: taginfo --details-colour <file> <current_secs>\n");
}

int main(int argc, char *argv[]) {
	if(argc < 2) {
		usage();
		exit(1);
	}

	if (argc == 3  && strcmp("--short", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);

		printf("%s\n", f.tag()->title().toCString(true));
		printf("%s\n", f.tag()->album().toCString(true));
		printf("%s\n", f.tag()->artist().toCString(true));
		int time = f.audioProperties()->length();
		printf("%d:%d\n", (time%3600/60), (time%60) );
		exit(0);
	}

	else if (argc == 3  && strcmp("--info", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);

		printf("%s - %02d %s - %s\n",
			f.tag()->artist().toCString(true),
			f.tag()->track(),
			f.tag()->title().toCString(true),
			f.tag()->album().toCString(true)
		);
		exit(0);
	}

	else if (argc == 4  && strcmp("--details", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);
		long start_time = strtol(argv[3],NULL,10);
		const int end_time = f.audioProperties()->length();

		printf("%s - %02d %s - %s -  %ld:%02ld/%d:%02d\n",
			f.tag()->artist().toCString(true),
			f.tag()->track(),
			f.tag()->title().toCString(true),
			f.tag()->album().toCString(true),
			(start_time%3600/60), (start_time%60),
			(end_time%3600/60),   (end_time%60)
		);
		exit(0);
	}

	else if (argc == 4  && strcmp("--details-colour", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);
		long start_time = strtol(argv[3],NULL,10);
		const int end_time = f.audioProperties()->length();

		// adds %s before and after
		#define SSS(str) "%s" str "%s"
		#define BLUE         "\033[34m"             // Blue
		#define RED          "\033[31m"             // Red
		#define GREEN        "\033[32m"             // Green
		#define RESET        "\033[0m"              // Need before and after
		#define COLOUR(string, colour) RESET colour, string, RESET

		printf("%s - %02d " SSS("%s") " - %s -  %ld:%02ld/%d:%02d\n",
			f.tag()->artist().toCString(true),
			f.tag()->track(),
			COLOUR(f.tag()->title().toCString(true),BLUE),
			f.tag()->album().toCString(true),
			(start_time%3600/60), (start_time%60),
			(end_time%3600/60),   (end_time%60)
		);
		exit(0);
	}

	for(int i = 1; i < argc; i++) {
		TagLib::FileRef f(argv[i]);
		if(!f.isNull() && f.tag()) {
			printf("FILE=\"%s\"\n", argv[i]);
			printf("ALBUM=\"%s\"\n", f.tag()->album().toCString(true));
			printf("TRACK=\"%d\"\n", f.tag()->track());
			printf("ARTIST=\"%s\"\n", f.tag()->artist().toCString(true));
			printf("TITLE=\"%s\"\n", f.tag()->title().toCString(true));
			printf("GENRE=\"%s\"\n", f.tag()->genre().toCString(true));
			printf("YEAR=\"%d\"\n", f.tag()->year());
			printf("COMMENT=\"%s\"\n", f.tag()->comment().toCString(true));
			printf("LENGTH=\"%d\"\n", f.audioProperties()->length());
			printf("BITRATE=\"%d\"\n", f.audioProperties()->bitrate());
			printf("SAMPLERATE=\"%d\"\n", f.audioProperties()->sampleRate());
			printf("CHANNELS=\"%d\"\n\n", f.audioProperties()->channels());
		} else {
			fprintf(stderr, "Error opening file: %s\n", argv[i]);
		}
	}

	return 0;
}
<commit_msg>pretty print<commit_after>// Prints the tag of a audio file
// mp3, m4a ogg and flac supported

// Bilal Hussain

// install:
//  g++ `taglib-config  --cflags --libs`  taginfo.cpp  -o taginfo
// or
// g++ -ltag -I/usr/local/include/taglib -L/usr/local/lib  taginfo.cpp  -o taginfo
// if no taglib-config

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <tag.h>
#include <fileref.h>

void usage() {
	fprintf(stderr, "taginfo \n");
	fprintf(stderr, "Usage: taginfo <file(s)>\n");
	fprintf(stderr, "Usage: taginfo --short   <file>\n");
	fprintf(stderr, "Usage: taginfo --info    <file>\n");
	fprintf(stderr, "Usage: taginfo --pretty  <file> \n");
	fprintf(stderr, "Usage: taginfo --pretty  <file> <current_secs>\n");
	fprintf(stderr, "Usage: taginfo --details <file> <current_secs>\n");
	fprintf(stderr, "Usage: taginfo --details-colour <file> <current_secs>\n");
}

// adds %s before and after
#define SSS(str) "%s" str "%s"
#define S3 "%s%s%s"
#define BLUE         "\033[34m"             // Blue
#define RED          "\033[31m"             // Red
#define GREEN        "\033[32m"             // Green
#define RESET        "\033[0m"              // Need before and after
#define COLOUR(string, colour)  RESET colour, string, RESET
#define COLOURN(string, colour) string

int main(int argc, char *argv[]) {
	if(argc < 2) {
		usage();
		exit(1);
	}

	if (argc == 3  && strcmp("--short", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);

		printf("%s\n", f.tag()->title().toCString(true));
		printf("%s\n", f.tag()->album().toCString(true));
		printf("%s\n", f.tag()->artist().toCString(true));
		int time = f.audioProperties()->length();
		printf("%d:%d\n", (time%3600/60), (time%60) );
		exit(0);
	}

	else if (argc == 3  && strcmp("--info", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);

		printf("%s - %02d %s - %s\n",
			f.tag()->artist().toCString(true),
			f.tag()->track(),
			f.tag()->title().toCString(true),
			f.tag()->album().toCString(true)
		);
		exit(0);
	}

	else if (argc == 4  && strcmp("--details", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);
		long start_time = strtol(argv[3],NULL,10);
		const int end_time = f.audioProperties()->length();

		printf("%s - %02d %s - %s -  %ld:%02ld/%d:%02d\n",
			f.tag()->artist().toCString(true),
			f.tag()->track(),
			f.tag()->title().toCString(true),
			f.tag()->album().toCString(true),
			(start_time%3600/60), (start_time%60),
			(end_time%3600/60),   (end_time%60)
		);
		exit(0);
	}

	else if (argc == 4  && strcmp("--details-colour", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);
		long start_time = strtol(argv[3],NULL,10);
		const int end_time = f.audioProperties()->length();

		printf("%s - %02d " SSS("%s") " - %s -  %ld:%02ld/%d:%02d\n",
			f.tag()->artist().toCString(true),
			f.tag()->track(),
			COLOUR(f.tag()->title().toCString(true),BLUE),
			f.tag()->album().toCString(true),
			(start_time%3600/60), (start_time%60),
			(end_time%3600/60),   (end_time%60)
		);
		exit(0);
	}

	else if (argc == 4  && strcmp("--pretty", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);
		long start_time = strtol(argv[3],NULL,10);
		const int end_time = f.audioProperties()->length();

	 // Track : Faraway ★★★★★
	 // Album : Day After Tomorrow
	 // Artist: Day After Tomorrow
	 // Time  : 5:00/5:84

		printf(
			"Track  : %d - " S3 "\n"
			"Album  : %s\n"
			"Artist : %s\n"
			"Time   : %ld:%02ld/%d:%02d\n",

			f.tag()->track(), COLOUR(f.tag()->title().toCString(true),BLUE),
			f.tag()->artist().toCString(true),
			f.tag()->album().toCString(true),

			(start_time%3600/60), (start_time%60), (end_time%3600/60), (end_time%60)
		);

		exit(0);
	}

	else if (argc == 3  && strcmp("--pretty", argv[1]) == 0){
		TagLib::FileRef f(argv[2]);
		const int end_time = f.audioProperties()->length();

	 // Track : Faraway ★★★★★
	 // Album : Day After Tomorrow
	 // Artist: Day After Tomorrow
	 // Time  : 5:00/5:84

		printf(
			"Track  : %d - " S3 "\n"
			"Album  : %s\n"
			"Artist : %s\n"
			"Time   : %d:%02d\n",

			f.tag()->track(), COLOUR(f.tag()->title().toCString(true),BLUE),
			f.tag()->artist().toCString(true),
			f.tag()->album().toCString(true),
			(end_time%3600/60), (end_time%60)
		);

		exit(0);
	}

	for(int i = 1; i < argc; i++) {
		TagLib::FileRef f(argv[i]);
		if(!f.isNull() && f.tag()) {
			printf("FILE=\"%s\"\n", argv[i]);
			printf("ALBUM=\"%s\"\n", f.tag()->album().toCString(true));
			printf("TRACK=\"%d\"\n", f.tag()->track());
			printf("ARTIST=\"%s\"\n", f.tag()->artist().toCString(true));
			printf("TITLE=\"%s\"\n", f.tag()->title().toCString(true));
			printf("GENRE=\"%s\"\n", f.tag()->genre().toCString(true));
			printf("YEAR=\"%d\"\n", f.tag()->year());
			printf("COMMENT=\"%s\"\n", f.tag()->comment().toCString(true));
			printf("LENGTH=\"%d\"\n", f.audioProperties()->length());
			printf("BITRATE=\"%d\"\n", f.audioProperties()->bitrate());
			printf("SAMPLERATE=\"%d\"\n", f.audioProperties()->sampleRate());
			printf("CHANNELS=\"%d\"\n\n", f.audioProperties()->channels());
		} else {
			fprintf(stderr, "Error opening file: %s\n", argv[i]);
		}
	}

	return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and 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 <Spinlock.h>
#include <processor/Processor.h>

#ifdef TRACK_LOCKS
#include <LocksCommand.h>
#endif

#include <panic.h>

void Spinlock::acquire()
{
  // Save the current irq status.

  // This save to local variable prevents a heinous race condition where the thread is
  // preempted between the getInterrupts and setInterrupts, then this same spinlock is called
  // in the new thread with interrupts disabled. It gets back to us, and m_bInterrupts==false.
  // Oh dear, hanging time.
  //
  // We write to a local so the interrupt value is saved onto the stack until interrupts are
  // definately disabled; then we can write it back to the member variable.
  bool bInterrupts = Processor::getInterrupts();

  // Disable irqs if not already done
  if (bInterrupts)
    Processor::setInterrupts(false);

  if (m_Magic != 0xdeadbaba)
  {
      FATAL("Wrong magic in acquire.");
  }

  while (m_Atom.compareAndSwap(true, false) == false)
  {
#ifndef MULTIPROCESSOR
    /// \note When we hit this breakpoint, we're not able to backtrace as backtracing
    ///       depends on the log spinlock, which may have deadlocked. So we actually
    ///       force the spinlock to release here, then hit the breakpoint.
      size_t atom = m_Atom;
      m_Atom = true;

    // Break into the debugger, with the return address in EAX to make debugging easier
#ifdef X86
      FATAL_NOLOCK("Spinlock has deadlocked, return address of other locker is " << m_Ra << ", spinlock is " << reinterpret_cast<uintptr_t>(this) << ", atom is " << atom << ".");
    // asm volatile("mov %0, %%eax; mov %1, %%ebx; int3" : : "r"(reinterpret_cast<uintptr_t>(this)), "r"(atom));
#endif
#ifdef X64
    asm volatile("mov %0, %%rax; mov %1, %%rbx; int3" : : "r"(reinterpret_cast<uintptr_t>(this)), "r"(atom));
#endif

    // Panic in case there's a return from the debugger (or the debugger isn't available)
    panic("Spinlock has deadlocked");
#endif
  }
  m_Ra = reinterpret_cast<uintptr_t>(__builtin_return_address(0));

#ifdef TRACK_LOCKS
//  if (!m_bAvoidTracking)
      g_LocksCommand.lockAcquired(this);
#endif

  m_bInterrupts = bInterrupts;

}
void Spinlock::release()
{
  bool bWasInterrupts = Processor::getInterrupts();
  if (bWasInterrupts == true)
  {
      FATAL("Spinlock: release() called with interrupts enabled.");
  }
  bool bInterrupts = m_bInterrupts;

  if (m_Magic != 0xdeadbaba)
  {
      FATAL("Wrong magic in release.");
  }

  if (m_Atom.compareAndSwap(false, true) == false)
  {
      /// \note When we hit this breakpoint, we're not able to backtrace as backtracing
    ///       depends on the log spinlock, which may have deadlocked. So we actually
    ///       force the spinlock to release here, then hit the breakpoint.
    m_Atom = true;

    // Break into the debugger, with the return address in EAX to make debugging easier
#ifdef X86
    asm volatile("mov %0, %%eax; mov %1, %%ebx; int3" : : "r"(reinterpret_cast<uintptr_t>(this)), "m"(m_Atom));
#endif
#ifdef X64
    asm volatile("mov %0, %%rax; mov %1, %%rbx; int3" : : "r"(reinterpret_cast<uintptr_t>(this)), "m"(m_Atom));
#endif

    // Panic in case there's a return from the debugger (or the debugger isn't available)
    panic("Spinlock has deadlocked");
  }

#ifdef TRACK_LOCKS
//  if (!m_bAvoidTracking)
    g_LocksCommand.lockReleased(this);
#endif

  // Reenable irqs if they were enabled before
  if (bInterrupts)
  {
    Processor::setInterrupts(true);
  }
}
<commit_msg>Add Log.h to list of includes in Spinlock.cc. Previously assumed that other headers would indirectly include Log.h<commit_after>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and 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 <Spinlock.h>
#include <processor/Processor.h>

#ifdef TRACK_LOCKS
#include <LocksCommand.h>
#endif

#include <Log.h>

#include <panic.h>

void Spinlock::acquire()
{
  // Save the current irq status.

  // This save to local variable prevents a heinous race condition where the thread is
  // preempted between the getInterrupts and setInterrupts, then this same spinlock is called
  // in the new thread with interrupts disabled. It gets back to us, and m_bInterrupts==false.
  // Oh dear, hanging time.
  //
  // We write to a local so the interrupt value is saved onto the stack until interrupts are
  // definately disabled; then we can write it back to the member variable.
  bool bInterrupts = Processor::getInterrupts();

  // Disable irqs if not already done
  if (bInterrupts)
    Processor::setInterrupts(false);

  if (m_Magic != 0xdeadbaba)
  {
      FATAL("Wrong magic in acquire.");
  }

  while (m_Atom.compareAndSwap(true, false) == false)
  {
#ifndef MULTIPROCESSOR
    /// \note When we hit this breakpoint, we're not able to backtrace as backtracing
    ///       depends on the log spinlock, which may have deadlocked. So we actually
    ///       force the spinlock to release here, then hit the breakpoint.
      size_t atom = m_Atom;
      m_Atom = true;

    // Break into the debugger, with the return address in EAX to make debugging easier
#ifdef X86
      FATAL_NOLOCK("Spinlock has deadlocked, return address of other locker is " << m_Ra << ", spinlock is " << reinterpret_cast<uintptr_t>(this) << ", atom is " << atom << ".");
    // asm volatile("mov %0, %%eax; mov %1, %%ebx; int3" : : "r"(reinterpret_cast<uintptr_t>(this)), "r"(atom));
#endif
#ifdef X64
    asm volatile("mov %0, %%rax; mov %1, %%rbx; int3" : : "r"(reinterpret_cast<uintptr_t>(this)), "r"(atom));
#endif

    // Panic in case there's a return from the debugger (or the debugger isn't available)
    panic("Spinlock has deadlocked");
#endif
  }
  m_Ra = reinterpret_cast<uintptr_t>(__builtin_return_address(0));

#ifdef TRACK_LOCKS
//  if (!m_bAvoidTracking)
      g_LocksCommand.lockAcquired(this);
#endif

  m_bInterrupts = bInterrupts;

}
void Spinlock::release()
{
  bool bWasInterrupts = Processor::getInterrupts();
  if (bWasInterrupts == true)
  {
      FATAL("Spinlock: release() called with interrupts enabled.");
  }
  bool bInterrupts = m_bInterrupts;

  if (m_Magic != 0xdeadbaba)
  {
      FATAL("Wrong magic in release.");
  }

  if (m_Atom.compareAndSwap(false, true) == false)
  {
      /// \note When we hit this breakpoint, we're not able to backtrace as backtracing
    ///       depends on the log spinlock, which may have deadlocked. So we actually
    ///       force the spinlock to release here, then hit the breakpoint.
    m_Atom = true;

    // Break into the debugger, with the return address in EAX to make debugging easier
#ifdef X86
    asm volatile("mov %0, %%eax; mov %1, %%ebx; int3" : : "r"(reinterpret_cast<uintptr_t>(this)), "m"(m_Atom));
#endif
#ifdef X64
    asm volatile("mov %0, %%rax; mov %1, %%rbx; int3" : : "r"(reinterpret_cast<uintptr_t>(this)), "m"(m_Atom));
#endif

    // Panic in case there's a return from the debugger (or the debugger isn't available)
    panic("Spinlock has deadlocked");
  }

#ifdef TRACK_LOCKS
//  if (!m_bAvoidTracking)
    g_LocksCommand.lockReleased(this);
#endif

  // Reenable irqs if they were enabled before
  if (bInterrupts)
  {
    Processor::setInterrupts(true);
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2002-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.
 *
 * Authors: Steve Reinhardt
 */

#include "arch/utility.hh"
#include "arch/faults.hh"
#include "base/cprintf.hh"
#include "base/inifile.hh"
#include "base/loader/symtab.hh"
#include "base/misc.hh"
#include "base/pollevent.hh"
#include "base/range.hh"
#include "base/stats/events.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "cpu/profile.hh"
#include "cpu/simple/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/smt.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/debug.hh"
#include "sim/host.hh"
#include "sim/sim_events.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
#include "sim/system.hh"

#if FULL_SYSTEM
#include "arch/kernel_stats.hh"
#include "arch/stacktrace.hh"
#include "arch/tlb.hh"
#include "arch/vtophys.hh"
#include "base/remote_gdb.hh"
#else // !FULL_SYSTEM
#include "mem/mem_object.hh"
#endif // FULL_SYSTEM

using namespace std;
using namespace TheISA;

BaseSimpleCPU::BaseSimpleCPU(Params *p)
    : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
{
#if FULL_SYSTEM
    thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
#else
    thread = new SimpleThread(this, /* thread_num */ 0, p->process,
            /* asid */ 0);
#endif // !FULL_SYSTEM

    thread->setStatus(ThreadContext::Unallocated);

    tc = thread->getTC();

    numInst = 0;
    startNumInst = 0;
    numLoad = 0;
    startNumLoad = 0;
    lastIcacheStall = 0;
    lastDcacheStall = 0;

    threadContexts.push_back(tc);

    fetchOffset = 0;
    stayAtPC = false;
}

BaseSimpleCPU::~BaseSimpleCPU()
{
}

void
BaseSimpleCPU::deallocateContext(int thread_num)
{
    // for now, these are equivalent
    suspendContext(thread_num);
}

void
BaseSimpleCPU::haltContext(int thread_num)
{
    // for now, these are equivalent
    suspendContext(thread_num);
}

void
BaseSimpleCPU::regStats()
{
    using namespace Stats;

    BaseCPU::regStats();

    numInsts
        .name(name() + ".num_insts")
        .desc("Number of instructions executed")
        ;

    numMemRefs
        .name(name() + ".num_refs")
        .desc("Number of memory references")
        ;

    notIdleFraction
        .name(name() + ".not_idle_fraction")
        .desc("Percentage of non-idle cycles")
        ;

    idleFraction
        .name(name() + ".idle_fraction")
        .desc("Percentage of idle cycles")
        ;

    icacheStallCycles
        .name(name() + ".icache_stall_cycles")
        .desc("ICache total stall cycles")
        .prereq(icacheStallCycles)
        ;

    dcacheStallCycles
        .name(name() + ".dcache_stall_cycles")
        .desc("DCache total stall cycles")
        .prereq(dcacheStallCycles)
        ;

    icacheRetryCycles
        .name(name() + ".icache_retry_cycles")
        .desc("ICache total retry cycles")
        .prereq(icacheRetryCycles)
        ;

    dcacheRetryCycles
        .name(name() + ".dcache_retry_cycles")
        .desc("DCache total retry cycles")
        .prereq(dcacheRetryCycles)
        ;

    idleFraction = constant(1.0) - notIdleFraction;
}

void
BaseSimpleCPU::resetStats()
{
//    startNumInst = numInst;
    // notIdleFraction = (_status != Idle);
}

void
BaseSimpleCPU::serialize(ostream &os)
{
    BaseCPU::serialize(os);
//    SERIALIZE_SCALAR(inst);
    nameOut(os, csprintf("%s.xc.0", name()));
    thread->serialize(os);
}

void
BaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
    BaseCPU::unserialize(cp, section);
//    UNSERIALIZE_SCALAR(inst);
    thread->unserialize(cp, csprintf("%s.xc.0", section));
}

void
change_thread_state(int thread_number, int activate, int priority)
{
}

Fault
BaseSimpleCPU::copySrcTranslate(Addr src)
{
#if 0
    static bool no_warn = true;
    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
    // Only support block sizes of 64 atm.
    assert(blk_size == 64);
    int offset = src & (blk_size - 1);

    // Make sure block doesn't span page
    if (no_warn &&
        (src & PageMask) != ((src + blk_size) & PageMask) &&
        (src >> 40) != 0xfffffc) {
        warn("Copied block source spans pages %x.", src);
        no_warn = false;
    }

    memReq->reset(src & ~(blk_size - 1), blk_size);

    // translate to physical address
    Fault fault = thread->translateDataReadReq(req);

    if (fault == NoFault) {
        thread->copySrcAddr = src;
        thread->copySrcPhysAddr = memReq->paddr + offset;
    } else {
        assert(!fault->isAlignmentFault());

        thread->copySrcAddr = 0;
        thread->copySrcPhysAddr = 0;
    }
    return fault;
#else
    return NoFault;
#endif
}

Fault
BaseSimpleCPU::copy(Addr dest)
{
#if 0
    static bool no_warn = true;
    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
    // Only support block sizes of 64 atm.
    assert(blk_size == 64);
    uint8_t data[blk_size];
    //assert(thread->copySrcAddr);
    int offset = dest & (blk_size - 1);

    // Make sure block doesn't span page
    if (no_warn &&
        (dest & PageMask) != ((dest + blk_size) & PageMask) &&
        (dest >> 40) != 0xfffffc) {
        no_warn = false;
        warn("Copied block destination spans pages %x. ", dest);
    }

    memReq->reset(dest & ~(blk_size -1), blk_size);
    // translate to physical address
    Fault fault = thread->translateDataWriteReq(req);

    if (fault == NoFault) {
        Addr dest_addr = memReq->paddr + offset;
        // Need to read straight from memory since we have more than 8 bytes.
        memReq->paddr = thread->copySrcPhysAddr;
        thread->mem->read(memReq, data);
        memReq->paddr = dest_addr;
        thread->mem->write(memReq, data);
        if (dcacheInterface) {
            memReq->cmd = Copy;
            memReq->completionEvent = NULL;
            memReq->paddr = thread->copySrcPhysAddr;
            memReq->dest = dest_addr;
            memReq->size = 64;
            memReq->time = curTick;
            memReq->flags &= ~INST_READ;
            dcacheInterface->access(memReq);
        }
    }
    else
        assert(!fault->isAlignmentFault());

    return fault;
#else
    panic("copy not implemented");
    return NoFault;
#endif
}

#if FULL_SYSTEM
Addr
BaseSimpleCPU::dbg_vtophys(Addr addr)
{
    return vtophys(tc, addr);
}
#endif // FULL_SYSTEM

#if FULL_SYSTEM
void
BaseSimpleCPU::post_interrupt(int int_num, int index)
{
    BaseCPU::post_interrupt(int_num, index);

    if (thread->status() == ThreadContext::Suspended) {
                DPRINTF(Quiesce,"Suspended Processor awoke\n");
        thread->activate();
    }
}
#endif // FULL_SYSTEM

void
BaseSimpleCPU::checkForInterrupts()
{
#if FULL_SYSTEM
    if (check_interrupts(tc)) {
        Fault interrupt = interrupts.getInterrupt(tc);

        if (interrupt != NoFault) {
            interrupts.updateIntrInfo(tc);
            interrupt->invoke(tc);
        }
    }
#endif
}

Fault
BaseSimpleCPU::setupFetchRequest(Request *req)
{
    uint64_t threadPC = thread->readPC();

    // set up memory request for instruction fetch
#if ISA_HAS_DELAY_SLOT
    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC,
            thread->readNextPC(),thread->readNextNPC());
#else
    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",threadPC,
            thread->readNextPC());
#endif

    const Addr PCMask = ~(sizeof(MachInst) - 1);
    Addr fetchPC = thread->readPC() + fetchOffset;
    req->setVirt(0, fetchPC & PCMask, sizeof(MachInst), 0, threadPC());

    Fault fault = thread->translateInstReq(req);

    return fault;
}

void
BaseSimpleCPU::preExecute()
{
    // maintain $r0 semantics
    thread->setIntReg(ZeroReg, 0);
#if THE_ISA == ALPHA_ISA
    thread->setFloatReg(ZeroReg, 0.0);
#endif // ALPHA_ISA

    // keep an instruction count
    numInst++;
    numInsts++;

    thread->funcExeInst++;

    // check for instruction-count-based events
    comInstEventQueue[0]->serviceEvents(numInst);

    // decode the instruction
    inst = gtoh(inst);

    //If we're not in the middle of a macro instruction
    if (!curMacroStaticInst) {

        StaticInstPtr instPtr = NULL;

        //Predecode, ie bundle up an ExtMachInst
        //This should go away once the constructor can be set up properly
        predecoder.setTC(thread->getTC());
        //If more fetch data is needed, pass it in.
        const Addr PCMask = ~(sizeof(MachInst) - 1);
        if(predecoder.needMoreBytes())
            predecoder.moreBytes((thread->readPC() & PCMask) + fetchOffset,
                    0, inst);
        else
            predecoder.process();

        //If an instruction is ready, decode it. Otherwise, we'll have to
        //fetch beyond the MachInst at the current pc.
        if (predecoder.extMachInstReady()) {
#if THE_ISA == X86_ISA
            thread->setNextPC(thread->readPC() + predecoder.getInstSize());
#endif // X86_ISA
            stayAtPC = false;
            instPtr = StaticInst::decode(predecoder.getExtMachInst());
        } else {
            stayAtPC = true;
            fetchOffset += sizeof(MachInst);
        }

        //If we decoded an instruction and it's microcoded, start pulling
        //out micro ops
        if (instPtr && instPtr->isMacroOp()) {
            curMacroStaticInst = instPtr;
            curStaticInst = curMacroStaticInst->
                fetchMicroOp(thread->readMicroPC());
        } else {
            curStaticInst = instPtr;
        }
    } else {
        //Read the next micro op from the macro op
        curStaticInst = curMacroStaticInst->
            fetchMicroOp(thread->readMicroPC());
    }

#if TRACING_ON
    //If we decoded an instruction this "tick", record information about it.
    if(curStaticInst)
    {
        traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
                                         thread->readPC());

        DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
                curStaticInst->getName(), curStaticInst->machInst);

#if FULL_SYSTEM
        thread->setInst(inst);
#endif // FULL_SYSTEM
    }
#endif // TRACING_ON
}

void
BaseSimpleCPU::postExecute()
{
#if FULL_SYSTEM
    if (thread->profile) {
        bool usermode = TheISA::inUserMode(tc);
        thread->profilePC = usermode ? 1 : thread->readPC();
        StaticInstPtr si(inst);
        ProfileNode *node = thread->profile->consume(tc, si);
        if (node)
            thread->profileNode = node;
    }
#endif

    if (curStaticInst->isMemRef()) {
        numMemRefs++;
    }

    if (curStaticInst->isLoad()) {
        ++numLoad;
        comLoadEventQueue[0]->serviceEvents(numLoad);
    }

    traceFunctions(thread->readPC());

    if (traceData) {
        traceData->dump();
        delete traceData;
        traceData = NULL;
    }
}

void
BaseSimpleCPU::advancePC(Fault fault)
{
    //Since we're moving to a new pc, zero out the offset
    fetchOffset = 0;
    if (fault != NoFault) {
        curMacroStaticInst = StaticInst::nullStaticInstPtr;
        fault->invoke(tc);
        thread->setMicroPC(0);
        thread->setNextMicroPC(1);
    } else {
        //If we're at the last micro op for this instruction
        if (curStaticInst && curStaticInst->isLastMicroOp()) {
            //We should be working with a macro op
            assert(curMacroStaticInst);
            //Close out this macro op, and clean up the
            //microcode state
            curMacroStaticInst = StaticInst::nullStaticInstPtr;
            thread->setMicroPC(0);
            thread->setNextMicroPC(1);
        }
        //If we're still in a macro op
        if (curMacroStaticInst) {
            //Advance the micro pc
            thread->setMicroPC(thread->readNextMicroPC());
            //Advance the "next" micro pc. Note that there are no delay
            //slots, and micro ops are "word" addressed.
            thread->setNextMicroPC(thread->readNextMicroPC() + 1);
        } else {
            // go to the next instruction
            thread->setPC(thread->readNextPC());
            thread->setNextPC(thread->readNextNPC());
            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
            assert(thread->readNextPC() != thread->readNextNPC());
        }
    }

#if FULL_SYSTEM
    Addr oldpc;
    do {
        oldpc = thread->readPC();
        system->pcEventQueue.service(tc);
    } while (oldpc != thread->readPC());
#endif
}

<commit_msg>Minor error. Forgotten to remove brackets for threadPC.<commit_after>/*
 * Copyright (c) 2002-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.
 *
 * Authors: Steve Reinhardt
 */

#include "arch/utility.hh"
#include "arch/faults.hh"
#include "base/cprintf.hh"
#include "base/inifile.hh"
#include "base/loader/symtab.hh"
#include "base/misc.hh"
#include "base/pollevent.hh"
#include "base/range.hh"
#include "base/stats/events.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "cpu/profile.hh"
#include "cpu/simple/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/smt.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/debug.hh"
#include "sim/host.hh"
#include "sim/sim_events.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
#include "sim/system.hh"

#if FULL_SYSTEM
#include "arch/kernel_stats.hh"
#include "arch/stacktrace.hh"
#include "arch/tlb.hh"
#include "arch/vtophys.hh"
#include "base/remote_gdb.hh"
#else // !FULL_SYSTEM
#include "mem/mem_object.hh"
#endif // FULL_SYSTEM

using namespace std;
using namespace TheISA;

BaseSimpleCPU::BaseSimpleCPU(Params *p)
    : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
{
#if FULL_SYSTEM
    thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
#else
    thread = new SimpleThread(this, /* thread_num */ 0, p->process,
            /* asid */ 0);
#endif // !FULL_SYSTEM

    thread->setStatus(ThreadContext::Unallocated);

    tc = thread->getTC();

    numInst = 0;
    startNumInst = 0;
    numLoad = 0;
    startNumLoad = 0;
    lastIcacheStall = 0;
    lastDcacheStall = 0;

    threadContexts.push_back(tc);

    fetchOffset = 0;
    stayAtPC = false;
}

BaseSimpleCPU::~BaseSimpleCPU()
{
}

void
BaseSimpleCPU::deallocateContext(int thread_num)
{
    // for now, these are equivalent
    suspendContext(thread_num);
}

void
BaseSimpleCPU::haltContext(int thread_num)
{
    // for now, these are equivalent
    suspendContext(thread_num);
}

void
BaseSimpleCPU::regStats()
{
    using namespace Stats;

    BaseCPU::regStats();

    numInsts
        .name(name() + ".num_insts")
        .desc("Number of instructions executed")
        ;

    numMemRefs
        .name(name() + ".num_refs")
        .desc("Number of memory references")
        ;

    notIdleFraction
        .name(name() + ".not_idle_fraction")
        .desc("Percentage of non-idle cycles")
        ;

    idleFraction
        .name(name() + ".idle_fraction")
        .desc("Percentage of idle cycles")
        ;

    icacheStallCycles
        .name(name() + ".icache_stall_cycles")
        .desc("ICache total stall cycles")
        .prereq(icacheStallCycles)
        ;

    dcacheStallCycles
        .name(name() + ".dcache_stall_cycles")
        .desc("DCache total stall cycles")
        .prereq(dcacheStallCycles)
        ;

    icacheRetryCycles
        .name(name() + ".icache_retry_cycles")
        .desc("ICache total retry cycles")
        .prereq(icacheRetryCycles)
        ;

    dcacheRetryCycles
        .name(name() + ".dcache_retry_cycles")
        .desc("DCache total retry cycles")
        .prereq(dcacheRetryCycles)
        ;

    idleFraction = constant(1.0) - notIdleFraction;
}

void
BaseSimpleCPU::resetStats()
{
//    startNumInst = numInst;
    // notIdleFraction = (_status != Idle);
}

void
BaseSimpleCPU::serialize(ostream &os)
{
    BaseCPU::serialize(os);
//    SERIALIZE_SCALAR(inst);
    nameOut(os, csprintf("%s.xc.0", name()));
    thread->serialize(os);
}

void
BaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
    BaseCPU::unserialize(cp, section);
//    UNSERIALIZE_SCALAR(inst);
    thread->unserialize(cp, csprintf("%s.xc.0", section));
}

void
change_thread_state(int thread_number, int activate, int priority)
{
}

Fault
BaseSimpleCPU::copySrcTranslate(Addr src)
{
#if 0
    static bool no_warn = true;
    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
    // Only support block sizes of 64 atm.
    assert(blk_size == 64);
    int offset = src & (blk_size - 1);

    // Make sure block doesn't span page
    if (no_warn &&
        (src & PageMask) != ((src + blk_size) & PageMask) &&
        (src >> 40) != 0xfffffc) {
        warn("Copied block source spans pages %x.", src);
        no_warn = false;
    }

    memReq->reset(src & ~(blk_size - 1), blk_size);

    // translate to physical address
    Fault fault = thread->translateDataReadReq(req);

    if (fault == NoFault) {
        thread->copySrcAddr = src;
        thread->copySrcPhysAddr = memReq->paddr + offset;
    } else {
        assert(!fault->isAlignmentFault());

        thread->copySrcAddr = 0;
        thread->copySrcPhysAddr = 0;
    }
    return fault;
#else
    return NoFault;
#endif
}

Fault
BaseSimpleCPU::copy(Addr dest)
{
#if 0
    static bool no_warn = true;
    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
    // Only support block sizes of 64 atm.
    assert(blk_size == 64);
    uint8_t data[blk_size];
    //assert(thread->copySrcAddr);
    int offset = dest & (blk_size - 1);

    // Make sure block doesn't span page
    if (no_warn &&
        (dest & PageMask) != ((dest + blk_size) & PageMask) &&
        (dest >> 40) != 0xfffffc) {
        no_warn = false;
        warn("Copied block destination spans pages %x. ", dest);
    }

    memReq->reset(dest & ~(blk_size -1), blk_size);
    // translate to physical address
    Fault fault = thread->translateDataWriteReq(req);

    if (fault == NoFault) {
        Addr dest_addr = memReq->paddr + offset;
        // Need to read straight from memory since we have more than 8 bytes.
        memReq->paddr = thread->copySrcPhysAddr;
        thread->mem->read(memReq, data);
        memReq->paddr = dest_addr;
        thread->mem->write(memReq, data);
        if (dcacheInterface) {
            memReq->cmd = Copy;
            memReq->completionEvent = NULL;
            memReq->paddr = thread->copySrcPhysAddr;
            memReq->dest = dest_addr;
            memReq->size = 64;
            memReq->time = curTick;
            memReq->flags &= ~INST_READ;
            dcacheInterface->access(memReq);
        }
    }
    else
        assert(!fault->isAlignmentFault());

    return fault;
#else
    panic("copy not implemented");
    return NoFault;
#endif
}

#if FULL_SYSTEM
Addr
BaseSimpleCPU::dbg_vtophys(Addr addr)
{
    return vtophys(tc, addr);
}
#endif // FULL_SYSTEM

#if FULL_SYSTEM
void
BaseSimpleCPU::post_interrupt(int int_num, int index)
{
    BaseCPU::post_interrupt(int_num, index);

    if (thread->status() == ThreadContext::Suspended) {
                DPRINTF(Quiesce,"Suspended Processor awoke\n");
        thread->activate();
    }
}
#endif // FULL_SYSTEM

void
BaseSimpleCPU::checkForInterrupts()
{
#if FULL_SYSTEM
    if (check_interrupts(tc)) {
        Fault interrupt = interrupts.getInterrupt(tc);

        if (interrupt != NoFault) {
            interrupts.updateIntrInfo(tc);
            interrupt->invoke(tc);
        }
    }
#endif
}

Fault
BaseSimpleCPU::setupFetchRequest(Request *req)
{
    uint64_t threadPC = thread->readPC();

    // set up memory request for instruction fetch
#if ISA_HAS_DELAY_SLOT
    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC,
            thread->readNextPC(),thread->readNextNPC());
#else
    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",threadPC,
            thread->readNextPC());
#endif

    const Addr PCMask = ~(sizeof(MachInst) - 1);
    Addr fetchPC = thread->readPC() + fetchOffset;
    req->setVirt(0, fetchPC & PCMask, sizeof(MachInst), 0, threadPC);

    Fault fault = thread->translateInstReq(req);

    return fault;
}

void
BaseSimpleCPU::preExecute()
{
    // maintain $r0 semantics
    thread->setIntReg(ZeroReg, 0);
#if THE_ISA == ALPHA_ISA
    thread->setFloatReg(ZeroReg, 0.0);
#endif // ALPHA_ISA

    // keep an instruction count
    numInst++;
    numInsts++;

    thread->funcExeInst++;

    // check for instruction-count-based events
    comInstEventQueue[0]->serviceEvents(numInst);

    // decode the instruction
    inst = gtoh(inst);

    //If we're not in the middle of a macro instruction
    if (!curMacroStaticInst) {

        StaticInstPtr instPtr = NULL;

        //Predecode, ie bundle up an ExtMachInst
        //This should go away once the constructor can be set up properly
        predecoder.setTC(thread->getTC());
        //If more fetch data is needed, pass it in.
        const Addr PCMask = ~(sizeof(MachInst) - 1);
        if(predecoder.needMoreBytes())
            predecoder.moreBytes((thread->readPC() & PCMask) + fetchOffset,
                    0, inst);
        else
            predecoder.process();

        //If an instruction is ready, decode it. Otherwise, we'll have to
        //fetch beyond the MachInst at the current pc.
        if (predecoder.extMachInstReady()) {
#if THE_ISA == X86_ISA
            thread->setNextPC(thread->readPC() + predecoder.getInstSize());
#endif // X86_ISA
            stayAtPC = false;
            instPtr = StaticInst::decode(predecoder.getExtMachInst());
        } else {
            stayAtPC = true;
            fetchOffset += sizeof(MachInst);
        }

        //If we decoded an instruction and it's microcoded, start pulling
        //out micro ops
        if (instPtr && instPtr->isMacroOp()) {
            curMacroStaticInst = instPtr;
            curStaticInst = curMacroStaticInst->
                fetchMicroOp(thread->readMicroPC());
        } else {
            curStaticInst = instPtr;
        }
    } else {
        //Read the next micro op from the macro op
        curStaticInst = curMacroStaticInst->
            fetchMicroOp(thread->readMicroPC());
    }

#if TRACING_ON
    //If we decoded an instruction this "tick", record information about it.
    if(curStaticInst)
    {
        traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
                                         thread->readPC());

        DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
                curStaticInst->getName(), curStaticInst->machInst);

#if FULL_SYSTEM
        thread->setInst(inst);
#endif // FULL_SYSTEM
    }
#endif // TRACING_ON
}

void
BaseSimpleCPU::postExecute()
{
#if FULL_SYSTEM
    if (thread->profile) {
        bool usermode = TheISA::inUserMode(tc);
        thread->profilePC = usermode ? 1 : thread->readPC();
        StaticInstPtr si(inst);
        ProfileNode *node = thread->profile->consume(tc, si);
        if (node)
            thread->profileNode = node;
    }
#endif

    if (curStaticInst->isMemRef()) {
        numMemRefs++;
    }

    if (curStaticInst->isLoad()) {
        ++numLoad;
        comLoadEventQueue[0]->serviceEvents(numLoad);
    }

    traceFunctions(thread->readPC());

    if (traceData) {
        traceData->dump();
        delete traceData;
        traceData = NULL;
    }
}

void
BaseSimpleCPU::advancePC(Fault fault)
{
    //Since we're moving to a new pc, zero out the offset
    fetchOffset = 0;
    if (fault != NoFault) {
        curMacroStaticInst = StaticInst::nullStaticInstPtr;
        fault->invoke(tc);
        thread->setMicroPC(0);
        thread->setNextMicroPC(1);
    } else {
        //If we're at the last micro op for this instruction
        if (curStaticInst && curStaticInst->isLastMicroOp()) {
            //We should be working with a macro op
            assert(curMacroStaticInst);
            //Close out this macro op, and clean up the
            //microcode state
            curMacroStaticInst = StaticInst::nullStaticInstPtr;
            thread->setMicroPC(0);
            thread->setNextMicroPC(1);
        }
        //If we're still in a macro op
        if (curMacroStaticInst) {
            //Advance the micro pc
            thread->setMicroPC(thread->readNextMicroPC());
            //Advance the "next" micro pc. Note that there are no delay
            //slots, and micro ops are "word" addressed.
            thread->setNextMicroPC(thread->readNextMicroPC() + 1);
        } else {
            // go to the next instruction
            thread->setPC(thread->readNextPC());
            thread->setNextPC(thread->readNextNPC());
            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
            assert(thread->readNextPC() != thread->readNextNPC());
        }
    }

#if FULL_SYSTEM
    Addr oldpc;
    do {
        oldpc = thread->readPC();
        system->pcEventQueue.service(tc);
    } while (oldpc != thread->readPC());
#endif
}

<|endoftext|>


<commit_before>/* Siconos-Kernel version 3.0.0, Copyright INRIA 2005-2008.
 * Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 * Siconos is a free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * Siconos is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Siconos; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Contact: Vincent ACARY vincent.acary@inrialpes.fr
 */
#include "Relay.h"
#include <iostream>
#include <assert.h>
#include "Tools.hpp"

#include "Simulation.h"
#include "RelayNSL.h"

using namespace std;
using namespace RELATION;

/* nslaw dispatch on bounds */

struct Relay::_BoundsNSLEffect : public SiconosVisitor
{
  Relay *parent;
  unsigned int pos;
  SP::UnitaryRelation UR;

  _BoundsNSLEffect(Relay *p, SP::UnitaryRelation UR, unsigned int pos) :
    parent(p), UR(UR), pos(pos) {};

  void visit(RelayNSL& nslaw)
  {

    // cout << "Relay::_BoundsNSLEffect visit"  << endl;
    for (int i = 0; i <  UR->getNonSmoothLawSize(); i++)
    {
      (*(parent->lb()))(pos + i) =
        nslaw.lb();
      (*(parent->ub()))(pos + i) =
        nslaw.ub();
    }
  }

  void visit(ComplementarityConditionNSL& nslaw)
  {
    for (int i = 0; i <  UR->getNonSmoothLawSize(); i++)
    {
      (*(parent->lb()))(pos + i) = 0.0;
      (*(parent->ub()))(pos + i) = 1e+24;
    }

    // \warning Introduce the infinte double symbol rather 1e+24

  }

};

void Relay::initialize(SP::Simulation sim)
{
  LinearOSNS::initialize(sim);
  //cout << "Relay::initialize" << endl;

  // initialize memory for _lb and _ub
  if (! _lb)
    _lb.reset(new SimpleVector(maxSize()));
  else
  {
    if (_lb->size() != maxSize())
      _lb->resize(maxSize());
  }
  if (! _ub)
    _ub.reset(new SimpleVector(maxSize()));
  else
  {
    if (_ub->size() != maxSize())
      _ub->resize(maxSize());
  }

  // fill _lb and _ub wiht the value of the NonSmooth Law

  SP::UnitaryRelationsGraph indexSet = simulation()->indexSet(levelMin());

  //cout << " _sizeOutput =" <<_sizeOutput << endl;
  if (_lb->size() != _sizeOutput)
  {
    _lb->resize(_sizeOutput, false);
    _lb->zero();
  }
  if (_ub->size() != _sizeOutput)
  {
    _ub->resize(_sizeOutput, false);
    _ub->zero();
  }

  unsigned int pos = 0;
  UnitaryRelationsGraph::VIterator ui, uiend;
  for (boost::tie(ui, uiend) = indexSet->vertices(); ui != uiend; ++ui)
  {
    SP::UnitaryRelation ur = indexSet->bundle(*ui);

    // Compute q, this depends on the type of non smooth problem, on
    // the relation type and on the non smooth law
    pos = _M->getPositionOfUnitaryBlock(ur);
    SP::SiconosVisitor NSLEffect(new _BoundsNSLEffect(this, ur, pos));
    ur->interaction()->nonSmoothLaw()->accept(*NSLEffect);
  }

}

int Relay::compute(double time)
{
  // --- Prepare data for Relay computing ---
  preCompute(time);

  int info = 0;
  // --- Call Numerics driver ---
  // Inputs:
  // - the problem (M,q ...)
  // - the unknowns (z,w)
  // - the options for the solver (name, max iteration number ...)
  // - the global options for Numerics (verbose mode ...)

  if (_sizeOutput != 0)
  {
    // The Relay in Numerics format
    Relay_Problem numerics_problem;
    numerics_problem.M = &*_M->getNumericsMatrix();
    numerics_problem.q = _q->getArray();
    numerics_problem.lb = _lb->getArray();
    numerics_problem.ub = _ub->getArray();
    numerics_problem.size = _sizeOutput;

    int nbSolvers = 1;
    // Call Relay Driver
    info = relay_driver(&numerics_problem, _z->getArray() , _w->getArray() ,
                        &*_solver->numericsSolverOptions(), &*_numerics_options);

    // --- Recovering of the desired variables from Relay output ---
    postCompute();

  }

  return info;
}

void Relay::display() const
{
  cout << "======= Relay of size " << _sizeOutput << " with: " << endl;
  LinearOSNS::display();
}

Relay* Relay::convert(OneStepNSProblem* osnsp)
{
  Relay* lcp = dynamic_cast<Relay*>(osnsp);
  return lcp;
}

<commit_msg>new Relay.cpp<commit_after>/* Siconos-Kernel version 3.0.0, Copyright INRIA 2005-2008.
 * Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 * Siconos is a free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * Siconos is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Siconos; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Contact: Vincent ACARY vincent.acary@inrialpes.fr
 */
#include "Relay.h"
#include <iostream>
#include <assert.h>
#include "Tools.hpp"

#include "Simulation.h"
#include "RelayNSL.h"

using namespace std;
using namespace RELATION;

/* nslaw dispatch on bounds */

struct Relay::_BoundsNSLEffect : public SiconosVisitor
{
  Relay *parent;
  unsigned int pos;
  SP::UnitaryRelation UR;

  _BoundsNSLEffect(Relay *p, SP::UnitaryRelation UR, unsigned int pos) :
    parent(p), UR(UR), pos(pos) {};

  void visit(RelayNSL& nslaw)
  {

    // cout << "Relay::_BoundsNSLEffect visit"  << endl;
    for (int i = 0; i <  UR->getNonSmoothLawSize(); i++)
    {
      (*(parent->lb()))(pos + i) =
        nslaw.lb();
      (*(parent->ub()))(pos + i) =
        nslaw.ub();
    }
  }

  void visit(ComplementarityConditionNSL& nslaw)
  {
    for (int i = 0; i <  UR->getNonSmoothLawSize(); i++)
    {
      (*(parent->lb()))(pos + i) = 0.0;
      (*(parent->ub()))(pos + i) = 1e+24;
    }

    // \warning Introduce the infinte double symbol rather 1e+24

  }

};

void Relay::initialize(SP::Simulation sim)
{
  LinearOSNS::initialize(sim);
  //cout << "Relay::initialize" << endl;

  // initialize memory for _lb and _ub
  if (! _lb)
    _lb.reset(new SimpleVector(maxSize()));
  else
  {
    if (_lb->size() != maxSize())
      _lb->resize(maxSize());
  }
  if (! _ub)
    _ub.reset(new SimpleVector(maxSize()));
  else
  {
    if (_ub->size() != maxSize())
      _ub->resize(maxSize());
  }

  // fill _lb and _ub wiht the value of the NonSmooth Law

  SP::UnitaryRelationsGraph indexSet = simulation()->indexSet(levelMin());

  //cout << " _sizeOutput =" <<_sizeOutput << endl;
  if (_lb->size() != _sizeOutput)
  {
    _lb->resize(_sizeOutput, false);
    _lb->zero();
  }
  if (_ub->size() != _sizeOutput)
  {
    _ub->resize(_sizeOutput, false);
    _ub->zero();
  }

  unsigned int pos = 0;
  UnitaryRelationsGraph::VIterator ui, uiend;
  for (boost::tie(ui, uiend) = indexSet->vertices(); ui != uiend; ++ui)
  {
    SP::UnitaryRelation ur = indexSet->bundle(*ui);

    // Compute q, this depends on the type of non smooth problem, on
    // the relation type and on the non smooth law
    pos = _M->getPositionOfUnitaryBlock(ur);
    SP::SiconosVisitor NSLEffect(new _BoundsNSLEffect(this, ur, pos));
    ur->interaction()->nonSmoothLaw()->accept(*NSLEffect);
  }

}

int Relay::compute(double time)
{
  // --- Prepare data for Relay computing ---
  preCompute(time);

  int info = 0;
  // --- Call Numerics driver ---
  // Inputs:
  // - the problem (M,q ...)
  // - the unknowns (z,w)
  // - the options for the solver (name, max iteration number ...)
  // - the global options for Numerics (verbose mode ...)

  if (_sizeOutput != 0)
  {
    // The Relay in Numerics format
    Relay_Problem numerics_problem;
    numerics_problem.M = &*_M->getNumericsMatrix();
    numerics_problem.q = _q->getArray();
    numerics_problem.lb = _lb->getArray();
    numerics_problem.ub = _ub->getArray();
    numerics_problem.size = _sizeOutput;

    int nbSolvers = 1;
    // Call Relay Driver

    Relay_display(&numerics_problem);

    info = relay_driver(&numerics_problem, _z->getArray() , _w->getArray() ,
                        &*_solver->numericsSolverOptions(), nbSolvers, &*_numerics_options);

    if (info != 0)
    {
      cout << "Warning : Problem in Relay resolution" << endl;
    }

    // --- Recovering of the desired variables from Relay output ---
    postCompute();

  }

  return info;
}

void Relay::display() const
{
  cout << "======= Relay of size " << _sizeOutput << " with: " << endl;
  LinearOSNS::display();
}

Relay* Relay::convert(OneStepNSProblem* osnsp)
{
  Relay* lcp = dynamic_cast<Relay*>(osnsp);
  return lcp;
}

<|endoftext|>


<commit_before>/*
 * Licensed under Apache License v2. See LICENSE for more information.
 */
#include <CppUTest/TestHarness.h>
#include "CppUTest/CommandLineTestRunner.h"

extern "C" {

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "dyn_function.h"

static int g_count;

static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
    va_list ap;
    const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
    fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
    va_start(ap, msg);
    vfprintf(stderr, msg, ap);
    fprintf(stderr, "\n");
}

#define EXAMPLE1_SCHEMA "example(III)I"
static void example1_binding(void *userData, void* args[], void *out) {
    printf("example1 closure called\n");
    int32_t a = *((int32_t *)args[0]);
    int32_t b = *((int32_t *)args[1]);
    int32_t c = *((int32_t *)args[2]);
    int32_t *ret = (int32_t *)out;
    *ret = a + b + c;
    g_count += 1;
}

#define EXAMPLE2_SCHEMA "example(I{DDD val1 val2 val3}I)D"
struct example2_arg2 {
    double val1;
    double val2;
    double val3;
};
void example2_binding(void *userData, void* args[], void *out) {
    printf("example2 closure called\n");
    int32_t a = *((int32_t *)args[0]);
    struct example2_arg2 b =  *((struct example2_arg2 *)args[1]);
    int32_t c = *((int32_t *)args[2]);
    int32_t *ret = (int32_t *)out;
    *ret = a + b.val1 + b.val2 + b.val3 + c;
    g_count += 1;
}

#define EXAMPLE3_SCHEMA "example(III){III sum max min}"
struct example3_ret {
    int32_t sum;
    int32_t max;
    int32_t min;
};

static void example3_binding(void *userData, void* args[], void *out) {
    printf("example closure called\n");
    int32_t a = *((int32_t *)args[0]);
    int32_t b = *((int32_t *)args[1]);
    int32_t c = *((int32_t *)args[2]);
    struct example3_ret *result = (struct example3_ret *)calloc(1,sizeof(struct example3_ret));
    result->sum = a + b + c;
    result->min = a <= b ? a : b;
    result->max = a >= b ? a : b;
    result->min = result->min <= c ? result->min : c;
    result->max = result->max >= c ? result->max : c;

    struct example3_ret **ret = (struct example3_ret **)out;
    (*ret) = result;
    g_count += 1;
}

static void tests() {
    dyn_closure_type *dynClosure = NULL;
    int rc;

    {
        rc = dynClosure_create(EXAMPLE1_SCHEMA, example1_binding, NULL, &dynClosure);
        CHECK_EQUAL(0, rc);
        int32_t (*func)(int32_t a, int32_t b, int32_t c) = NULL;
        int rc = dynClosure_getFnPointer(dynClosure, (void(**)(void))&func);
        CHECK_EQUAL(0, rc);
        int32_t ret = func(2,3,4);
        printf("Return value for example1 is %i\n", ret);
        CHECK_EQUAL(1, g_count);
        dynClosure_destroy(dynClosure);
    }

    {
        dynClosure = NULL;
        rc = dynClosure_create(EXAMPLE2_SCHEMA, example2_binding, NULL, &dynClosure);
        CHECK_EQUAL(0, rc);
        double (*func)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
        rc = dynClosure_getFnPointer(dynClosure, (void(**)(void))&func);
        CHECK_EQUAL(0, rc);
        struct example2_arg2 b = { .val1 = 1.0, .val2 = 1.5, .val3 = 2.0 };
        double ret = func(2,b,4);
        printf("Return value for example2 is %f\n", ret);
        CHECK_EQUAL(2, g_count);
        dynClosure_destroy(dynClosure);
    }

    {
        dynClosure = NULL;
        rc = dynClosure_create(EXAMPLE3_SCHEMA, example3_binding, NULL, &dynClosure);
        CHECK_EQUAL(0, rc);
        struct example3_ret * (*func)(int32_t a, int32_t b, int32_t c) = NULL;
        rc = dynClosure_getFnPointer(dynClosure, (void(**)(void))&func);
        CHECK_EQUAL(0, rc);
        struct example3_ret *ret = func(2,8,4);
        printf("Return value for example3 is {sum:%i, max:%i, min:%i}\n", ret->sum, ret->max, ret->min);
        CHECK_EQUAL(3, g_count);
        dynClosure_destroy(dynClosure);
        free(ret);
    }
}

}

TEST_GROUP(DynClosureTests) {
    void setup() {
        dynFunction_logSetup(stdLog, NULL, 4);
        //TODO dynType_logSetup(stdLog, NULL, 4);
        g_count = 0;
    }
};

TEST(DynClosureTests, DynCLosureTest1) {
    //TODO split up
    tests();
}
<commit_msg>CELIX-237: change struct assigment in ccputest.<commit_after>/*
 * Licensed under Apache License v2. See LICENSE for more information.
 */
#include <CppUTest/TestHarness.h>
#include "CppUTest/CommandLineTestRunner.h"

extern "C" {

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "dyn_function.h"

static int g_count;

static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
    va_list ap;
    const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
    fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
    va_start(ap, msg);
    vfprintf(stderr, msg, ap);
    fprintf(stderr, "\n");
}

#define EXAMPLE1_SCHEMA "example(III)I"
static void example1_binding(void *userData, void* args[], void *out) {
    printf("example1 closure called\n");
    int32_t a = *((int32_t *)args[0]);
    int32_t b = *((int32_t *)args[1]);
    int32_t c = *((int32_t *)args[2]);
    int32_t *ret = (int32_t *)out;
    *ret = a + b + c;
    g_count += 1;
}

#define EXAMPLE2_SCHEMA "example(I{DDD val1 val2 val3}I)D"
struct example2_arg2 {
    double val1;
    double val2;
    double val3;
};
void example2_binding(void *userData, void* args[], void *out) {
    printf("example2 closure called\n");
    int32_t a = *((int32_t *)args[0]);
    struct example2_arg2 b =  *((struct example2_arg2 *)args[1]);
    int32_t c = *((int32_t *)args[2]);
    int32_t *ret = (int32_t *)out;
    *ret = a + b.val1 + b.val2 + b.val3 + c;
    g_count += 1;
}

#define EXAMPLE3_SCHEMA "example(III){III sum max min}"
struct example3_ret {
    int32_t sum;
    int32_t max;
    int32_t min;
};

static void example3_binding(void *userData, void* args[], void *out) {
    printf("example closure called\n");
    int32_t a = *((int32_t *)args[0]);
    int32_t b = *((int32_t *)args[1]);
    int32_t c = *((int32_t *)args[2]);
    struct example3_ret *result = (struct example3_ret *)calloc(1,sizeof(struct example3_ret));
    result->sum = a + b + c;
    result->min = a <= b ? a : b;
    result->max = a >= b ? a : b;
    result->min = result->min <= c ? result->min : c;
    result->max = result->max >= c ? result->max : c;

    struct example3_ret **ret = (struct example3_ret **)out;
    (*ret) = result;
    g_count += 1;
}

static void tests() {
    dyn_closure_type *dynClosure = NULL;
    int rc;

    {
        rc = dynClosure_create(EXAMPLE1_SCHEMA, example1_binding, NULL, &dynClosure);
        CHECK_EQUAL(0, rc);
        int32_t (*func)(int32_t a, int32_t b, int32_t c) = NULL;
        int rc = dynClosure_getFnPointer(dynClosure, (void(**)(void))&func);
        CHECK_EQUAL(0, rc);
        int32_t ret = func(2,3,4);
        printf("Return value for example1 is %i\n", ret);
        CHECK_EQUAL(1, g_count);
        dynClosure_destroy(dynClosure);
    }

    {
        dynClosure = NULL;
        rc = dynClosure_create(EXAMPLE2_SCHEMA, example2_binding, NULL, &dynClosure);
        CHECK_EQUAL(0, rc);
        double (*func)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
        rc = dynClosure_getFnPointer(dynClosure, (void(**)(void))&func);
        CHECK_EQUAL(0, rc);
        struct example2_arg2 b;
        b.val1 = 1.0;
        b.val2 = 1.5;
        b.val3 = 2.0;
        double ret = func(2,b,4);
        printf("Return value for example2 is %f\n", ret);
        CHECK_EQUAL(2, g_count);
        dynClosure_destroy(dynClosure);
    }

    {
        dynClosure = NULL;
        rc = dynClosure_create(EXAMPLE3_SCHEMA, example3_binding, NULL, &dynClosure);
        CHECK_EQUAL(0, rc);
        struct example3_ret * (*func)(int32_t a, int32_t b, int32_t c) = NULL;
        rc = dynClosure_getFnPointer(dynClosure, (void(**)(void))&func);
        CHECK_EQUAL(0, rc);
        struct example3_ret *ret = func(2,8,4);
        printf("Return value for example3 is {sum:%i, max:%i, min:%i}\n", ret->sum, ret->max, ret->min);
        CHECK_EQUAL(3, g_count);
        dynClosure_destroy(dynClosure);
        free(ret);
    }
}

}

TEST_GROUP(DynClosureTests) {
    void setup() {
        dynFunction_logSetup(stdLog, NULL, 4);
        //TODO dynType_logSetup(stdLog, NULL, 4);
        g_count = 0;
    }
};

TEST(DynClosureTests, DynCLosureTest1) {
    //TODO split up
    tests();
}
<|endoftext|>


<commit_before>/*
 *  Copyright 2008-2011 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <thrust/detail/config.h>
#include <thrust/detail/tagged_allocator.h>
#include <thrust/detail/backend/generic/select_system.h>
#include <thrust/system/detail/bad_alloc.h>
#include <limits>

namespace thrust
{
namespace detail
{

template<typename T, typename Tag, typename Pointer>
  tagged_allocator<T,Tag,Pointer>
    ::tagged_allocator()
{}

template<typename T, typename Tag, typename Pointer>
  tagged_allocator<T,Tag,Pointer>
    ::tagged_allocator(const tagged_allocator<T,Tag,Pointer> &)
{}

template<typename T, typename Tag, typename Pointer>
  template<typename U, typename OtherPointer>
    tagged_allocator<T,Tag,Pointer>
      ::tagged_allocator(const tagged_allocator<U,Tag,OtherPointer> &)
{}

template<typename T, typename Tag, typename Pointer>
  tagged_allocator<T,Tag,Pointer>
    ::~tagged_allocator()
{}

template<typename T, typename Tag, typename Pointer>
  typename tagged_allocator<T,Tag,Pointer>::pointer
    tagged_allocator<T,Tag,Pointer>
      ::address(reference x) const
{
  return &x;
}

template<typename T, typename Tag, typename Pointer>
  typename tagged_allocator<T,Tag,Pointer>::const_pointer
    tagged_allocator<T,Tag,Pointer>
      ::address(const_reference x) const
{
  return &x;
}

template<typename T, typename Tag, typename Pointer>
  template<typename OtherPointer>
    typename thrust::detail::pointer_traits<OtherPointer>::raw_pointer
      tagged_allocator<T,Tag,Pointer>
        ::get(OtherPointer ptr)
{
  return thrust::detail::pointer_traits<OtherPointer>::get(ptr);
}

template<typename T, typename Tag, typename Pointer>
  typename tagged_allocator<T,Tag,Pointer>::pointer
    tagged_allocator<T,Tag,Pointer>
      ::allocate(size_type cnt)
{
  using thrust::detail::backend::generic::select_system;
  using thrust::detail::backend::generic::malloc;

  // XXX should use a hypothetical thrust::static_pointer_cast here
  T* result = static_cast<T*>(get(malloc(select_system(Tag()), sizeof(value_type) * cnt)));

  if(result == 0)
  {
    throw thrust::system::detail::bad_alloc("tagged_allocator::allocate: malloc failed");
  } // end if

  return pointer(result);
}

template<typename T, typename Tag, typename Pointer>
  void tagged_allocator<T,Tag,Pointer>
    ::deallocate(pointer p, size_type n)
{
  using thrust::detail::backend::generic::select_system;

  // XXX should probably have a using generic::free here
  //     which would be an automatic failure if selected
  free(select_system(Tag()), p);
}

template<typename T, typename Tag, typename Pointer>
  typename tagged_allocator<T,Tag,Pointer>::size_type
    tagged_allocator<T,Tag,Pointer>
      ::max_size() const
{
  return (std::numeric_limits<size_type>::max)() / sizeof(T);
}

template<typename T1, typename Pointer1, typename T2, typename Pointer2, typename Tag>
__host__ __device__
bool operator==(const tagged_allocator<T1,Pointer1,Tag> &, const tagged_allocator<T2,Pointer2,Tag> &)
{
  return true;
}

template<typename T1, typename Pointer1, typename T2, typename Pointer2, typename Tag>
__host__ __device__
bool operator!=(const tagged_allocator<T1,Pointer1,Tag> &, const tagged_allocator<T2,Pointer2,Tag> &)
{
  return false;
}

} // end detail
} // end thrust

<commit_msg>Add a using thrust::detail::backend::generic::free to tagged_allocator::deallocate<commit_after>/*
 *  Copyright 2008-2011 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <thrust/detail/config.h>
#include <thrust/detail/tagged_allocator.h>
#include <thrust/detail/backend/generic/select_system.h>
#include <thrust/detail/backend/generic/memory.h>
#include <thrust/system/detail/bad_alloc.h>
#include <limits>

namespace thrust
{
namespace detail
{

template<typename T, typename Tag, typename Pointer>
  tagged_allocator<T,Tag,Pointer>
    ::tagged_allocator()
{}

template<typename T, typename Tag, typename Pointer>
  tagged_allocator<T,Tag,Pointer>
    ::tagged_allocator(const tagged_allocator<T,Tag,Pointer> &)
{}

template<typename T, typename Tag, typename Pointer>
  template<typename U, typename OtherPointer>
    tagged_allocator<T,Tag,Pointer>
      ::tagged_allocator(const tagged_allocator<U,Tag,OtherPointer> &)
{}

template<typename T, typename Tag, typename Pointer>
  tagged_allocator<T,Tag,Pointer>
    ::~tagged_allocator()
{}

template<typename T, typename Tag, typename Pointer>
  typename tagged_allocator<T,Tag,Pointer>::pointer
    tagged_allocator<T,Tag,Pointer>
      ::address(reference x) const
{
  return &x;
}

template<typename T, typename Tag, typename Pointer>
  typename tagged_allocator<T,Tag,Pointer>::const_pointer
    tagged_allocator<T,Tag,Pointer>
      ::address(const_reference x) const
{
  return &x;
}

template<typename T, typename Tag, typename Pointer>
  template<typename OtherPointer>
    typename thrust::detail::pointer_traits<OtherPointer>::raw_pointer
      tagged_allocator<T,Tag,Pointer>
        ::get(OtherPointer ptr)
{
  return thrust::detail::pointer_traits<OtherPointer>::get(ptr);
}

template<typename T, typename Tag, typename Pointer>
  typename tagged_allocator<T,Tag,Pointer>::pointer
    tagged_allocator<T,Tag,Pointer>
      ::allocate(size_type cnt)
{
  using thrust::detail::backend::generic::select_system;
  using thrust::detail::backend::generic::malloc;

  // XXX should use a hypothetical thrust::static_pointer_cast here
  T* result = static_cast<T*>(get(malloc(select_system(Tag()), sizeof(value_type) * cnt)));

  if(result == 0)
  {
    throw thrust::system::detail::bad_alloc("tagged_allocator::allocate: malloc failed");
  } // end if

  return pointer(result);
}

template<typename T, typename Tag, typename Pointer>
  void tagged_allocator<T,Tag,Pointer>
    ::deallocate(pointer p, size_type n)
{
  using thrust::detail::backend::generic::select_system;
  using thrust::detail::backend::generic::free;

  free(select_system(Tag()), p);
}

template<typename T, typename Tag, typename Pointer>
  typename tagged_allocator<T,Tag,Pointer>::size_type
    tagged_allocator<T,Tag,Pointer>
      ::max_size() const
{
  return (std::numeric_limits<size_type>::max)() / sizeof(T);
}

template<typename T1, typename Pointer1, typename T2, typename Pointer2, typename Tag>
__host__ __device__
bool operator==(const tagged_allocator<T1,Pointer1,Tag> &, const tagged_allocator<T2,Pointer2,Tag> &)
{
  return true;
}

template<typename T1, typename Pointer1, typename T2, typename Pointer2, typename Tag>
__host__ __device__
bool operator!=(const tagged_allocator<T1,Pointer1,Tag> &, const tagged_allocator<T2,Pointer2,Tag> &)
{
  return false;
}

} // end detail
} // end thrust

<|endoftext|>