<commit_before>/*
 * Copyright 2014 Realm Inc.
 *
 * 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 <algorithm>
#include <stdexcept>

#include <tightdb/util/assert.hpp>
#include <tightdb/util/utf8.hpp>

#include "util.hpp"
#include "io_realm_internal_Util.h"

using namespace std;
using namespace tightdb;
using namespace tightdb::util;

void ThrowException(JNIEnv* env, ExceptionKind exception, std::string classStr, std::string itemStr)
{
    std::string message;
    jclass jExceptionClass = NULL;

    TR_ERR((env, "\njni: ThrowingException %d, %s, %s.\n", exception, classStr.c_str(), itemStr.c_str()));

    switch (exception) {
        case ClassNotFound:
            jExceptionClass = env->FindClass("java/lang/ClassNotFoundException");
            message = "Class '" + classStr + "' could not be located.";
            break;

        case NoSuchField:
            jExceptionClass = env->FindClass("java/lang/NoSuchFieldException");
            message = "Field '" + itemStr + "' could not be located in class io.realm." + classStr;
            break;

        case NoSuchMethod:
            jExceptionClass = env->FindClass("java/lang/NoSuchMethodException");
            message = "Method '" + itemStr + "' could not be located in class io.realm." + classStr;
            break;

        case IllegalArgument:
            jExceptionClass = env->FindClass("java/lang/IllegalArgumentException");
            message = "Illegal Argument: " + classStr;
            break;

        case TableInvalid:
            jExceptionClass = env->FindClass("java/lang/IllegalStateException");
            message = "Illegal State: " + classStr;
            break;

        case IOFailed:
            jExceptionClass = env->FindClass("io/realm/exceptions/RealmIOException");
            message = "Failed to open " + classStr + ". " + itemStr;
            break;

        case FileNotFound:
            jExceptionClass = env->FindClass("io/realm/exceptions/RealmIOException");
            message = "File not found: " + classStr + ".";
            break;

        case FileAccessError:
            jExceptionClass = env->FindClass("io/realm/exceptions/RealmIOException");
            message = "Failed to access: " + classStr + ". " + itemStr;
            break;

        case IndexOutOfBounds:
            jExceptionClass = env->FindClass("java/lang/ArrayIndexOutOfBoundsException");
            message = classStr;
            break;

        case UnsupportedOperation:
            jExceptionClass = env->FindClass("java/lang/UnsupportedOperationException");
            message = classStr;
            break;

        case OutOfMemory:
            jExceptionClass = env->FindClass("io/realm/internal/OutOfMemoryError");
            message = classStr + " " + itemStr;
            break;

        case Unspecified:
            jExceptionClass = env->FindClass("java/lang/RuntimeException");
            message = "Unspecified exception. " + classStr;
            break;

        case RuntimeError:
            jExceptionClass = env->FindClass("java/lang/RuntimeException");
            message = classStr;
            break;

        case RowInvalid:
            jExceptionClass = env->FindClass("java/lang/IllegalStateException");
            message = "Illegal State: " + classStr;
            break;
    }
    if (jExceptionClass != NULL)
        env->ThrowNew(jExceptionClass, message.c_str());
    else {
        TR_ERR((env, "\nERROR: Couldn't throw exception.\n"));
    }

    env->DeleteLocalRef(jExceptionClass);
}

jclass GetClass(JNIEnv* env, const char* classStr)
{
    jclass localRefClass = env->FindClass(classStr);
    if (localRefClass == NULL) {
        ThrowException(env, ClassNotFound, classStr);
        return NULL;
    }

    jclass myClass = reinterpret_cast<jclass>( env->NewGlobalRef(localRefClass) );
    env->DeleteLocalRef(localRefClass);
    return myClass;
}

void jprint(JNIEnv *env, char *txt)
{
#if 1
    static_cast<void>(env);
    fprintf(stderr, " -- JNI: %s", txt);  fflush(stderr);
#else
    static jclass myClass = GetClass(env, "io/realm/internal/Util");
    static jmethodID myMethod = env->GetStaticMethodID(myClass, "javaPrint", "(Ljava/lang/String;)V");
    if (myMethod)
        env->CallStaticVoidMethod(myClass, myMethod, to_jstring(env, txt));
    else
        ThrowException(env, NoSuchMethod, "Util", "javaPrint");
#endif
}

void jprintf(JNIEnv *env, const char *format, ...)
{
    va_list argptr;
    char buf[200];
    va_start(argptr, format);
    //vfprintf(stderr, format, argptr);
    vsnprintf(buf, 200, format, argptr);
    jprint(env, buf);
    va_end(argptr);
}

bool GetBinaryData(JNIEnv* env, jobject jByteBuffer, tightdb::BinaryData& bin)
{
    const char* data = static_cast<char*>(env->GetDirectBufferAddress(jByteBuffer));
    if (!data) {
        ThrowException(env, IllegalArgument, "ByteBuffer is invalid");
        return false;
    }
    jlong size = env->GetDirectBufferCapacity(jByteBuffer);
    if (size < 0) {
        ThrowException(env, IllegalArgument, "Can't get BufferCapacity.");
        return false;
    }
    bin = BinaryData(data, S(size));
    return true;
}

//*********************************************************************
// String handling
//*********************************************************************

namespace {

// This assumes that 'jchar' is an integral type with at least 16
// non-sign value bits, that is, an unsigned 16-bit integer, or any
// signed or unsigned integer with more than 16 bits.
struct JcharTraits {
    static jchar to_int_type(jchar c)  TIGHTDB_NOEXCEPT { return c; }
    static jchar to_char_type(jchar i) TIGHTDB_NOEXCEPT { return i; }
};

struct JStringCharsAccessor {
    JStringCharsAccessor(JNIEnv* e, jstring s):
        m_env(e), m_string(s), m_data(e->GetStringChars(s,0)), m_size(get_size(e,s)) {}
    ~JStringCharsAccessor()
    {
        m_env->ReleaseStringChars(m_string, m_data);
    }
    const jchar* data() const TIGHTDB_NOEXCEPT { return m_data; }
    size_t size() const TIGHTDB_NOEXCEPT { return m_size; }

private:
    JNIEnv* const m_env;
    const jstring m_string;
    const jchar* const m_data;
    const size_t m_size;

    static size_t get_size(JNIEnv* e, jstring s)
    {
        size_t size;
        if (int_cast_with_overflow_detect(e->GetStringLength(s), size))
            throw runtime_error("String size overflow");
        return size;
    }
};

} // anonymous namespace

string string_to_hex(const string& message, StringData& str) {
    ostringstream ret;

    const char *s = str.data();
    ret << message;
    for (string::size_type i = 0; i < str.size(); ++i)
        ret << " 0x" << std::hex << std::setfill('0') << std::setw(2) << (int)s[i];
    return ret.str();
}

string string_to_hex(const string& message, const jchar *str, size_t size) {
    ostringstream ret;

    ret << message;
    for (size_t i = 0; i < size; ++i)
        ret << " 0x" << std::hex << std::setfill('0') << std::setw(2) << (int)str[i];
    return ret.str();
}

jstring to_jstring(JNIEnv* env, StringData str)
{
    // Input is UTF-8 and output is UTF-16. Invalid UTF-8 input is
    // silently converted to Unicode replacement characters.

    // We use a small fixed size stack-allocated output buffer to avoid the cost
    // of dynamic allocation for short input strings. If this buffer turns out
    // to be too small, we proceed by calulating an estimate for the actual
    // required output buffer size, and then allocate the buffer dynamically.

    const size_t stack_buf_size = 48;
    jchar stack_buf[stack_buf_size];
    Buffer<jchar> dyn_buf;

    const char* in = str.data();
    const char* in_end = in + str.size();
    jchar* out = stack_buf;
    jchar* out_begin = out;
    jchar* out_end = out_begin + stack_buf_size;

    for (;;) {
        typedef Utf8x16<jchar, JcharTraits> Xcode;
        Xcode::to_utf16(in, in_end, out, out_end);
        bool end_of_input = in == in_end;
        if (end_of_input)
            break;
        bool bad_input = out != out_end;
        if (bad_input) {
            // Discard one or more invalid bytes from the input. We shall follow
            // the stardard way of doing this, namely by first discarding the
            // leading invalid byte, which must either be a sequence lead byte
            // (11xxxxxx) or a stray continuation byte (10xxxxxx), and then
            // discard any additional continuation bytes following leading
            // invalid byte.
            for (;;) {
                ++in;
                end_of_input = in == in_end;
                if (end_of_input)
                    break;
                bool next_byte_is_continuation = unsigned(*in) & 0xC0 == 0x80;
                if (!next_byte_is_continuation)
                    break;
            }
        }
        size_t used_size = out - out_begin; // What we already have
        size_t min_capacity = used_size;
        min_cpacity += 1; // Make space for a replacement character
        size_t in_2 = in; // Avoid clobbering `in`
        if (int_add_with_overflow_detect(min_capacity, Xcode::find_utf16_buf_size(in_2, in_end)))
            throw runtime_error("Buffer size overflow");
        bool copy_stack_buf = dyn_buf.size() == 0;
        size_t used_dyn_buf_size = copy_stack_buf ? 0 : used_size;
        dyn_buf.reserve(used_dyn_buf_size, min_capacity);
        out_begin = dyn_buf.data();
        out_end = dyn_buf.data() + dyn_buf.size();
        out = out_begin + used_size;
        if (copy_stack_buf)
            copy(stack_buf, stack_buf_out_end, out_begin);
        if (bad_input)
            *out++ = JcharTraits::to_char_type(0xFFFD); // Unicode replacement character
    }

    jsize out_size;
    if (int_cast_with_overflow_detect(out - out_begin, out_size))
        throw runtime_error("String size overflow");

    return env->NewString(out_begin, out_size);
}

JStringAccessor::JStringAccessor(JNIEnv* env, jstring str)
{
    // For efficiency, if the incoming UTF-16 string is sufficiently
    // small, we will choose an UTF-8 output buffer whose size (in
    // bytes) is simply 4 times the number of 16-bit elements in the
    // input. This is guaranteed to be enough. However, to avoid
    // excessive over allocation, this is not done for larger input
    // strings.

    JStringCharsAccessor chars(env, str);

    typedef Utf8x16<jchar, JcharTraits> Xcode;
    size_t max_project_size = 48;
    TIGHTDB_ASSERT(max_project_size <= numeric_limits<size_t>::max()/4);
    size_t buf_size;
    if (chars.size() <= max_project_size) {
        buf_size = chars.size() * 4;
    }
    else {
        const jchar* begin = chars.data();
        const jchar* end   = begin + chars.size();
        buf_size = Xcode::find_utf8_buf_size(begin, end);
    }
    m_data.reset(new char[buf_size]);  // throws
    {
        const jchar* in_begin = chars.data();
        const jchar* in_end   = in_begin + chars.size();
        char* out_begin = m_data.get();
        char* out_end   = m_data.get() + buf_size;
        if (!Xcode::to_utf8(in_begin, in_end, out_begin, out_end)) {
            throw runtime_error(string_to_hex("Failure when converting to UTF-8", chars.data(), chars.size()));
        }
        TIGHTDB_ASSERT(in_begin == in_end);
        m_size = out_begin - m_data.get();
    }
}
<commit_msg>Fix for: Lenient UTF-8 -> UTF-16 transcoding (insert replacement characters)<commit_after>/*
 * Copyright 2014 Realm Inc.
 *
 * 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 <algorithm>
#include <stdexcept>

#include <tightdb/util/assert.hpp>
#include <tightdb/util/utf8.hpp>
#include <tightdb/util/buffer.hpp>

#include "util.hpp"
#include "io_realm_internal_Util.h"

using namespace std;
using namespace tightdb;
using namespace tightdb::util;

void ThrowException(JNIEnv* env, ExceptionKind exception, std::string classStr, std::string itemStr)
{
    std::string message;
    jclass jExceptionClass = NULL;

    TR_ERR((env, "\njni: ThrowingException %d, %s, %s.\n", exception, classStr.c_str(), itemStr.c_str()));

    switch (exception) {
        case ClassNotFound:
            jExceptionClass = env->FindClass("java/lang/ClassNotFoundException");
            message = "Class '" + classStr + "' could not be located.";
            break;

        case NoSuchField:
            jExceptionClass = env->FindClass("java/lang/NoSuchFieldException");
            message = "Field '" + itemStr + "' could not be located in class io.realm." + classStr;
            break;

        case NoSuchMethod:
            jExceptionClass = env->FindClass("java/lang/NoSuchMethodException");
            message = "Method '" + itemStr + "' could not be located in class io.realm." + classStr;
            break;

        case IllegalArgument:
            jExceptionClass = env->FindClass("java/lang/IllegalArgumentException");
            message = "Illegal Argument: " + classStr;
            break;

        case TableInvalid:
            jExceptionClass = env->FindClass("java/lang/IllegalStateException");
            message = "Illegal State: " + classStr;
            break;

        case IOFailed:
            jExceptionClass = env->FindClass("io/realm/exceptions/RealmIOException");
            message = "Failed to open " + classStr + ". " + itemStr;
            break;

        case FileNotFound:
            jExceptionClass = env->FindClass("io/realm/exceptions/RealmIOException");
            message = "File not found: " + classStr + ".";
            break;

        case FileAccessError:
            jExceptionClass = env->FindClass("io/realm/exceptions/RealmIOException");
            message = "Failed to access: " + classStr + ". " + itemStr;
            break;

        case IndexOutOfBounds:
            jExceptionClass = env->FindClass("java/lang/ArrayIndexOutOfBoundsException");
            message = classStr;
            break;

        case UnsupportedOperation:
            jExceptionClass = env->FindClass("java/lang/UnsupportedOperationException");
            message = classStr;
            break;

        case OutOfMemory:
            jExceptionClass = env->FindClass("io/realm/internal/OutOfMemoryError");
            message = classStr + " " + itemStr;
            break;

        case Unspecified:
            jExceptionClass = env->FindClass("java/lang/RuntimeException");
            message = "Unspecified exception. " + classStr;
            break;

        case RuntimeError:
            jExceptionClass = env->FindClass("java/lang/RuntimeException");
            message = classStr;
            break;

        case RowInvalid:
            jExceptionClass = env->FindClass("java/lang/IllegalStateException");
            message = "Illegal State: " + classStr;
            break;
    }
    if (jExceptionClass != NULL)
        env->ThrowNew(jExceptionClass, message.c_str());
    else {
        TR_ERR((env, "\nERROR: Couldn't throw exception.\n"));
    }

    env->DeleteLocalRef(jExceptionClass);
}

jclass GetClass(JNIEnv* env, const char* classStr)
{
    jclass localRefClass = env->FindClass(classStr);
    if (localRefClass == NULL) {
        ThrowException(env, ClassNotFound, classStr);
        return NULL;
    }

    jclass myClass = reinterpret_cast<jclass>( env->NewGlobalRef(localRefClass) );
    env->DeleteLocalRef(localRefClass);
    return myClass;
}

void jprint(JNIEnv *env, char *txt)
{
#if 1
    static_cast<void>(env);
    fprintf(stderr, " -- JNI: %s", txt);  fflush(stderr);
#else
    static jclass myClass = GetClass(env, "io/realm/internal/Util");
    static jmethodID myMethod = env->GetStaticMethodID(myClass, "javaPrint", "(Ljava/lang/String;)V");
    if (myMethod)
        env->CallStaticVoidMethod(myClass, myMethod, to_jstring(env, txt));
    else
        ThrowException(env, NoSuchMethod, "Util", "javaPrint");
#endif
}

void jprintf(JNIEnv *env, const char *format, ...)
{
    va_list argptr;
    char buf[200];
    va_start(argptr, format);
    //vfprintf(stderr, format, argptr);
    vsnprintf(buf, 200, format, argptr);
    jprint(env, buf);
    va_end(argptr);
}

bool GetBinaryData(JNIEnv* env, jobject jByteBuffer, tightdb::BinaryData& bin)
{
    const char* data = static_cast<char*>(env->GetDirectBufferAddress(jByteBuffer));
    if (!data) {
        ThrowException(env, IllegalArgument, "ByteBuffer is invalid");
        return false;
    }
    jlong size = env->GetDirectBufferCapacity(jByteBuffer);
    if (size < 0) {
        ThrowException(env, IllegalArgument, "Can't get BufferCapacity.");
        return false;
    }
    bin = BinaryData(data, S(size));
    return true;
}

//*********************************************************************
// String handling
//*********************************************************************

namespace {

// This assumes that 'jchar' is an integral type with at least 16
// non-sign value bits, that is, an unsigned 16-bit integer, or any
// signed or unsigned integer with more than 16 bits.
struct JcharTraits {
    static jchar to_int_type(jchar c)  TIGHTDB_NOEXCEPT { return c; }
    static jchar to_char_type(jchar i) TIGHTDB_NOEXCEPT { return i; }
};

struct JStringCharsAccessor {
    JStringCharsAccessor(JNIEnv* e, jstring s):
        m_env(e), m_string(s), m_data(e->GetStringChars(s,0)), m_size(get_size(e,s)) {}
    ~JStringCharsAccessor()
    {
        m_env->ReleaseStringChars(m_string, m_data);
    }
    const jchar* data() const TIGHTDB_NOEXCEPT { return m_data; }
    size_t size() const TIGHTDB_NOEXCEPT { return m_size; }

private:
    JNIEnv* const m_env;
    const jstring m_string;
    const jchar* const m_data;
    const size_t m_size;

    static size_t get_size(JNIEnv* e, jstring s)
    {
        size_t size;
        if (int_cast_with_overflow_detect(e->GetStringLength(s), size))
            throw runtime_error("String size overflow");
        return size;
    }
};

} // anonymous namespace

string string_to_hex(const string& message, StringData& str) {
    ostringstream ret;

    const char *s = str.data();
    ret << message;
    for (string::size_type i = 0; i < str.size(); ++i)
        ret << " 0x" << std::hex << std::setfill('0') << std::setw(2) << (int)s[i];
    return ret.str();
}

string string_to_hex(const string& message, const jchar *str, size_t size) {
    ostringstream ret;

    ret << message;
    for (size_t i = 0; i < size; ++i)
        ret << " 0x" << std::hex << std::setfill('0') << std::setw(2) << (int)str[i];
    return ret.str();
}

jstring to_jstring(JNIEnv* env, StringData str)
{
    // Input is UTF-8 and output is UTF-16. Invalid UTF-8 input is
    // silently converted to Unicode replacement characters.

    // We use a small fixed size stack-allocated output buffer to avoid the cost
    // of dynamic allocation for short input strings. If this buffer turns out
    // to be too small, we proceed by calulating an estimate for the actual
    // required output buffer size, and then allocate the buffer dynamically.

    const size_t stack_buf_size = 48;
    jchar stack_buf[stack_buf_size];
    Buffer<jchar> dyn_buf;

    const char* in = str.data();
    const char* in_end = in + str.size();
    jchar* out = stack_buf;
    jchar* out_begin = out;
    jchar* out_end = out_begin + stack_buf_size;

    for (;;) {
        typedef Utf8x16<jchar, JcharTraits> Xcode;
        Xcode::to_utf16(in, in_end, out, out_end);
        bool end_of_input = in == in_end;
        if (end_of_input)
            break;
        bool bad_input = out != out_end;
        if (bad_input) {
            // Discard one or more invalid bytes from the input. We shall follow
            // the stardard way of doing this, namely by first discarding the
            // leading invalid byte, which must either be a sequence lead byte
            // (11xxxxxx) or a stray continuation byte (10xxxxxx), and then
            // discard any additional continuation bytes following leading
            // invalid byte.
            for (;;) {
                ++in;
                end_of_input = in == in_end;
                if (end_of_input)
                    break;
                bool next_byte_is_continuation = unsigned(*in) & 0xC0 == 0x80;
                if (!next_byte_is_continuation)
                    break;
            }
        }
        size_t used_size = out - out_begin; // What we already have
        size_t min_capacity = used_size;
        min_cpacity += 1; // Make space for a replacement character
        size_t in_2 = in; // Avoid clobbering `in`
        if (int_add_with_overflow_detect(min_capacity, Xcode::find_utf16_buf_size(in_2, in_end)))
            throw runtime_error("Buffer size overflow");
        bool copy_stack_buf = dyn_buf.size() == 0;
        size_t used_dyn_buf_size = copy_stack_buf ? 0 : used_size;
        dyn_buf.reserve(used_dyn_buf_size, min_capacity);
        out_begin = dyn_buf.data();
        out_end = dyn_buf.data() + dyn_buf.size();
        out = out_begin + used_size;
        if (copy_stack_buf)
            copy(stack_buf, stack_buf_out_end, out_begin);
        if (bad_input)
            *out++ = JcharTraits::to_char_type(0xFFFD); // Unicode replacement character
    }

    jsize out_size;
    if (int_cast_with_overflow_detect(out - out_begin, out_size))
        throw runtime_error("String size overflow");

    return env->NewString(out_begin, out_size);
}

JStringAccessor::JStringAccessor(JNIEnv* env, jstring str)
{
    // For efficiency, if the incoming UTF-16 string is sufficiently
    // small, we will choose an UTF-8 output buffer whose size (in
    // bytes) is simply 4 times the number of 16-bit elements in the
    // input. This is guaranteed to be enough. However, to avoid
    // excessive over allocation, this is not done for larger input
    // strings.

    JStringCharsAccessor chars(env, str);

    typedef Utf8x16<jchar, JcharTraits> Xcode;
    size_t max_project_size = 48;
    TIGHTDB_ASSERT(max_project_size <= numeric_limits<size_t>::max()/4);
    size_t buf_size;
    if (chars.size() <= max_project_size) {
        buf_size = chars.size() * 4;
    }
    else {
        const jchar* begin = chars.data();
        const jchar* end   = begin + chars.size();
        buf_size = Xcode::find_utf8_buf_size(begin, end);
    }
    m_data.reset(new char[buf_size]);  // throws
    {
        const jchar* in_begin = chars.data();
        const jchar* in_end   = in_begin + chars.size();
        char* out_begin = m_data.get();
        char* out_end   = m_data.get() + buf_size;
        if (!Xcode::to_utf8(in_begin, in_end, out_begin, out_end)) {
            throw runtime_error(string_to_hex("Failure when converting to UTF-8", chars.data(), chars.size()));
        }
        TIGHTDB_ASSERT(in_begin == in_end);
        m_size = out_begin - m_data.get();
    }
}
<|endoftext|>


<commit_before>/***********************************************************************
 * File         : pipeline.cpp
 * Author       : Soham J. Desai
 * Date         : 14th January 2014
 * Description  : Superscalar Pipeline for Lab2 ECE 6100
 **********************************************************************/

#include "pipeline.h"
#include <cstdlib>

extern int32_t PIPE_WIDTH;
extern int32_t ENABLE_MEM_FWD;
extern int32_t ENABLE_EXE_FWD;
extern int32_t BPRED_POLICY;

void shift_registers(Pipeline *p,int move_count);

/**********************************************************************
 * Support Function: Read 1 Trace Record From File and populate Fetch Op
 **********************************************************************/

void pipe_get_fetch_op(Pipeline *p, Pipeline_Latch* fetch_op){
    uint8_t bytes_read = 0;
    bytes_read = fread(&fetch_op->tr_entry, 1, sizeof(Trace_Rec), p->tr_file);

    // check for end of trace
    if( bytes_read < sizeof(Trace_Rec)) {
      fetch_op->valid=false;
      p->halt_op_id=p->op_id_tracker;
      return;
    }

    // got an instruction ... hooray!
    fetch_op->valid=true;
    fetch_op->stall=false;
    fetch_op->is_mispred_cbr=false;
    p->op_id_tracker++;
    fetch_op->op_id=p->op_id_tracker;

    return;
}

/**********************************************************************
 * Pipeline Class Member Functions
 **********************************************************************/

Pipeline * pipe_init(FILE *tr_file_in){
    printf("\n** PIPELINE IS %d WIDE **\n\n", PIPE_WIDTH);

    // Initialize Pipeline Internals
    Pipeline *p = (Pipeline *) calloc (1, sizeof (Pipeline));

    p->tr_file = tr_file_in;
    p->halt_op_id = ((uint64_t)-1) - 3;

    // Allocated Branch Predictor
    if(BPRED_POLICY){
      p->b_pred = new BPRED(BPRED_POLICY);
    }

    return p;
}

/**********************************************************************
 * Print the pipeline state (useful for debugging)
 **********************************************************************/

void pipe_print_state(Pipeline *p){
    std::cout << "--------------------------------------------" << std::endl;
    std::cout <<"cycle count : " << p->stat_num_cycle << " retired_instruction : " << p->stat_retired_inst << std::endl;

    uint8_t latch_type_i = 0;   // Iterates over Latch Types
    uint8_t width_i      = 0;   // Iterates over Pipeline Width
    for(latch_type_i = 0; latch_type_i < NUM_LATCH_TYPES; latch_type_i++) {
        switch(latch_type_i) {
            case 0:
                printf("    FE: ");
                break;
            case 1:
                printf("    ID: ");
                break;
            case 2:
                printf("    EX: ");
                break;
            case 3:
                printf("    MEM: ");
                break;
            default:
                printf(" ---- ");
        }
    }
    printf("\n");
    for(width_i = 0; width_i < PIPE_WIDTH; width_i++) {
        for(latch_type_i = 0; latch_type_i < NUM_LATCH_TYPES; latch_type_i++) {
            if(p->pipe_latch[latch_type_i][width_i].valid == true) {
	      printf(" %6u ",(uint32_t)( p->pipe_latch[latch_type_i][width_i].op_id));
            } else {
                printf(" ------ ");
            }
        }
        printf("\n");
    }
    printf("\n");

}

/**********************************************************************
 * Pipeline Main Function: Every cycle, cycle the stage
 **********************************************************************/

void pipe_cycle(Pipeline *p)
{
    p->stat_num_cycle++;

    pipe_cycle_WB(p);
    pipe_cycle_MEM(p);
    pipe_cycle_EX(p);
    pipe_cycle_ID(p);
    pipe_cycle_FE(p);

	pipe_print_state(p);

}
/**********************************************************************
 * -----------  DO NOT MODIFY THE CODE ABOVE THIS LINE ----------------
 **********************************************************************/

void pipe_cycle_WB(Pipeline *p){
  int ii;
  for(ii=0; ii<PIPE_WIDTH; ii++){
    if(p->pipe_latch[MEM_LATCH][ii].valid){
      p->stat_retired_inst++;
      if(p->pipe_latch[MEM_LATCH][ii].op_id >= p->halt_op_id){
	p->halt=true;
      }
    }
  }
}

//--------------------------------------------------------------------//

void pipe_cycle_MEM(Pipeline *p){
  int ii;
  for(ii=0; ii<PIPE_WIDTH; ii++){
    p->pipe_latch[MEM_LATCH][ii]=p->pipe_latch[EX_LATCH][ii];
  }
}

//--------------------------------------------------------------------//

void pipe_cycle_EX(Pipeline *p){
  int ii;
  for(ii=0; ii<PIPE_WIDTH; ii++){
    p->pipe_latch[EX_LATCH][ii]=p->pipe_latch[ID_LATCH][ii];
  }
}

//--------------------------------------------------------------------//

void pipe_cycle_ID(Pipeline *p){

//resetting the registers
	int i,j;
	for(i=0;i<PIPE_WIDTH;i++){
		p->pipe_latch[ID_LATCH][i].valid = false;
		p->pipe_latch[FE_LATCH][i].stall = false;
	}

  int ii,jj,kk;
  for(ii=0; ii<PIPE_WIDTH; ii++){
	Trace_Rec *fe_entry = &(p->pipe_latch[FE_LATCH][ii].tr_entry);
	for(jj=EX_LATCH; jj<=MEM_LATCH; jj++){
	    for(kk=0; kk<PIPE_WIDTH; kk++){
			Pipeline_Latch *jlatch = &(p->pipe_latch[jj][kk]);
			Trace_Rec *jentry = &(jlatch->tr_entry);

			if(!jlatch->valid){
				continue; // no dependency from this instruction.
			}
			if( (fe_entry->cc_read == 1) && (jentry->cc_write == 1)){
				p->pipe_latch[FE_LATCH][ii].stall = true;
				break;
			}

			if(!jentry->dest_needed){
				continue; // no dependency from this instruction.
			}
			if(fe_entry->src1_needed &&
						 (fe_entry->src1_reg == jentry->dest)){
				p->pipe_latch[FE_LATCH][ii].stall = true;
				break;
			}
			if(fe_entry->src2_needed &&
					 (fe_entry->src2_reg == jentry->dest)){
				p->pipe_latch[FE_LATCH][ii].stall = true;
				break;
			}
		}
	  }
	}

	//finding stalls due to dependencies within ID stage
	for(i=0;i<PIPE_WIDTH;i++){
		Trace_Rec *i_entry = &(p->pipe_latch[FE_LATCH][i].tr_entry);
		for(j=i+1;j<PIPE_WIDTH;j++){
			Trace_Rec *j_entry = &(p->pipe_latch[FE_LATCH][j].tr_entry);

			if( (i_entry->cc_read == 1) && (j_entry->cc_write == 1)){
				p->pipe_latch[FE_LATCH][i].stall = true;
				break;
			}
			if(!j_entry->dest_needed){
				continue; // no dependency from this instruction.
			}
			if(i_entry->src1_needed &&
						 (i_entry->src1_reg == j_entry->dest)){
				p->pipe_latch[FE_LATCH][i].stall = true;
				break;
			}
			if(i_entry->src2_needed &&
					 (i_entry->src2_reg == j_entry->dest)){
				p->pipe_latch[FE_LATCH][i].stall = true;
				break;
			}
		}
	}

	//now we have identified all the stalls. move the non-stalled instructions
	//to ID stage.
	int move_count=0;
	for(i=PIPE_WIDTH-1;i>=0;i--){
		if(!p->pipe_latch[FE_LATCH][i].stall){
			p->pipe_latch[ID_LATCH][i]=p->pipe_latch[FE_LATCH][i];
			move_count++;
		}else{
			break; // stop moving if we encounter a stall
		}
	}
	//shift the remaining FE_LATCH registers down
	shift_registers(p,move_count);

}

void shift_registers(Pipeline *p,int move_count){
	int i,j;
	for(j=0;j<move_count;j++){
		for(i=PIPE_WIDTH-1;i>0;i--){
			p->pipe_latch[FE_LATCH][i]=p->pipe_latch[FE_LATCH][i-1];
		}
		p->pipe_latch[FE_LATCH][0].valid=false;
	}
}

void print_entry(Trace_Rec *tr_entry,int op_id){

	printf("op id : %d\n",op_id);
	switch(tr_entry->op_type){

		case OP_ALU:
			printf("optype : OP_ALU\n");
			break;
		case OP_LD:
			printf("optype : OP_LD\n");
			break;
		case OP_ST:
			printf("optype : OP_ST\n");
			break;
		case OP_CBR:
			printf("optype : OP_CBR\n");
			break;
		case OP_OTHER:
			printf("optype : OP_OTHER\n");
			break;
		default:
			printf("wrong execution path..\n");
	}

	printf("dest : %" SCNu8 "\n",tr_entry->dest);
	printf("dest needed : %" SCNu8 "\n",tr_entry->dest_needed);
	printf("src1_reg : %" SCNu8 "\n",tr_entry->src1_reg);
	printf("src1 needed : %" SCNu8 "\n",tr_entry->src1_needed);
	printf("src2_reg : %" SCNu8 "\n",tr_entry->src2_reg);
	printf("src2 needed : %" SCNu8 "\n",tr_entry->src2_needed);
	printf("cc_write : %" SCNu8 "\n",tr_entry->cc_write);
	printf("cc_read : %" SCNu8 "\n",tr_entry->cc_read);
	printf("\n\n");

}

//--------------------------------------------------------------------//

void pipe_cycle_FE(Pipeline *p){
  int ii;
  Pipeline_Latch fetch_op;

  for(ii=PIPE_WIDTH-1; ii>=0; ii--){
	//fill the remaining registers after stalls
	if(!p->pipe_latch[FE_LATCH][ii].valid){
		pipe_get_fetch_op(p, &fetch_op);

		if(BPRED_POLICY){
		  pipe_check_bpred(p, &fetch_op);
		}

		// copy the op in FE LATCH
		p->pipe_latch[FE_LATCH][ii]=fetch_op;
		print_entry(&fetch_op.tr_entry,fetch_op.op_id);
	}
  }

}

//--------------------------------------------------------------------//

void pipe_check_bpred(Pipeline *p, Pipeline_Latch *fetch_op){
  // call branch predictor here, if mispred then mark in fetch_op
  // update the predictor instantly
  // stall fetch using the flag p->fetch_cbr_stall
}

//--------------------------------------------------------------------//

<commit_msg>A.3 working<commit_after>/***********************************************************************
 * File         : pipeline.cpp
 * Author       : Soham J. Desai
 * Date         : 14th January 2014
 * Description  : Superscalar Pipeline for Lab2 ECE 6100
 **********************************************************************/

#include "pipeline.h"
#include <cstdlib>

extern int32_t PIPE_WIDTH;
extern int32_t ENABLE_MEM_FWD;
extern int32_t ENABLE_EXE_FWD;
extern int32_t BPRED_POLICY;

void shift_registers(Pipeline *p,int move_count);

/**********************************************************************
 * Support Function: Read 1 Trace Record From File and populate Fetch Op
 **********************************************************************/

void pipe_get_fetch_op(Pipeline *p, Pipeline_Latch* fetch_op){
    uint8_t bytes_read = 0;
    bytes_read = fread(&fetch_op->tr_entry, 1, sizeof(Trace_Rec), p->tr_file);

    // check for end of trace
    if( bytes_read < sizeof(Trace_Rec)) {
      fetch_op->valid=false;
      p->halt_op_id=p->op_id_tracker;
      return;
    }

    // got an instruction ... hooray!
    fetch_op->valid=true;
    fetch_op->stall=false;
    fetch_op->is_mispred_cbr=false;
    p->op_id_tracker++;
    fetch_op->op_id=p->op_id_tracker;

    return;
}

/**********************************************************************
 * Pipeline Class Member Functions
 **********************************************************************/

Pipeline * pipe_init(FILE *tr_file_in){
    printf("\n** PIPELINE IS %d WIDE **\n\n", PIPE_WIDTH);

    // Initialize Pipeline Internals
    Pipeline *p = (Pipeline *) calloc (1, sizeof (Pipeline));

    p->tr_file = tr_file_in;
    p->halt_op_id = ((uint64_t)-1) - 3;

    // Allocated Branch Predictor
    if(BPRED_POLICY){
      p->b_pred = new BPRED(BPRED_POLICY);
    }

    return p;
}

/**********************************************************************
 * Print the pipeline state (useful for debugging)
 **********************************************************************/

void pipe_print_state(Pipeline *p){
    std::cout << "--------------------------------------------" << std::endl;
    std::cout <<"cycle count : " << p->stat_num_cycle << " retired_instruction : " << p->stat_retired_inst << std::endl;

    uint8_t latch_type_i = 0;   // Iterates over Latch Types
    uint8_t width_i      = 0;   // Iterates over Pipeline Width
    for(latch_type_i = 0; latch_type_i < NUM_LATCH_TYPES; latch_type_i++) {
        switch(latch_type_i) {
            case 0:
                printf("    FE: ");
                break;
            case 1:
                printf("    ID: ");
                break;
            case 2:
                printf("    EX: ");
                break;
            case 3:
                printf("    MEM: ");
                break;
            default:
                printf(" ---- ");
        }
    }
    printf("\n");
    for(width_i = 0; width_i < PIPE_WIDTH; width_i++) {
        for(latch_type_i = 0; latch_type_i < NUM_LATCH_TYPES; latch_type_i++) {
            if(p->pipe_latch[latch_type_i][width_i].valid == true) {
	      printf(" %6u ",(uint32_t)( p->pipe_latch[latch_type_i][width_i].op_id));
            } else {
                printf(" ------ ");
            }
        }
        printf("\n");
    }
    printf("\n");

}

/**********************************************************************
 * Pipeline Main Function: Every cycle, cycle the stage
 **********************************************************************/

void pipe_cycle(Pipeline *p)
{
    p->stat_num_cycle++;

    pipe_cycle_WB(p);
    pipe_cycle_MEM(p);
    pipe_cycle_EX(p);
    pipe_cycle_ID(p);
    pipe_cycle_FE(p);

	pipe_print_state(p);

}
/**********************************************************************
 * -----------  DO NOT MODIFY THE CODE ABOVE THIS LINE ----------------
 **********************************************************************/

void pipe_cycle_WB(Pipeline *p){
  int ii;
  for(ii=0; ii<PIPE_WIDTH; ii++){
    if(p->pipe_latch[MEM_LATCH][ii].valid){
      p->stat_retired_inst++;
      if(p->pipe_latch[MEM_LATCH][ii].op_id >= p->halt_op_id){
	p->halt=true;
      }
    }
  }
}

//--------------------------------------------------------------------//

void pipe_cycle_MEM(Pipeline *p){
  int ii;
  for(ii=0; ii<PIPE_WIDTH; ii++){
    p->pipe_latch[MEM_LATCH][ii]=p->pipe_latch[EX_LATCH][ii];
  }
}

//--------------------------------------------------------------------//

void pipe_cycle_EX(Pipeline *p){
  int ii;
  for(ii=0; ii<PIPE_WIDTH; ii++){
    p->pipe_latch[EX_LATCH][ii]=p->pipe_latch[ID_LATCH][ii];
  }
}

//--------------------------------------------------------------------//

void pipe_cycle_ID(Pipeline *p){
	int forwarding_enabled = ENABLE_EXE_FWD && ENABLE_MEM_FWD;
//resetting the registers
	int i,j;
	for(i=0;i<PIPE_WIDTH;i++){
		p->pipe_latch[ID_LATCH][i].valid = false;
		p->pipe_latch[FE_LATCH][i].stall = false;
	}

  int ii,jj,kk;
  for(ii=0; ii<PIPE_WIDTH; ii++){
	Trace_Rec *fe_entry = &(p->pipe_latch[FE_LATCH][ii].tr_entry);
	for(jj=EX_LATCH; jj<=MEM_LATCH; jj++){
	    for(kk=0; kk<PIPE_WIDTH; kk++){
			Pipeline_Latch *jlatch = &(p->pipe_latch[jj][kk]);
			Trace_Rec *jentry = &(jlatch->tr_entry);

			if(!jlatch->valid){
				continue; // no dependency from this instruction.
			}

			if(forwarding_enabled && (jj==MEM_LATCH)){
				continue; // no dependency in the MEM Stage if forwarding enabled
			}

			if(forwarding_enabled && (jj==EX_LATCH)){
				if(jentry->op_type != OP_LD){
					continue; //only LD operations have dependency
				}
			}

			if( (fe_entry->cc_read == 1) && (jentry->cc_write == 1)){
				p->pipe_latch[FE_LATCH][ii].stall = true;
				break;
			}

			if(!jentry->dest_needed){
				continue; // no dependency from this instruction.
			}
			if(fe_entry->src1_needed &&
						 (fe_entry->src1_reg == jentry->dest)){
				p->pipe_latch[FE_LATCH][ii].stall = true;
				break;
			}
			if(fe_entry->src2_needed &&
					 (fe_entry->src2_reg == jentry->dest)){
				p->pipe_latch[FE_LATCH][ii].stall = true;
				break;
			}
		}
	  }
	}

	//finding stalls due to dependencies within ID stage
	for(i=0;i<PIPE_WIDTH;i++){
		Trace_Rec *i_entry = &(p->pipe_latch[FE_LATCH][i].tr_entry);
		for(j=i+1;j<PIPE_WIDTH;j++){
			Trace_Rec *j_entry = &(p->pipe_latch[FE_LATCH][j].tr_entry);

			if( (i_entry->cc_read == 1) && (j_entry->cc_write == 1)){
				p->pipe_latch[FE_LATCH][i].stall = true;
				break;
			}
			if(!j_entry->dest_needed){
				continue; // no dependency from this instruction.
			}
			if(i_entry->src1_needed &&
						 (i_entry->src1_reg == j_entry->dest)){
				p->pipe_latch[FE_LATCH][i].stall = true;
				break;
			}
			if(i_entry->src2_needed &&
					 (i_entry->src2_reg == j_entry->dest)){
				p->pipe_latch[FE_LATCH][i].stall = true;
				break;
			}
		}
	}

	//now we have identified all the stalls. move the non-stalled instructions
	//to ID stage.
	int move_count=0;
	for(i=PIPE_WIDTH-1;i>=0;i--){
		if(!p->pipe_latch[FE_LATCH][i].stall){
			p->pipe_latch[ID_LATCH][i]=p->pipe_latch[FE_LATCH][i];
			move_count++;
		}else{
			break; // stop moving if we encounter a stall
		}
	}
	//shift the remaining FE_LATCH registers down
	shift_registers(p,move_count);

}

void shift_registers(Pipeline *p,int move_count){
	int i,j;
	for(j=0;j<move_count;j++){
		for(i=PIPE_WIDTH-1;i>0;i--){
			p->pipe_latch[FE_LATCH][i]=p->pipe_latch[FE_LATCH][i-1];
		}
		p->pipe_latch[FE_LATCH][0].valid=false;
	}
}

void print_entry(Trace_Rec *tr_entry,int op_id){

	printf("op id : %d\n",op_id);
	switch(tr_entry->op_type){

		case OP_ALU:
			printf("optype : OP_ALU\n");
			break;
		case OP_LD:
			printf("optype : OP_LD\n");
			break;
		case OP_ST:
			printf("optype : OP_ST\n");
			break;
		case OP_CBR:
			printf("optype : OP_CBR\n");
			break;
		case OP_OTHER:
			printf("optype : OP_OTHER\n");
			break;
		default:
			printf("wrong execution path..\n");
	}

	printf("dest : %" SCNu8 "\n",tr_entry->dest);
	printf("dest needed : %" SCNu8 "\n",tr_entry->dest_needed);
	printf("src1_reg : %" SCNu8 "\n",tr_entry->src1_reg);
	printf("src1 needed : %" SCNu8 "\n",tr_entry->src1_needed);
	printf("src2_reg : %" SCNu8 "\n",tr_entry->src2_reg);
	printf("src2 needed : %" SCNu8 "\n",tr_entry->src2_needed);
	printf("cc_write : %" SCNu8 "\n",tr_entry->cc_write);
	printf("cc_read : %" SCNu8 "\n",tr_entry->cc_read);
	printf("\n\n");

}

//--------------------------------------------------------------------//

void pipe_cycle_FE(Pipeline *p){
  int ii;
  Pipeline_Latch fetch_op;

  for(ii=PIPE_WIDTH-1; ii>=0; ii--){
    //fill the remaining registers after stalls
    if(!p->pipe_latch[FE_LATCH][ii].valid){
        pipe_get_fetch_op(p, &fetch_op);

        if(BPRED_POLICY){
          pipe_check_bpred(p, &fetch_op);
        }

        // copy the op in FE LATCH
        p->pipe_latch[FE_LATCH][ii]=fetch_op;
        print_entry(&fetch_op.tr_entry,fetch_op.op_id);
    }
  }

}

//--------------------------------------------------------------------//

void pipe_check_bpred(Pipeline *p, Pipeline_Latch *fetch_op){
  // call branch predictor here, if mispred then mark in fetch_op
  // update the predictor instantly
  // stall fetch using the flag p->fetch_cbr_stall
	p->fetch_cbr_stall=true;
}

//--------------------------------------------------------------------//

<|endoftext|>


<commit_before>/*
 * This file is part of the Camera Streaming Daemon
 *
 * Copyright (C) 2017  Intel Corporation. All rights reserved.
 *
 * 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 <assert.h>
#include <string.h>

#include "log.h"
#include "mainloop.h"
#include "pollable.h"

#define DEFAULT_BUF_SIZE 1024

Pollable::Pollable()
    : _fd(0)
    , _read_handler(0)
    , _write_handler(0)
    , _read_buf{DEFAULT_BUF_SIZE, new uint8_t[DEFAULT_BUF_SIZE]}
    , _write_buf{0, nullptr}
    , _read_cb([](const struct buffer &buf) {})
{
}

bool Pollable::_can_read(const void *data, int flags)
{
    assert(data);

    Pollable *p = (Pollable *)data;

    int r = p->_do_read(p->_read_buf);
    if (r == -EAGAIN) {
        log_debug("Read package failed. Trying again.");
        return true;
    }
    if (r < 0) {
        p->_read_handler = 0;
        return false;
    }
    if (r > 0) {
        struct buffer tmp_buf = {(unsigned int)r, p->_read_buf.data};
        p->_read_cb(tmp_buf);
    }
    return true;
}

bool Pollable::_can_write(const void *data, int flags)
{
    assert(data);

    Pollable *p = (Pollable *)data;
    int r;

    if (!p->_write_buf.data)
        goto end;

    r = p->_do_write(p->_write_buf);
    if (r == -EAGAIN) {
        log_debug("Write package failed. Trying again.");
        return true;
    }

    delete[] p->_write_buf.data;
    p->_write_buf = {0, nullptr};
end:
    p->_write_handler = 0;
    return false;
}

void Pollable::monitor_read(bool monitor)
{
    Mainloop *m = Mainloop::get_mainloop();

    if (_read_handler)
        m->remove_fd(_read_handler);

    if (monitor)
        _read_handler = m->add_fd(_fd, Mainloop::IO_IN, _can_read, this);
    else
        _read_handler = 0;
}

int Pollable::write(const struct buffer &buf)
{
    int r;
    r = _do_write(buf);
    if (r >= 0)
        return 0;

    if (_write_buf.data) {
        delete[] _write_buf.data;
        log_warning("There was another packet to be sent. Dropping that packet.");
    }

    _write_buf = {buf.len, new uint8_t[buf.len]};
    memcpy(_write_buf.data, buf.data, buf.len);

    if (!_write_handler)
        _write_handler = Mainloop::get_mainloop()->add_fd(_fd, Mainloop::IO_OUT, _can_write, this);
    return 0;
}

void Pollable::set_read_callback(std::function<void(const struct buffer &buf)> cb)
{
    _read_cb = cb;
}
<commit_msg>pollable: Return the number of written bytes on success<commit_after>/*
 * This file is part of the Camera Streaming Daemon
 *
 * Copyright (C) 2017  Intel Corporation. All rights reserved.
 *
 * 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 <assert.h>
#include <string.h>

#include "log.h"
#include "mainloop.h"
#include "pollable.h"

#define DEFAULT_BUF_SIZE 1024

Pollable::Pollable()
    : _fd(0)
    , _read_handler(0)
    , _write_handler(0)
    , _read_buf{DEFAULT_BUF_SIZE, new uint8_t[DEFAULT_BUF_SIZE]}
    , _write_buf{0, nullptr}
    , _read_cb([](const struct buffer &buf) {})
{
}

bool Pollable::_can_read(const void *data, int flags)
{
    assert(data);

    Pollable *p = (Pollable *)data;

    int r = p->_do_read(p->_read_buf);
    if (r == -EAGAIN) {
        log_debug("Read package failed. Trying again.");
        return true;
    }
    if (r < 0) {
        p->_read_handler = 0;
        return false;
    }
    if (r > 0) {
        struct buffer tmp_buf = {(unsigned int)r, p->_read_buf.data};
        p->_read_cb(tmp_buf);
    }
    return true;
}

bool Pollable::_can_write(const void *data, int flags)
{
    assert(data);

    Pollable *p = (Pollable *)data;
    int r;

    if (!p->_write_buf.data)
        goto end;

    r = p->_do_write(p->_write_buf);
    if (r == -EAGAIN) {
        log_debug("Write package failed. Trying again.");
        return true;
    }

    delete[] p->_write_buf.data;
    p->_write_buf = {0, nullptr};
end:
    p->_write_handler = 0;
    return false;
}

void Pollable::monitor_read(bool monitor)
{
    Mainloop *m = Mainloop::get_mainloop();

    if (_read_handler)
        m->remove_fd(_read_handler);

    if (monitor)
        _read_handler = m->add_fd(_fd, Mainloop::IO_IN, _can_read, this);
    else
        _read_handler = 0;
}

int Pollable::write(const struct buffer &buf)
{
    int r;
    r = _do_write(buf);
    if (r >= 0)
        return r;

    if (_write_buf.data) {
        delete[] _write_buf.data;
        log_warning("There was another packet to be sent. Dropping that packet.");
    }

    _write_buf = {buf.len, new uint8_t[buf.len]};
    memcpy(_write_buf.data, buf.data, buf.len);

    if (!_write_handler)
        _write_handler = Mainloop::get_mainloop()->add_fd(_fd, Mainloop::IO_OUT, _can_write, this);
    return 0;
}

void Pollable::set_read_callback(std::function<void(const struct buffer &buf)> cb)
{
    _read_cb = cb;
}
<|endoftext|>


<commit_before>#include <string.h>
#include <iostream>
#include <unistd.h>
#include <sstream>
#include <math.h>
#include <sys/time.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include "base64.h"
#include <jansson.h>
#include "poloniex.h"
#include "curl_fun.h"

namespace Poloniex {

double getQuote(Parameters& params, bool isBid) {
  bool GETRequest = false;
  json_t* root = getJsonFromUrl(params, "https://poloniex.com/public?command=returnTicker", "", GETRequest);
  const char* quote;
  double quoteValue;
  if (isBid) {
    quote = json_string_value(json_object_get(json_object_get(root, "USDT_BTC"), "highestBid"));
  } else {
    quote = json_string_value(json_object_get(json_object_get(root, "USDT_BTC"), "lowestAsk"));
  }
  if (quote != NULL) {
    quoteValue = atof(quote);
  } else {
    quoteValue = 0.0;
  }
  json_decref(root);
  return quoteValue;
}

double getAvail(Parameters& params, std::string currency) {
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "returnBalances");
  json_t* result = json_object_get(root, "result");
  if (json_object_size(result) == 0) {
    return 0.0;
  }
  double available = 0.0;
  if (currency.compare("usd") == 0) {
    const char * avail_str = json_string_value(json_object_get(result, "USDT"));
    available = avail_str ? atof(avail_str) : 0.0;
  } else if (currency.compare("btc") == 0) {
    const char * avail_str = json_string_value(json_object_get(result, "BTC"));
    available = avail_str ? atof(avail_str) : 0.0;
  } else {
    *params.logFile << "<Poloniex> Currency not supported" << std::endl;
  }
  return available;
}

int sendLongOrder(Parameters& params, std::string direction, double quantity, double price) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  *params.logFile << "<Poloniex> Trying to send a \"" << direction << "\" limit order: " << quantity << "@$" << price << "..." << std::endl;
  std::ostringstream oss;
  std::string options = oss.str();
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "marginBuy", options);
  int orderId = json_integer_value(json_object_get(root, "order_id"));
  *params.logFile << "<Poloniex> Done (order ID: " << orderId << ")\n" << std::endl;
  json_decref(root);
  return orderId;
}

int sendShortOrder(Parameters& params, std::string direction, double quantity, double price) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  *params.logFile << "<Poloniex> Trying to send a \"" << direction << "\" limit order: " << quantity << "@$" << price << "..." << std::endl;
  std::ostringstream oss;
  std::string options = oss.str();
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "marginSell", options);
  int orderId = json_integer_value(json_object_get(root, "order_id"));
  *params.logFile << "<Poloniex> Done (order ID: " << orderId << ")\n" << std::endl;
  json_decref(root);
  return orderId;
}

bool isOrderComplete(Parameters& params, int orderId) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  if (orderId == 0) {
    return true;
  }
  std::ostringstream oss;
  oss << "\"order_id\":" << orderId;
  std::string options = oss.str();
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "order/status", options);
  bool isComplete = !json_boolean_value(json_object_get(root, "is_live"));
  json_decref(root);
  return isComplete;
}

double getActivePos(Parameters& params) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "positions", "");
  double position;
  if (json_array_size(root) == 0) {
    *params.logFile << "<Poloniex> WARNING: BTC position not available, return 0.0" << std::endl;
    position = 0.0;
  } else {
    position = atof(json_string_value(json_object_get(json_array_get(root, 0), "amount")));
  }
  json_decref(root);
  return position;
}

double getLimitPrice(Parameters& params, double volume, bool isBid) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  bool GETRequest = false;
  json_t* root;
  if (isBid) {
    root = json_object_get(getJsonFromUrl(params, "", "", GETRequest), "bids");
  } else {
    root = json_object_get(getJsonFromUrl(params, "", "", GETRequest), "asks");
  }
  *params.logFile << "<Poloniex> Looking for a limit price to fill " << fabs(volume) << " BTC..." << std::endl;
  double tmpVol = 0.0;
  double p;
  double v;
  int i = 0;
    // loop on volume
  while (tmpVol < fabs(volume) * params.orderBookFactor) {
    p = atof("");
    v = atof("");
    *params.logFile << "<Poloniex> order book: " << v << "@$" << p << std::endl;
    tmpVol += v;
    i++;
  }
  double limPrice = 0.0;
  limPrice = atof(json_string_value(json_object_get(json_array_get(root, i-1), "price")));
  json_decref(root);
  return limPrice;
}

json_t* authRequest(Parameters& params, std::string url, std::string request, std::string options) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  struct timeval tv;
  gettimeofday(&tv, NULL);
  unsigned long long nonce = (tv.tv_sec * 1000.0) + (tv.tv_usec * 0.001) + 0.5;
  std::ostringstream oss;
  oss << nonce << params.bitstampClientId << params.bitstampApi;
  unsigned char* digest;
  digest = HMAC(EVP_sha256(), params.bitstampSecret.c_str(), strlen(params.bitstampSecret.c_str()), (unsigned char*)oss.str().c_str(), strlen(oss.str().c_str()), NULL, NULL);
  char mdString[SHA256_DIGEST_LENGTH+100];  // FIXME +100
  for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
    sprintf(&mdString[i*2], "%02X", (unsigned int)digest[i]);
  }
  oss.clear();
  oss.str("");
  oss << "key=" << params.bitstampApi << "&signature=" << mdString << "&nonce=" << nonce << "&" << options;
  std::string postParams = oss.str().c_str();
  CURLcode resCurl;
  if (params.curl) {
    std::string readBuffer;
    curl_easy_setopt(params.curl, CURLOPT_POST,1L);
    curl_easy_setopt(params.curl, CURLOPT_POSTFIELDS, postParams.c_str());
    curl_easy_setopt(params.curl, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(params.curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(params.curl, CURLOPT_WRITEDATA, &readBuffer);
    curl_easy_setopt(params.curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(params.curl, CURLOPT_CONNECTTIMEOUT, 10L);
    resCurl = curl_easy_perform(params.curl);
    json_t* root;
    json_error_t error;
    while (resCurl != CURLE_OK) {
      *params.logFile << "<Poloniex> Error with cURL. Retry in 2 sec..." << std::endl;
      sleep(2.0);
      readBuffer = "";
      resCurl = curl_easy_perform(params.curl);
    }
    root = json_loads(readBuffer.c_str(), 0, &error);
    while (!root) {
      *params.logFile << "<Poloniex> Error with JSON:\n" << error.text << std::endl;
      *params.logFile << "<Poloniex> Buffer:\n" << readBuffer.c_str() << std::endl;
      *params.logFile << "<Poloniex> Retrying..." << std::endl;
      sleep(2.0);
      readBuffer = "";
      resCurl = curl_easy_perform(params.curl);
      while (resCurl != CURLE_OK) {
        *params.logFile << "<Poloniex> Error with cURL. Retry in 2 sec..." << std::endl;
        sleep(2.0);
        readBuffer = "";
        resCurl = curl_easy_perform(params.curl);
      }
      root = json_loads(readBuffer.c_str(), 0, &error);
    }
    curl_easy_reset(params.curl);
    return root;
  } else {
    *params.logFile << "<Poloniex> Error with cURL init." << std::endl;
    return NULL;
  }
}

}

<commit_msg>fix compilation err<commit_after>#include <string.h>
#include <iostream>
#include <unistd.h>
#include <sstream>
#include <math.h>
#include <sys/time.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include "base64.h"
#include <jansson.h>
#include "poloniex.h"
#include "curl_fun.h"

namespace Poloniex {

double getQuote(Parameters& params, bool isBid) {
  bool GETRequest = false;
  json_t* root = getJsonFromUrl(params, "https://poloniex.com/public?command=returnTicker", "", GETRequest);
  const char* quote;
  double quoteValue;
  if (isBid) {
    quote = json_string_value(json_object_get(json_object_get(root, "USDT_BTC"), "highestBid"));
  } else {
    quote = json_string_value(json_object_get(json_object_get(root, "USDT_BTC"), "lowestAsk"));
  }
  if (quote != NULL) {
    quoteValue = atof(quote);
  } else {
    quoteValue = 0.0;
  }
  json_decref(root);
  return quoteValue;
}

double getAvail(Parameters& params, std::string currency) {
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "returnBalances", "");
  json_t* result = json_object_get(root, "result");
  if (json_object_size(result) == 0) {
    return 0.0;
  }
  double available = 0.0;
  if (currency.compare("usd") == 0) {
    const char * avail_str = json_string_value(json_object_get(result, "USDT"));
    available = avail_str ? atof(avail_str) : 0.0;
  } else if (currency.compare("btc") == 0) {
    const char * avail_str = json_string_value(json_object_get(result, "BTC"));
    available = avail_str ? atof(avail_str) : 0.0;
  } else {
    *params.logFile << "<Poloniex> Currency not supported" << std::endl;
  }
  return available;
}

int sendLongOrder(Parameters& params, std::string direction, double quantity, double price) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  *params.logFile << "<Poloniex> Trying to send a \"" << direction << "\" limit order: " << quantity << "@$" << price << "..." << std::endl;
  std::ostringstream oss;
  std::string options = oss.str();
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "marginBuy", options);
  int orderId = json_integer_value(json_object_get(root, "order_id"));
  *params.logFile << "<Poloniex> Done (order ID: " << orderId << ")\n" << std::endl;
  json_decref(root);
  return orderId;
}

int sendShortOrder(Parameters& params, std::string direction, double quantity, double price) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  *params.logFile << "<Poloniex> Trying to send a \"" << direction << "\" limit order: " << quantity << "@$" << price << "..." << std::endl;
  std::ostringstream oss;
  std::string options = oss.str();
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "marginSell", options);
  int orderId = json_integer_value(json_object_get(root, "order_id"));
  *params.logFile << "<Poloniex> Done (order ID: " << orderId << ")\n" << std::endl;
  json_decref(root);
  return orderId;
}

bool isOrderComplete(Parameters& params, int orderId) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  if (orderId == 0) {
    return true;
  }
  std::ostringstream oss;
  oss << "\"order_id\":" << orderId;
  std::string options = oss.str();
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "order/status", options);
  bool isComplete = !json_boolean_value(json_object_get(root, "is_live"));
  json_decref(root);
  return isComplete;
}

double getActivePos(Parameters& params) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  json_t* root = authRequest(params, "https://poloniex.com/tradingApi", "positions", "");
  double position;
  if (json_array_size(root) == 0) {
    *params.logFile << "<Poloniex> WARNING: BTC position not available, return 0.0" << std::endl;
    position = 0.0;
  } else {
    position = atof(json_string_value(json_object_get(json_array_get(root, 0), "amount")));
  }
  json_decref(root);
  return position;
}

double getLimitPrice(Parameters& params, double volume, bool isBid) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  bool GETRequest = false;
  json_t* root;
  if (isBid) {
    root = json_object_get(getJsonFromUrl(params, "", "", GETRequest), "bids");
  } else {
    root = json_object_get(getJsonFromUrl(params, "", "", GETRequest), "asks");
  }
  *params.logFile << "<Poloniex> Looking for a limit price to fill " << fabs(volume) << " BTC..." << std::endl;
  double tmpVol = 0.0;
  double p;
  double v;
  int i = 0;
    // loop on volume
  while (tmpVol < fabs(volume) * params.orderBookFactor) {
    p = atof("");
    v = atof("");
    *params.logFile << "<Poloniex> order book: " << v << "@$" << p << std::endl;
    tmpVol += v;
    i++;
  }
  double limPrice = 0.0;
  limPrice = atof(json_string_value(json_object_get(json_array_get(root, i-1), "price")));
  json_decref(root);
  return limPrice;
}

json_t* authRequest(Parameters& params, std::string url, std::string request, std::string options) {
  // TODO
  // This function needs to be implemented
  // The code below is given as a general guideline but needs to be rewritten
  // to match the Poloniex API
  struct timeval tv;
  gettimeofday(&tv, NULL);
  unsigned long long nonce = (tv.tv_sec * 1000.0) + (tv.tv_usec * 0.001) + 0.5;
  std::ostringstream oss;
  oss << nonce << params.bitstampClientId << params.bitstampApi;
  unsigned char* digest;
  digest = HMAC(EVP_sha256(), params.bitstampSecret.c_str(), strlen(params.bitstampSecret.c_str()), (unsigned char*)oss.str().c_str(), strlen(oss.str().c_str()), NULL, NULL);
  char mdString[SHA256_DIGEST_LENGTH+100];  // FIXME +100
  for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
    sprintf(&mdString[i*2], "%02X", (unsigned int)digest[i]);
  }
  oss.clear();
  oss.str("");
  oss << "key=" << params.bitstampApi << "&signature=" << mdString << "&nonce=" << nonce << "&" << options;
  std::string postParams = oss.str().c_str();
  CURLcode resCurl;
  if (params.curl) {
    std::string readBuffer;
    curl_easy_setopt(params.curl, CURLOPT_POST,1L);
    curl_easy_setopt(params.curl, CURLOPT_POSTFIELDS, postParams.c_str());
    curl_easy_setopt(params.curl, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(params.curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(params.curl, CURLOPT_WRITEDATA, &readBuffer);
    curl_easy_setopt(params.curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(params.curl, CURLOPT_CONNECTTIMEOUT, 10L);
    resCurl = curl_easy_perform(params.curl);
    json_t* root;
    json_error_t error;
    while (resCurl != CURLE_OK) {
      *params.logFile << "<Poloniex> Error with cURL. Retry in 2 sec..." << std::endl;
      sleep(2.0);
      readBuffer = "";
      resCurl = curl_easy_perform(params.curl);
    }
    root = json_loads(readBuffer.c_str(), 0, &error);
    while (!root) {
      *params.logFile << "<Poloniex> Error with JSON:\n" << error.text << std::endl;
      *params.logFile << "<Poloniex> Buffer:\n" << readBuffer.c_str() << std::endl;
      *params.logFile << "<Poloniex> Retrying..." << std::endl;
      sleep(2.0);
      readBuffer = "";
      resCurl = curl_easy_perform(params.curl);
      while (resCurl != CURLE_OK) {
        *params.logFile << "<Poloniex> Error with cURL. Retry in 2 sec..." << std::endl;
        sleep(2.0);
        readBuffer = "";
        resCurl = curl_easy_perform(params.curl);
      }
      root = json_loads(readBuffer.c_str(), 0, &error);
    }
    curl_easy_reset(params.curl);
    return root;
  } else {
    *params.logFile << "<Poloniex> Error with cURL init." << std::endl;
    return NULL;
  }
}

}

<|endoftext|>


<commit_before>/*
 * This source file is part of ARK
 * For the latest info, see https://github.com/ArkNX
 *
 * Copyright (c) 2013-2019 ArkNX authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     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 "utility/include/AFUtilityPlugin.h"
#include "utility/include/AFCGUIDModule.h"
//#include "utility/include/AFCLogModule.h"
#include "utility/include/AFCTimerModule.h"
//#include "utility/include/AFCScheduleModule.h"

namespace ark {

ARK_DLL_PLUGIN_ENTRY(AFUtilityPlugin)
ARK_DLL_PLUGIN_EXIT(AFUtilityPlugin)

//////////////////////////////////////////////////////////////////////////
int AFUtilityPlugin::GetPluginVersion()
{
    return 0;
}

const std::string AFUtilityPlugin::GetPluginName()
{
    return GET_CLASS_NAME(AFUtilityPlugin)
}

void AFUtilityPlugin::Install()
{
    // RegisterModule<AFILogModule, AFCLogModule>();
    // RegisterModule<AFIDynamicLogModule, AFCDynamicLogModule>();
    RegisterModule<AFIGUIDModule, AFCGUIDModule>();
    RegisterModule<AFITimerModule, AFCTimerModule>();
    // RegisterModule<AFIScheduleModule, AFCScheduleModule>();
}

void AFUtilityPlugin::Uninstall()
{
    // DeregisterModule<AFIScheduleModule, AFCScheduleModule>();
    DeregisterModule<AFITimerModule, AFCGUIDModule>();
    DeregisterModule<AFIGUIDModule, AFCGUIDModule>();
    // DeregisterModule<AFIDynamicLogModule, AFCDynamicLogModule>();
    // DeregisterModule<AFILogModule, AFCLogModule>();
}

} // namespace ark
<commit_msg>Fix misprint<commit_after>/*
 * This source file is part of ARK
 * For the latest info, see https://github.com/ArkNX
 *
 * Copyright (c) 2013-2019 ArkNX authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     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 "utility/include/AFUtilityPlugin.h"
#include "utility/include/AFCGUIDModule.h"
//#include "utility/include/AFCLogModule.h"
#include "utility/include/AFCTimerModule.h"
//#include "utility/include/AFCScheduleModule.h"

namespace ark {

ARK_DLL_PLUGIN_ENTRY(AFUtilityPlugin)
ARK_DLL_PLUGIN_EXIT(AFUtilityPlugin)

//////////////////////////////////////////////////////////////////////////
int AFUtilityPlugin::GetPluginVersion()
{
    return 0;
}

const std::string AFUtilityPlugin::GetPluginName()
{
    return GET_CLASS_NAME(AFUtilityPlugin)
}

void AFUtilityPlugin::Install()
{
    // RegisterModule<AFILogModule, AFCLogModule>();
    // RegisterModule<AFIDynamicLogModule, AFCDynamicLogModule>();
    RegisterModule<AFIGUIDModule, AFCGUIDModule>();
    RegisterModule<AFITimerModule, AFCTimerModule>();
    // RegisterModule<AFIScheduleModule, AFCScheduleModule>();
}

void AFUtilityPlugin::Uninstall()
{
    // DeregisterModule<AFIScheduleModule, AFCScheduleModule>();
    DeregisterModule<AFITimerModule, AFCTimerModule>();
    DeregisterModule<AFIGUIDModule, AFCGUIDModule>();
    // DeregisterModule<AFIDynamicLogModule, AFCDynamicLogModule>();
    // DeregisterModule<AFILogModule, AFCLogModule>();
}

} // namespace ark
<|endoftext|>


<commit_before>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;
    MTL M;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
    /*
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
     */
    Gals Secret;
    Secret=read_Secretfile(F.Secretfile,F);
    F.Ngal= Secret.size();

	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.Secretfile.c_str());
    std::vector<int> count;
    count=count_galaxies(Secret);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    //read the three input files
    MTL Targ=read_MTLfile(F.Targfile,F,0,0);
    MTL SStars=read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF=read_MTLfile(F.SkyFfile,F,0,1);
    //combine the three input files

    M=Targ;
    M.reserve(Targ.size()+SStars.size()+SkyF.size());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" M size %d \n",M.size());
    //need to fix priority list, combining those from targets, standard stars, skyfibers
    //std::vector<int> p_list=Targ.priority_list;
    //p_list.insert(p_list.end(),SStars.priority_list.begin(),SStars.priority_list.end());
    //p_list.insert(p_list.end(),SkyF.priority_list.begin(),SkyF.priority_list.end());
    //std::sort(p_list.begin(),p_list.end());

    //M.priority_list.clear();
    //M.priority_list.push_back(p_list[0]);
    //for(int i=1;i<p_list.size();++i){
       // if(p_list[i]!=p_list[i-1]){
         //   M.priority_list.push_back(p_list[i]);
           // }
    //}

    assign_priority_class(Targ);

    //establish priority classes
    std::vector <int> count_class(Targ.priority_list.size(),0);
    printf("Number in each priority class.  The last two are SF and SS.\n");
    for(int i;i<Targ.size();++i){
        count_class[Targ[i].priority_class]+=1;
    }
    for(int i;i<Targ.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
	Plates OP = read_plate_centers(F);
    Plates P;
    printf(" future plates %d\n",P.size());
    F.ONplate=OP.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.ONplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel
    collect_galaxies_for_all(M,T,OP,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,OP,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.ONplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);

	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
    // Plans whole survey without sky fibers, standard stars
    // assumes maximum number of observations needed for QSOs, LRGs

    simple_assign(M,OP,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    for (int j=0;j<F.ONplate ;++j){

        //OP[j].is_used=false;
        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){
                //OP[j].is_used=true;
                P.push_back(OP[j]);
                A.suborder.push_back(j);
                //A.inverse_order.push_back(j);
                printf("j  %d   k  %d  value %d\n",j,k,A.TF[j][k]);
                not_done=false;
            }
            //else A.inverse_order.push_back(-1);
        }
    }
    F.Nplate=P.size();
    printf(" Plates after screening %d \n",F.Nplate);
    //if(F.diagnose)diagnostic(M,G,F,A);

    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<2; i++) {
        improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int j=0;j<F.Nplate;++j){
        int js=A.suborder[j];
        A.next_plate=js;
        assign_sf_ss(js,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(js,M,P,pp,F,A);
    }

    init_time_at(time,"# Begin real time assignment",t);

	//Execute plan, updating targets at intervals

    for(int i=0;i<F.pass_intervals.size()&&F.pass_intervals[i]<F.Nplate;++i){
        printf(" before pass = %d  at %d  tiles\n",i,F.pass_intervals[i]);
        //display_results("doc/figs/",G,P,pp,F,A,true);
        //execute this phase (i) of survey
        //A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.Nplate; jj++) {
            int j = A.suborder[A.next_plate];
            printf("  next plate is %d \n",j);
            assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF
            assign_unused(j,M,P,pp,F,A);
            //A.next_plate++;
        }
        //update target information for this interval
        //A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.pass_intervals[i+1]&&jj<F.Nplate; jj++) {
            //int j = A.suborder[A.next_plate];
            int js=A.suborder[jj];
            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
            if (0<=js-F.Analysis) update_plan_from_one_obs(Secret,M,P,pp,F,A,F.Nplate-1); else printf("\n");
            //A.next_plate++;
        }
        /*
        if(A.next_plate<F.Nplate){
        redistribute_tf(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        improve(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        }
         */
        if(F.diagnose)diagnostic(M,Secret,F,A);
    }

	// Results -------------------------------------------------------
    if (F.PrintAscii) for (int j=0; j<F.Nplate; j++){
        write_FAtile_ascii(j,F.outDir,M,P,pp,F,A);
    }

    if (F.PrintFits) for (int j=0; j<F.Nplate; j++){
        fa_write(j,F.outDir,M,P,pp,F,A); // Write output
    }

	display_results("doc/figs/",Secret,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<commit_msg>remove  reserve space for M<commit_after>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;
    MTL M;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
    /*
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
     */

    // Secret contains the identity of each target: QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF
    Gals Secret;
    printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.Secretfile.c_str());
    Secret=read_Secretfile(F.Secretfile,F);
    F.Ngal= Secret.size();

    std::vector<int> count;
    count=count_galaxies(Secret);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    //read the three input files
    MTL Targ=read_MTLfile(F.Targfile,F,0,0);
    MTL SStars=read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF=read_MTLfile(F.SkyFfile,F,0,1);
    //combine the three input files

    M=Targ;

    printf(" M size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" M size %d \n",M.size());

    assign_priority_class(Targ);

    //establish priority classes
    std::vector <int> count_class(Targ.priority_list.size(),0);
    printf("Number in each priority class.  The last two are SF and SS.\n");
    for(int i;i<Targ.size();++i){
        count_class[Targ[i].priority_class]+=1;
    }
    for(int i;i<Targ.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
	Plates OP = read_plate_centers(F);
    Plates P;
    printf(" future plates %d\n",P.size());
    F.ONplate=OP.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.ONplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel
    collect_galaxies_for_all(M,T,OP,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,OP,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.ONplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);

	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
    // Plans whole survey without sky fibers, standard stars
    // assumes maximum number of observations needed for QSOs, LRGs

    simple_assign(M,OP,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    for (int j=0;j<F.ONplate ;++j){
        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){
                 P.push_back(OP[j]);
                A.suborder.push_back(j);
                not_done=false;
            }
        }
    }
    F.Nplate=P.size();
    printf(" Plates after screening %d \n",F.Nplate);
    //if(F.diagnose)diagnostic(M,G,F,A);

    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {
        improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int j=0;j<F.Nplate;++j){
        int js=A.suborder[j];
        A.next_plate=js;
        assign_sf_ss(js,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(js,M,P,pp,F,A);
    }

    init_time_at(time,"# Begin real time assignment",t);

	//Execute plan, updating targets at intervals

    for(int i=0;i<F.pass_intervals.size()&&F.pass_intervals[i]<F.Nplate;++i){
        printf(" before pass = %d  at %d  tiles\n",i,F.pass_intervals[i]);
        //display_results("doc/figs/",G,P,pp,F,A,true);
        //execute this phase (i) of survey
        //A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.Nplate; jj++) {
            int j = A.suborder[A.next_plate];
            printf("  next plate is %d \n",j);
            assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF
            assign_unused(j,M,P,pp,F,A);
            //A.next_plate++;
        }
        //update target information for this interval
        //A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.pass_intervals[i+1]&&jj<F.Nplate; jj++) {
            //int j = A.suborder[A.next_plate];
            int js=A.suborder[jj];
            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
            if (0<=js-F.Analysis) update_plan_from_one_obs(Secret,M,P,pp,F,A,F.Nplate-1); else printf("\n");
            //A.next_plate++;
        }
        /*
        if(A.next_plate<F.Nplate){
        redistribute_tf(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        improve(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        }
         */
        if(F.diagnose)diagnostic(M,Secret,F,A);
    }

	// Results -------------------------------------------------------
    if (F.PrintAscii) for (int j=0; j<F.Nplate; j++){
        write_FAtile_ascii(j,F.outDir,M,P,pp,F,A);
    }

    if (F.PrintFits) for (int j=0; j<F.Nplate; j++){
        fa_write(j,F.outDir,M,P,pp,F,A); // Write output
    }

	display_results("doc/figs/",Secret,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<|endoftext|>