<commit_before>/*
 * Copyright (c) 2016 Shanghai Jiao Tong University.
 *     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.
 *
 * For more about this software visit:
 *
 *      http://ipads.se.sjtu.edu.cn/projects/wukong.html
 *
 */

#pragma once

#ifdef USE_GPU

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>
#include <map>
#include <sstream>
#include "type.hpp"

using namespace std;
using namespace boost::archive;

#define EXT_LIST_MAX_LEN 4
#define EXT_BUCKET_EXTENT_LEN(num_buckets) (num_buckets * 15 / 100 + 1)
#define PREDICATE_NSEGS 4

/**
 * A contiguous space in the indirect-header region
 */
struct ext_bucket_extent_t {
    uint64_t num_ext_buckets;   // capacity
    uint64_t off;       // current offset
    uint64_t start;     // start offset in the indirect header region

    ext_bucket_extent_t() : num_ext_buckets(0), off(0), start(0) {}
    ext_bucket_extent_t(uint64_t nbuckets, uint64_t start_off)
        : num_ext_buckets(nbuckets), off(0), start(start_off) { }

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) {
        ar & num_ext_buckets;
        ar & off;
        ar & start;
    }
};

/**
 * Metadata of a segment
 *
 * Each predicate has four segments:
 * 1) Normal-OUT 2) Normal-IN 3) Index-OUT 4) Index-IN.
 * Normal segments are for normal vertices, while index segments for index vertices.
 * And the IN/OUT indicates the direction of triples in the segment.
 */
struct rdf_segment_meta_t {
    uint64_t num_keys;      // #key of the segment
    uint64_t num_buckets;   // allocated main headers (hash space)
    uint64_t bucket_start;  // start offset of main-header region
    ext_bucket_extent_t ext_bucket_list[EXT_LIST_MAX_LEN];
    int ext_list_sz;        // the length of ext_bucket_list
    uint64_t num_edges;     // #edge of the segment
    uint64_t edge_start;    // start offset in the entry region

    rdf_segment_meta_t() : num_keys(0), num_buckets(0), bucket_start(0),
        ext_list_sz(0), edge_start(0), num_edges(0) {
        memset(&ext_bucket_list, 0, sizeof(ext_bucket_list));
    }

    uint64_t get_ext_bucket() {
        for (int i = 0; i < ext_list_sz; ++i) {
            ext_bucket_extent_t &ext = ext_bucket_list[i];
            if (ext.off < ext.num_ext_buckets) {
                return ext.start + ext.off++;
            }
        }

        return 0;
    }

    void add_ext_buckets(const ext_bucket_extent_t &ext) {
        ext_bucket_list[ext_list_sz++] = ext;
    }

    uint64_t get_total_num_buckets() const {
        uint64_t total = num_buckets;
        for (int i = 0; i < ext_list_sz; ++i) {
            const auto &ext = ext_bucket_list[i];
            total += ext.num_ext_buckets;
        }
        return total;
    }

    int num_key_blocks() const {
        extern int global_block_num_buckets;
        static uint64_t n = get_total_num_buckets();
        return ceil(((double) n) / global_block_num_buckets);
    }

    int num_value_blocks() const {
        extern int global_block_num_edges;
        return ceil(((double) num_edges) / global_block_num_edges);
    }

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) {
        ar & num_buckets;
        ar & bucket_start;
        ar & ext_bucket_list;
        ar & ext_list_sz;
        ar & num_edges;
        ar & edge_start;
    }
};

/**
 * Identifier of a segment
 */
struct segid_t {
    int index;  // normal or index segment
    int dir;  // direction of triples in the segment
    sid_t pid;  // predicate id
    segid_t(): index(0), pid(0), dir(0) { }
    segid_t(int idx, sid_t p, int d) : index(idx), pid(p), dir(d) { }

    bool operator == (const segid_t &s) const {
        return (index == s.index && dir == s.dir && pid == s.pid);
    }

    bool operator < (const segid_t& segid) const {
        if (pid < segid.pid)
            return true;
        else if (pid == segid.pid) {
            if (index < segid.index)
                return true;
            else if (index == segid.index && dir < segid.dir)
                return true;
        }
        return false;
    }

    string stringify() {
        ostringstream ss;
        ss << "[" << index << "|" << pid << "|" << dir << "]";
        return ss.str();
    }

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) {
        ar & index;
        ar & dir;
        ar & pid;
    }
};

/**
 * Metadata synchronization message
 *
 * When run on multiple servers, we need to sync the metadata of segments
 * with each server. Because the layout of kvstore is different in each server.
 * Then light queries running in in-place mode can work correctly.
 */
class SyncSegmentMetaMsg {
public:
    int sender_sid;
    map<segid_t, rdf_segment_meta_t> data;

    SyncSegmentMetaMsg() { }

    SyncSegmentMetaMsg(map<segid_t, rdf_segment_meta_t> data) {
        this->data = data;
    }

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) {
        ar & sender_sid;
        ar & data;
    }
};

#endif  // USE_GPU
<commit_msg>bugfix: cannot use static variable for calculating object's state<commit_after>/*
 * Copyright (c) 2016 Shanghai Jiao Tong University.
 *     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.
 *
 * For more about this software visit:
 *
 *      http://ipads.se.sjtu.edu.cn/projects/wukong.html
 *
 */

#pragma once

#ifdef USE_GPU

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>
#include <map>
#include <sstream>
#include "type.hpp"

using namespace std;
using namespace boost::archive;

#define EXT_LIST_MAX_LEN 1
#define EXT_BUCKET_EXTENT_LEN(num_buckets) (num_buckets * 15 / 100 + 1)
#define PREDICATE_NSEGS 4

/**
 * A contiguous space in the indirect-header region
 */
struct ext_bucket_extent_t {
    uint64_t num_ext_buckets;   // capacity
    uint64_t off;       // current offset
    uint64_t start;     // start offset in the indirect header region

    ext_bucket_extent_t() : num_ext_buckets(0), off(0), start(0) {}
    ext_bucket_extent_t(uint64_t nbuckets, uint64_t start_off)
        : num_ext_buckets(nbuckets), off(0), start(start_off) { }

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) {
        ar & num_ext_buckets;
        ar & off;
        ar & start;
    }
};

/**
 * Metadata of a segment
 *
 * Each predicate has four segments:
 * 1) Normal-OUT 2) Normal-IN 3) Index-OUT 4) Index-IN.
 * Normal segments are for normal vertices, while index segments for index vertices.
 * And the IN/OUT indicates the direction of triples in the segment.
 */
struct rdf_segment_meta_t {
    uint64_t num_keys;      // #key of the segment
    uint64_t num_buckets;   // allocated main headers (hash space)
    uint64_t bucket_start;  // start offset of main-header region
    ext_bucket_extent_t ext_bucket_list[EXT_LIST_MAX_LEN];
    int ext_list_sz;        // the length of ext_bucket_list
    uint64_t num_edges;     // #edge of the segment
    uint64_t edge_start;    // start offset in the entry region

    rdf_segment_meta_t() : num_keys(0), num_buckets(0), bucket_start(0),
        ext_list_sz(0), edge_start(0), num_edges(0) {
        memset(&ext_bucket_list, 0, sizeof(ext_bucket_list));
    }

    uint64_t get_ext_bucket() {
        for (int i = 0; i < ext_list_sz; ++i) {
            ext_bucket_extent_t &ext = ext_bucket_list[i];
            if (ext.off < ext.num_ext_buckets) {
                return ext.start + ext.off++;
            }
        }

        return 0;
    }

    void add_ext_buckets(const ext_bucket_extent_t &ext) {
        ext_bucket_list[ext_list_sz++] = ext;
    }

    inline uint64_t get_total_num_buckets() const {
        uint64_t total = num_buckets;
        for (int i = 0; i < ext_list_sz; ++i) {
            const auto &ext = ext_bucket_list[i];
            total += ext.num_ext_buckets;
        }
        return total;
    }

    int num_key_blocks() const {
        extern int global_block_num_buckets;
        return ceil(((double) get_total_num_buckets()) / global_block_num_buckets);
    }

    int num_value_blocks() const {
        extern int global_block_num_edges;
        return ceil(((double) num_edges) / global_block_num_edges);
    }

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) {
        ar & num_buckets;
        ar & bucket_start;
        ar & ext_bucket_list;
        ar & ext_list_sz;
        ar & num_edges;
        ar & edge_start;
    }
};

/**
 * Identifier of a segment
 */
struct segid_t {
    int index;  // normal or index segment
    int dir;  // direction of triples in the segment
    sid_t pid;  // predicate id
    segid_t(): index(0), pid(0), dir(0) { }
    segid_t(int idx, sid_t p, int d) : index(idx), pid(p), dir(d) { }

    bool operator == (const segid_t &s) const {
        return (index == s.index && dir == s.dir && pid == s.pid);
    }

    bool operator < (const segid_t& segid) const {
        if (pid < segid.pid)
            return true;
        else if (pid == segid.pid) {
            if (index < segid.index)
                return true;
            else if (index == segid.index && dir < segid.dir)
                return true;
        }
        return false;
    }

    string stringify() {
        ostringstream ss;
        ss << "[" << index << "|" << pid << "|" << dir << "]";
        return ss.str();
    }

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) {
        ar & index;
        ar & dir;
        ar & pid;
    }
};

/**
 * Metadata synchronization message
 *
 * When run on multiple servers, we need to sync the metadata of segments
 * with each server. Because the layout of kvstore is different in each server.
 * Then light queries running in in-place mode can work correctly.
 */
class SyncSegmentMetaMsg {
public:
    int sender_sid;
    map<segid_t, rdf_segment_meta_t> data;

    SyncSegmentMetaMsg() { }

    SyncSegmentMetaMsg(map<segid_t, rdf_segment_meta_t> data) {
        this->data = data;
    }

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) {
        ar & sender_sid;
        ar & data;
    }
};

#endif  // USE_GPU
<|endoftext|>


<commit_before>/*
 * This file is part of the Electron Orbital Explorer. The Electron
 * Orbital Explorer is distributed under the Simplified BSD License
 * (also called the "BSD 2-Clause License"), in hopes that these
 * rendering techniques might be used by other programmers in
 * applications such as scientific visualization, video gaming, and so
 * on. If you find value in this software and use its technologies for
 * another purpose, I would love to hear back from you at bjthinks (at)
 * gmail (dot) com. If you improve this software and agree to release
 * your modifications under the below license, I encourage you to fork
 * the development tree on github and push your modifications. The
 * Electron Orbital Explorer's development URL is:
 * https://github.com/bjthinks/orbital-explorer
 * (This paragraph is not part of the software license and may be
 * removed.)
 *
 * Copyright (c) 2013, Brian W. Johnson
 * 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.
 *
 * 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 HOLDER 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.
 */

#ifndef GLPROCS_HH
#define GLPROCS_HH

#ifdef __APPLE__
// TODO: Unsure if this is the best way to do it on OSX
#include <OpenGL/gl3.h>
#else
#include <GL/glew.h>
#endif

void initGLProcs();

#endif
<commit_msg>Remove a TODO from glprocs.hh<commit_after>/*
 * This file is part of the Electron Orbital Explorer. The Electron
 * Orbital Explorer is distributed under the Simplified BSD License
 * (also called the "BSD 2-Clause License"), in hopes that these
 * rendering techniques might be used by other programmers in
 * applications such as scientific visualization, video gaming, and so
 * on. If you find value in this software and use its technologies for
 * another purpose, I would love to hear back from you at bjthinks (at)
 * gmail (dot) com. If you improve this software and agree to release
 * your modifications under the below license, I encourage you to fork
 * the development tree on github and push your modifications. The
 * Electron Orbital Explorer's development URL is:
 * https://github.com/bjthinks/orbital-explorer
 * (This paragraph is not part of the software license and may be
 * removed.)
 *
 * Copyright (c) 2013, Brian W. Johnson
 * 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.
 *
 * 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 HOLDER 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.
 */

#ifndef GLPROCS_HH
#define GLPROCS_HH

#ifdef __APPLE__
#include <OpenGL/gl3.h>
#else
#include <GL/glew.h>
#endif

void initGLProcs();

#endif
<|endoftext|>


<commit_before>#include <string>

#include "coco/connection.h"
#include "coco/execution.h"
#include "coco/task_impl.hpp"
#include "coco/task.h"

namespace coco
{

// -------------------------------------------------------------------
// Attribute
// -------------------------------------------------------------------

AttributeBase::AttributeBase(TaskContext *task,
                             const std::string &name)
    : name_(name)
{
    std::shared_ptr<AttributeBase> shared_this(this);
    task->addAttribute(shared_this);
}

// --------------------------------------------------------------s-----
// Operation
// -------------------------------------------------------------------

OperationBase::OperationBase(TaskContext *task,
                             const std::string &name)
    : name_(name)
{
    std::shared_ptr<OperationBase> shared_this(this);
    task->addOperation(shared_this);
}

OperationInvocation::OperationInvocation(const std::function<void(void)> & f)
    : fx(f)
{}

// -------------------------------------------------------------------
// Port
// -------------------------------------------------------------------

PortBase::PortBase(TaskContext *task, const std::string &name,
                   bool is_output, bool is_event)
    : task_(task), name_(name), is_output_(is_output), is_event_(is_event)
{
    std::shared_ptr<PortBase> shared_this(this);
    task->addPort(shared_this);
}

bool PortBase::isConnected() const
{
    return manager_->hasConnections();
}

unsigned int PortBase::connectionsCount() const
{
    return manager_->connectionsCount();
}

unsigned int PortBase::queueLength(int connection) const
{
    return manager_->queueLenght();
}

void PortBase::triggerComponent()
{
    task_->triggerActivity(this->name_);
}

void PortBase::removeTriggerComponent()
{
    task_->removeTriggerActivity();
}

bool PortBase::addConnection(std::shared_ptr<ConnectionBase> &connection)
{
    if (!is_output_ && is_event_)
    {
        task_->addEventPort(name_);
    }

    manager_->addConnection(connection);
    return true;
}

std::shared_ptr<TaskContext> PortBase::task() const
{ return task_->sharedPtr(); }
// -------------------------------------------------------------------
// Service
// -------------------------------------------------------------------

Service::Service(const std::string &name)
    : name_(name)
{}

bool Service::addAttribute(std::shared_ptr<AttributeBase> &attribute)
{
    if (attributes_[attribute->name()])
    {
        COCO_ERR() << "An attribute with name: " << attribute->name()
                   << " already exist\n";
        return false;
    }
    attributes_[attribute->name()] = attribute;
    return true;
}

std::shared_ptr<AttributeBase> Service::attribute(const std::string &name)
{
    auto it = attributes_.find(name);
    if (it == attributes_.end())
    {
        return nullptr;
    }
    else
    {
        return it->second;
    }
}

bool Service::addPort(std::shared_ptr<PortBase> &port)
{
    if (ports_[port->name()])
    {
        COCO_ERR() << instantiationName() <<  ": A port with name: "
                   << port->name() << " already exist";
        return false;
    }
    else
    {
        ports_[port->name()] = port;
        return true;
    }
}

std::shared_ptr<PortBase> Service::port(const std::string &name)
{
    auto it = ports_.find(name);
    if (it == ports_.end())
            return nullptr;
        else
            return it->second;
}

bool Service::addOperation(std::shared_ptr<OperationBase> &operation)
{
    if (operations_[operation->name()])
    {
        COCO_ERR() << "An operation with name: " << operation->name() << " already exist";
        return false;
    }
    operations_[operation->name()] = operation;
    return true;
}

bool Service::hasPending() const
{
    return !asked_ops_.empty();
}

void Service::stepPending()
{
    auto op = asked_ops_.front();
    asked_ops_.pop_front();
    op.fx();
}

void Service::addPeer(std::shared_ptr<TaskContext> & peer)
{
    peers_.push_back(peer);
}

// const std::unique_ptr<Service> &Service::provides(const std::string &name)
// {
//   auto it = subservices_.find(name);
//   if(it == subservices_.end())
//   {
//        std::unique_ptr<Service> service(new Service(name));
//        subservices_[name] = std::move(service);
//        return subservices_[name];
//  }
//  else
//        return it->second;
//  return nullptr;
// }

TaskContext::TaskContext()
{
    state_ = TaskState::IDLE;
    std::unique_ptr<AttributeBase> attribute(new Attribute<bool>(this, "wait_all_trigger", wait_all_trigger_));
    att_wait_all_trigger_.swap(attribute);
}

void TaskContext::stop()
{}

bool TaskContext::isOnSameThread(const std::shared_ptr<TaskContext> &other) const
{
    return this->actvityId() == other->actvityId();
}

uint32_t TaskContext::actvityId() const
{
    return activity_->id();
}

void TaskContext::triggerActivity(const std::string &port_name)
{
    if (!wait_all_trigger_)
    {
        activity_->trigger();
        return;
    }

//    if (this->instantiationName() == "middle_sink")
//        std::cout << port_name << " " << event_port_num_ << " " << forward_check_ << std::endl;

    /* Check whether all the ports have been triggered.
     * This is done checking the size of the unordered_set.
     * If size equal total number of ports, trigger.
     * To avoid emptying the set, the check is reversed and items are removed
     * till size is zero and activity triggered.
     */
    std::unique_lock<std::mutex> lock(all_trigger_mutex_);
    if (forward_check_)
    {
        event_ports_.insert(port_name);
        if (event_ports_.size() == event_port_num_)
        {
            activity_->trigger();
            forward_check_ = false;
        }
    }
    else
    {
        event_ports_.erase(port_name);
        if (event_ports_.size() == 0)
        {
            activity_->trigger();
            forward_check_ = true;
        }
    }
}

void TaskContext::removeTriggerActivity()
{
    activity_->removeTrigger();
}

util::TimeStatistics TaskContext::timeStatistics()
{
    return engine_->timeStatistics();
}

void TaskContext::resetTimeStatistics()
{
    return engine_->resetTimeStatistics();
}

std::shared_ptr<ExecutionEngine> TaskContext::engine() const
{
    std::cout << "Task " << instantiationName() << " engine" << std::endl;
    return engine_;
}

int long TaskContext::latencyTimestamp()
{
    return engine_->latency_timer.start_time;
}
void TaskContext::setLatencyTimestamp(int long timestamp)
{
    engine_->latency_timer.tmp_time = timestamp;
    //engine_->latency_timer.start_time = timestamp;
}
void TaskContext::setTaskLatencySource()
{
    //engine_- >latency_timer.source = true;
    std::cout << "Task " << instantiationName() << " get" << std::endl;
    engine()->latency_timer.source = true;
}
void TaskContext::setTaskLatencyTarget()
{
    std::cout << "Task " << instantiationName() << " set" << std::endl;
    engine()->latency_timer.target = true;
}

uint32_t PeerTask::actvityId() const
{
    return father_->actvityId();
}

int long PeerTask::latencyTimestamp()
{
    return father_->latencyTimestamp();
}
void PeerTask::setLatencyTimestamp(int long timestamp)
{
    father_->setLatencyTimestamp(timestamp);
}

std::shared_ptr<ExecutionEngine> PeerTask::engine() const
{
    return father_->engine();
}

}  // end of namespace coco

<commit_msg>minor fixes<commit_after>#include <string>

#include "coco/connection.h"
#include "coco/execution.h"
#include "coco/task_impl.hpp"
#include "coco/task.h"

namespace coco
{

// -------------------------------------------------------------------
// Attribute
// -------------------------------------------------------------------

AttributeBase::AttributeBase(TaskContext *task,
                             const std::string &name)
    : name_(name)
{
    std::shared_ptr<AttributeBase> shared_this(this);
    task->addAttribute(shared_this);
}

// --------------------------------------------------------------s-----
// Operation
// -------------------------------------------------------------------

OperationBase::OperationBase(TaskContext *task,
                             const std::string &name)
    : name_(name)
{
    std::shared_ptr<OperationBase> shared_this(this);
    task->addOperation(shared_this);
}

OperationInvocation::OperationInvocation(const std::function<void(void)> & f)
    : fx(f)
{}

// -------------------------------------------------------------------
// Port
// -------------------------------------------------------------------

PortBase::PortBase(TaskContext *task, const std::string &name,
                   bool is_output, bool is_event)
    : task_(task), name_(name), is_output_(is_output), is_event_(is_event)
{
    std::shared_ptr<PortBase> shared_this(this);
    task->addPort(shared_this);
}

bool PortBase::isConnected() const
{
    return manager_->hasConnections();
}

unsigned int PortBase::connectionsCount() const
{
    return manager_->connectionsCount();
}

unsigned int PortBase::queueLength(int connection) const
{
    return manager_->queueLenght();
}

void PortBase::triggerComponent()
{
    task_->triggerActivity(this->name_);
}

void PortBase::removeTriggerComponent()
{
    task_->removeTriggerActivity();
}

bool PortBase::addConnection(std::shared_ptr<ConnectionBase> &connection)
{
    if (!is_output_ && is_event_)
    {
        task_->addEventPort(name_);
    }

    manager_->addConnection(connection);
    return true;
}

std::shared_ptr<TaskContext> PortBase::task() const
{ return task_->sharedPtr(); }
// -------------------------------------------------------------------
// Service
// -------------------------------------------------------------------

Service::Service(const std::string &name)
    : name_(name)
{}

bool Service::addAttribute(std::shared_ptr<AttributeBase> &attribute)
{
    if (attributes_[attribute->name()])
    {
        COCO_ERR() << "An attribute with name: " << attribute->name()
                   << " already exist\n";
        return false;
    }
    attributes_[attribute->name()] = attribute;
    return true;
}

std::shared_ptr<AttributeBase> Service::attribute(const std::string &name)
{
    auto it = attributes_.find(name);
    if (it == attributes_.end())
    {
        return nullptr;
    }
    else
    {
        return it->second;
    }
}

bool Service::addPort(std::shared_ptr<PortBase> &port)
{
    if (ports_[port->name()])
    {
        COCO_ERR() << instantiationName() <<  ": A port with name: "
                   << port->name() << " already exist";
        return false;
    }
    else
    {
        ports_[port->name()] = port;
        return true;
    }
}

std::shared_ptr<PortBase> Service::port(const std::string &name)
{
    auto it = ports_.find(name);
    if (it == ports_.end())
            return nullptr;
        else
            return it->second;
}

bool Service::addOperation(std::shared_ptr<OperationBase> &operation)
{
    if (operations_[operation->name()])
    {
        COCO_ERR() << "An operation with name: " << operation->name() << " already exist";
        return false;
    }
    operations_[operation->name()] = operation;
    return true;
}

bool Service::hasPending() const
{
    return !asked_ops_.empty();
}

void Service::stepPending()
{
    auto op = asked_ops_.front();
    asked_ops_.pop_front();
    op.fx();
}

void Service::addPeer(std::shared_ptr<TaskContext> & peer)
{
    peers_.push_back(peer);
}

// const std::unique_ptr<Service> &Service::provides(const std::string &name)
// {
//   auto it = subservices_.find(name);
//   if(it == subservices_.end())
//   {
//        std::unique_ptr<Service> service(new Service(name));
//        subservices_[name] = std::move(service);
//        return subservices_[name];
//  }
//  else
//        return it->second;
//  return nullptr;
// }

TaskContext::TaskContext()
{
    state_ = TaskState::IDLE;
    std::unique_ptr<AttributeBase> attribute(new Attribute<bool>(this, "wait_all_trigger", wait_all_trigger_));
    att_wait_all_trigger_.swap(attribute);
}

void TaskContext::stop()
{}

bool TaskContext::isOnSameThread(const std::shared_ptr<TaskContext> &other) const
{
    return this->actvityId() == other->actvityId();
}

uint32_t TaskContext::actvityId() const
{
    return activity_->id();
}

void TaskContext::triggerActivity(const std::string &port_name)
{
    if (!wait_all_trigger_)
    {
        activity_->trigger();
        return;
    }

//    if (this->instantiationName() == "middle_sink")
//        std::cout << port_name << " " << event_port_num_ << " " << forward_check_ << std::endl;

    /* Check whether all the ports have been triggered.
     * This is done checking the size of the unordered_set.
     * If size equal total number of ports, trigger.
     * To avoid emptying the set, the check is reversed and items are removed
     * till size is zero and activity triggered.
     */
    std::unique_lock<std::mutex> lock(all_trigger_mutex_);
    if (forward_check_)
    {
        event_ports_.insert(port_name);
        if (event_ports_.size() == event_port_num_)
        {
            activity_->trigger();
            forward_check_ = false;
        }
    }
    else
    {
        event_ports_.erase(port_name);
        if (event_ports_.size() == 0)
        {
            activity_->trigger();
            forward_check_ = true;
        }
    }
}

void TaskContext::removeTriggerActivity()
{
    activity_->removeTrigger();
}

util::TimeStatistics TaskContext::timeStatistics()
{
    return engine_->timeStatistics();
}

void TaskContext::resetTimeStatistics()
{
    return engine_->resetTimeStatistics();
}

std::shared_ptr<ExecutionEngine> TaskContext::engine() const
{
    return engine_;
}

int long TaskContext::latencyTimestamp()
{
    return engine_->latency_timer.start_time;
}
void TaskContext::setLatencyTimestamp(int long timestamp)
{
    engine_->latency_timer.tmp_time = timestamp;
}
void TaskContext::setTaskLatencySource()
{
    engine()->latency_timer.source = true;
}
void TaskContext::setTaskLatencyTarget()
{

    engine()->latency_timer.target = true;
}

uint32_t PeerTask::actvityId() const
{
    return father_->actvityId();
}

int long PeerTask::latencyTimestamp()
{
    return father_->latencyTimestamp();
}
void PeerTask::setLatencyTimestamp(int long timestamp)
{
    father_->setLatencyTimestamp(timestamp);
}

std::shared_ptr<ExecutionEngine> PeerTask::engine() const
{
    return father_->engine();
}

}  // end of namespace coco

<|endoftext|>


<commit_before>#include "gazebo_plugins/gazebo_ros_depth_sensor.h"

#include <assert.h>
#include <algorithm>
#include <string>

namespace gazebo
{
GZ_REGISTER_MODEL_PLUGIN(DepthSensor);

DepthSensor::DepthSensor()
{
  this->depth_.depth = 0;
  this->depth_.pressure = 0;
  this->depth_.temp = 0;
  this->depth_.altitude = 0;
}

DepthSensor::~DepthSensor()
{
  event::Events::DisconnectWorldUpdateBegin(this->update_connection_);

  this->rosnode_->shutdown();

  delete this->rosnode_;
}

void DepthSensor::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
{
  this->world_ = _model->GetWorld();
  this->gravity_ = this->world_->Gravity().Z();

  this->robot_namespace_ = "";
  if (_sdf->HasElement("robotNamespace"))
    this->robot_namespace_ = _sdf->GetElement("robotNamespace")->Get<std::string>() + "/";

  this->sensor_link_name_ = _sdf->GetElement("sensorLink")->Get<std::string>();
  this->sensor_link_ = _model->GetLink(sensor_link_name_);

  this->topic_name_ = _sdf->GetElement("topicName")->Get<std::string>();
  this->rosnode_ = new ros::NodeHandle(this->robot_namespace_);
  this->depth_pub_ = this->rosnode_->advertise<riptide_msgs::Depth>(this->topic_name_, 1);

  this->sea_level_ = _sdf->GetElement("seaLevel")->Get<double>();
  this->fluid_density_ = _sdf->GetElement("fluidDensity")->Get<double>();

  this->update_connection_ = event::Events::ConnectWorldUpdateEnd(boost::bind(&DepthSensor::Update, this));
}

  void DepthSensor::Update()
  {
    double z_pos = this->sensor_link_->GetWorldPose().pos.z;
    this->depth_.depth = this->sea_level_ - z_pos;
    this->depth_.pressure = this->fluid_density_ * this->gravity_ * this->depth_.depth;
    this->depth_pub_.publish(this->depth_);
  }
}
<commit_msg>Stamped the simulated depth sensor<commit_after>#include "gazebo_plugins/gazebo_ros_depth_sensor.h"

#include <assert.h>
#include <algorithm>
#include <string>

namespace gazebo
{
GZ_REGISTER_MODEL_PLUGIN(DepthSensor);

DepthSensor::DepthSensor()
{
  this->depth_.depth = 0;
  this->depth_.pressure = 0;
  this->depth_.temp = 0;
  this->depth_.altitude = 0;
}

DepthSensor::~DepthSensor()
{
  event::Events::DisconnectWorldUpdateBegin(this->update_connection_);

  this->rosnode_->shutdown();

  delete this->rosnode_;
}

void DepthSensor::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
{
  this->world_ = _model->GetWorld();
  this->gravity_ = this->world_->Gravity().Z();

  this->robot_namespace_ = "";
  if (_sdf->HasElement("robotNamespace"))
    this->robot_namespace_ = _sdf->GetElement("robotNamespace")->Get<std::string>() + "/";

  this->sensor_link_name_ = _sdf->GetElement("sensorLink")->Get<std::string>();
  this->sensor_link_ = _model->GetLink(sensor_link_name_);

  this->topic_name_ = _sdf->GetElement("topicName")->Get<std::string>();
  this->rosnode_ = new ros::NodeHandle(this->robot_namespace_);
  this->depth_pub_ = this->rosnode_->advertise<riptide_msgs::Depth>(this->topic_name_, 1);

  this->sea_level_ = _sdf->GetElement("seaLevel")->Get<double>();
  this->fluid_density_ = _sdf->GetElement("fluidDensity")->Get<double>();

  this->update_connection_ = event::Events::ConnectWorldUpdateEnd(boost::bind(&DepthSensor::Update, this));
}

  void DepthSensor::Update()
  {
    double z_pos = this->sensor_link_->GetWorldPose().pos.z;
    this->depth_.depth = this->sea_level_ - z_pos;
    this->depth_.pressure = this->fluid_density_ * this->gravity_ * this->depth_.depth;
    this->depth_pub_.publish(this->depth_);
    this->depth_.header.stamp = ros::Time::now();
  }
}
<|endoftext|>


<commit_before>//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.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 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

#include <signal.h>
#include "bochs.h"
#include "gui/bitmaps/floppya.h"
#include "gui/bitmaps/floppyb.h"
#include "gui/bitmaps/mouse.h"
#include "gui/bitmaps/reset.h"
#include "gui/bitmaps/power.h"
#include "gui/bitmaps/snapshot.h"
#ifdef macintosh
#  include <Disks.h>
#endif

bx_gui_c   bx_gui;

#define BX_GUI_THIS bx_gui.
#define LOG_THIS BX_GUI_THIS

bx_gui_c::bx_gui_c(void)
{
  setprefix("[GUI ]"); // Init in specific_init
  settype(GUILOG);
}

  void
bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheight)
{
  specific_init(&bx_gui, argc, argv, tilewidth, tileheight, BX_HEADER_BAR_Y);

  // Define some bitmaps to use in the headerbar
  BX_GUI_THIS floppyA_bmap_id = create_bitmap(bx_floppya_bmap,
                          BX_FLOPPYA_BMAP_X, BX_FLOPPYA_BMAP_Y);
  BX_GUI_THIS floppyA_eject_bmap_id = create_bitmap(bx_floppya_eject_bmap,
                          BX_FLOPPYA_BMAP_X, BX_FLOPPYA_BMAP_Y);
  BX_GUI_THIS floppyB_bmap_id = create_bitmap(bx_floppyb_bmap,
                          BX_FLOPPYB_BMAP_X, BX_FLOPPYB_BMAP_Y);
  BX_GUI_THIS floppyB_eject_bmap_id = create_bitmap(bx_floppyb_eject_bmap,
                          BX_FLOPPYB_BMAP_X, BX_FLOPPYB_BMAP_Y);
  BX_GUI_THIS mouse_bmap_id = create_bitmap(bx_mouse_bmap,
                          BX_MOUSE_BMAP_X, BX_MOUSE_BMAP_Y);
  BX_GUI_THIS nomouse_bmap_id = create_bitmap(bx_nomouse_bmap,
                          BX_MOUSE_BMAP_X, BX_MOUSE_BMAP_Y);

  BX_GUI_THIS power_bmap_id = create_bitmap(bx_power_bmap, BX_POWER_BMAP_X, BX_POWER_BMAP_Y);
  BX_GUI_THIS reset_bmap_id = create_bitmap(bx_reset_bmap, BX_RESET_BMAP_X, BX_RESET_BMAP_Y);
  BX_GUI_THIS snapshot_bmap_id = create_bitmap(bx_snapshot_bmap, BX_SNAPSHOT_BMAP_X, BX_SNAPSHOT_BMAP_Y);

  // Add the initial bitmaps to the headerbar, and enable callback routine, for use
  // when that bitmap is clicked on

  // Floppy A:
  BX_GUI_THIS floppyA_status = bx_devices.floppy->get_media_status(0);
  if (BX_GUI_THIS floppyA_status)
    BX_GUI_THIS floppyA_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyA_bmap_id,
                          BX_GRAVITY_LEFT, floppyA_handler);
  else
    BX_GUI_THIS floppyA_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyA_eject_bmap_id,
                          BX_GRAVITY_LEFT, floppyA_handler);

  // Floppy B:
  BX_GUI_THIS floppyB_status = bx_devices.floppy->get_media_status(1);
  if (BX_GUI_THIS floppyB_status)
    BX_GUI_THIS floppyB_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyB_bmap_id,
                          BX_GRAVITY_LEFT, floppyB_handler);
  else
    BX_GUI_THIS floppyB_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyB_eject_bmap_id,
                          BX_GRAVITY_LEFT, floppyB_handler);

  // Mouse button
  BX_GUI_THIS mouse_status = gui_get_mouse_enable();
  if (BX_GUI_THIS mouse_status)
    BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS mouse_bmap_id,
                          BX_GRAVITY_LEFT, mouse_handler);
  else
    BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS nomouse_bmap_id,
                          BX_GRAVITY_LEFT, mouse_handler);

  // Power button
  BX_GUI_THIS power_hbar_id = headerbar_bitmap(BX_GUI_THIS power_bmap_id,
                          BX_GRAVITY_RIGHT, power_handler);
  // Reset button
  BX_GUI_THIS reset_hbar_id = headerbar_bitmap(BX_GUI_THIS reset_bmap_id,
                          BX_GRAVITY_RIGHT, reset_handler);
  // Snapshot button
  BX_GUI_THIS snapshot_hbar_id = headerbar_bitmap(BX_GUI_THIS snapshot_bmap_id,
                          BX_GRAVITY_RIGHT, snapshot_handler);

  show_headerbar();
}

  void
bx_gui_c::floppyA_handler(void)
{
  unsigned new_status;

  new_status = bx_devices.floppy->set_media_status(0, !BX_GUI_THIS floppyA_status);
  if (new_status == BX_GUI_THIS floppyA_status)
    return;  // no change made

  BX_GUI_THIS floppyA_status = new_status;
  if (BX_GUI_THIS floppyA_status)
    replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_bmap_id);
  else {
#ifdef macintosh
    // If we are using the Mac floppy driver, eject the disk
    // from the floppy drive
    if (!strcmp(bx_options.floppya.path, SuperDrive))
      DiskEject(1);
#endif
    replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_eject_bmap_id);
    }
}

  void
bx_gui_c::floppyB_handler(void)
{
  unsigned new_status;

  new_status = bx_devices.floppy->set_media_status(1, !BX_GUI_THIS floppyB_status);
  if (new_status == BX_GUI_THIS floppyB_status)
    return;  // no change made

  BX_GUI_THIS floppyB_status = new_status;
  if (BX_GUI_THIS floppyB_status)
    replace_bitmap(BX_GUI_THIS floppyB_hbar_id, BX_GUI_THIS floppyB_bmap_id);
  else
    replace_bitmap(BX_GUI_THIS floppyB_hbar_id, BX_GUI_THIS floppyB_eject_bmap_id);
}

  void
bx_gui_c::reset_handler(void)
{
  BX_INFO(( "system RESET callback." ));
  bx_pc_system.ResetSignal( PCS_SET ); /* XXX is this right? */
  for (int i=0; i<BX_SMP_PROCESSORS; i++)
      BX_CPU(i)->reset(BX_RESET_HARDWARE);
}

  void
bx_gui_c::power_handler(void)
{
  BX_PANIC(("POWER button turned off."));
}

  void
bx_gui_c::snapshot_handler(void)
{
  BX_INFO(( "# SNAPSHOT callback (unimplemented)." ));
  bx_control_panel_entry ();
}

  void
bx_gui_c::mouse_handler(void)
{
  BX_GUI_THIS mouse_status = ! BX_GUI_THIS mouse_status;

  if (BX_GUI_THIS mouse_status)
    replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS mouse_bmap_id);
  else
    replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS nomouse_bmap_id);

  gui_set_mouse_enable(BX_GUI_THIS mouse_status);
}

  Boolean
bx_gui_c::gui_get_mouse_enable(void)
{
  return(bx_options.mouse_enabled);
}

  void
bx_gui_c::gui_set_mouse_enable(Boolean val)
{
  bx_options.mouse_enabled = val;
}

void
bx_gui_c::init_signal_handlers ()
{
#if BX_GUI_SIGHANDLER
  Bit32u mask = get_sighandler_mask ();
  for (Bit32u sig=0; sig<32; sig++)
  {
    if (mask & (1<<sig))
      signal (sig, bx_signal_handler);
  }
#endif
}
<commit_msg>- even if panic is nonfatal, the exit button should still make it quit!<commit_after>//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.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 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

#include <signal.h>
#include "bochs.h"
#include "gui/bitmaps/floppya.h"
#include "gui/bitmaps/floppyb.h"
#include "gui/bitmaps/mouse.h"
#include "gui/bitmaps/reset.h"
#include "gui/bitmaps/power.h"
#include "gui/bitmaps/snapshot.h"
#ifdef macintosh
#  include <Disks.h>
#endif

bx_gui_c   bx_gui;

#define BX_GUI_THIS bx_gui.
#define LOG_THIS BX_GUI_THIS

bx_gui_c::bx_gui_c(void)
{
  setprefix("[GUI ]"); // Init in specific_init
  settype(GUILOG);
}

  void
bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheight)
{
  specific_init(&bx_gui, argc, argv, tilewidth, tileheight, BX_HEADER_BAR_Y);

  // Define some bitmaps to use in the headerbar
  BX_GUI_THIS floppyA_bmap_id = create_bitmap(bx_floppya_bmap,
                          BX_FLOPPYA_BMAP_X, BX_FLOPPYA_BMAP_Y);
  BX_GUI_THIS floppyA_eject_bmap_id = create_bitmap(bx_floppya_eject_bmap,
                          BX_FLOPPYA_BMAP_X, BX_FLOPPYA_BMAP_Y);
  BX_GUI_THIS floppyB_bmap_id = create_bitmap(bx_floppyb_bmap,
                          BX_FLOPPYB_BMAP_X, BX_FLOPPYB_BMAP_Y);
  BX_GUI_THIS floppyB_eject_bmap_id = create_bitmap(bx_floppyb_eject_bmap,
                          BX_FLOPPYB_BMAP_X, BX_FLOPPYB_BMAP_Y);
  BX_GUI_THIS mouse_bmap_id = create_bitmap(bx_mouse_bmap,
                          BX_MOUSE_BMAP_X, BX_MOUSE_BMAP_Y);
  BX_GUI_THIS nomouse_bmap_id = create_bitmap(bx_nomouse_bmap,
                          BX_MOUSE_BMAP_X, BX_MOUSE_BMAP_Y);

  BX_GUI_THIS power_bmap_id = create_bitmap(bx_power_bmap, BX_POWER_BMAP_X, BX_POWER_BMAP_Y);
  BX_GUI_THIS reset_bmap_id = create_bitmap(bx_reset_bmap, BX_RESET_BMAP_X, BX_RESET_BMAP_Y);
  BX_GUI_THIS snapshot_bmap_id = create_bitmap(bx_snapshot_bmap, BX_SNAPSHOT_BMAP_X, BX_SNAPSHOT_BMAP_Y);

  // Add the initial bitmaps to the headerbar, and enable callback routine, for use
  // when that bitmap is clicked on

  // Floppy A:
  BX_GUI_THIS floppyA_status = bx_devices.floppy->get_media_status(0);
  if (BX_GUI_THIS floppyA_status)
    BX_GUI_THIS floppyA_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyA_bmap_id,
                          BX_GRAVITY_LEFT, floppyA_handler);
  else
    BX_GUI_THIS floppyA_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyA_eject_bmap_id,
                          BX_GRAVITY_LEFT, floppyA_handler);

  // Floppy B:
  BX_GUI_THIS floppyB_status = bx_devices.floppy->get_media_status(1);
  if (BX_GUI_THIS floppyB_status)
    BX_GUI_THIS floppyB_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyB_bmap_id,
                          BX_GRAVITY_LEFT, floppyB_handler);
  else
    BX_GUI_THIS floppyB_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyB_eject_bmap_id,
                          BX_GRAVITY_LEFT, floppyB_handler);

  // Mouse button
  BX_GUI_THIS mouse_status = gui_get_mouse_enable();
  if (BX_GUI_THIS mouse_status)
    BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS mouse_bmap_id,
                          BX_GRAVITY_LEFT, mouse_handler);
  else
    BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS nomouse_bmap_id,
                          BX_GRAVITY_LEFT, mouse_handler);

  // Power button
  BX_GUI_THIS power_hbar_id = headerbar_bitmap(BX_GUI_THIS power_bmap_id,
                          BX_GRAVITY_RIGHT, power_handler);
  // Reset button
  BX_GUI_THIS reset_hbar_id = headerbar_bitmap(BX_GUI_THIS reset_bmap_id,
                          BX_GRAVITY_RIGHT, reset_handler);
  // Snapshot button
  BX_GUI_THIS snapshot_hbar_id = headerbar_bitmap(BX_GUI_THIS snapshot_bmap_id,
                          BX_GRAVITY_RIGHT, snapshot_handler);

  show_headerbar();
}

  void
bx_gui_c::floppyA_handler(void)
{
  unsigned new_status;

  new_status = bx_devices.floppy->set_media_status(0, !BX_GUI_THIS floppyA_status);
  if (new_status == BX_GUI_THIS floppyA_status)
    return;  // no change made

  BX_GUI_THIS floppyA_status = new_status;
  if (BX_GUI_THIS floppyA_status)
    replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_bmap_id);
  else {
#ifdef macintosh
    // If we are using the Mac floppy driver, eject the disk
    // from the floppy drive
    if (!strcmp(bx_options.floppya.path, SuperDrive))
      DiskEject(1);
#endif
    replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_eject_bmap_id);
    }
}

  void
bx_gui_c::floppyB_handler(void)
{
  unsigned new_status;

  new_status = bx_devices.floppy->set_media_status(1, !BX_GUI_THIS floppyB_status);
  if (new_status == BX_GUI_THIS floppyB_status)
    return;  // no change made

  BX_GUI_THIS floppyB_status = new_status;
  if (BX_GUI_THIS floppyB_status)
    replace_bitmap(BX_GUI_THIS floppyB_hbar_id, BX_GUI_THIS floppyB_bmap_id);
  else
    replace_bitmap(BX_GUI_THIS floppyB_hbar_id, BX_GUI_THIS floppyB_eject_bmap_id);
}

  void
bx_gui_c::reset_handler(void)
{
  BX_INFO(( "system RESET callback." ));
  bx_pc_system.ResetSignal( PCS_SET ); /* XXX is this right? */
  for (int i=0; i<BX_SMP_PROCESSORS; i++)
      BX_CPU(i)->reset(BX_RESET_HARDWARE);
}

  void
bx_gui_c::power_handler(void)
{
  BX_PANIC(("POWER button turned off."));
  // exit the simulator even if panic did not actually quit.
  ::exit (1);
}

  void
bx_gui_c::snapshot_handler(void)
{
  BX_INFO(( "# SNAPSHOT callback (unimplemented)." ));
  bx_control_panel_entry ();
}

  void
bx_gui_c::mouse_handler(void)
{
  BX_GUI_THIS mouse_status = ! BX_GUI_THIS mouse_status;

  if (BX_GUI_THIS mouse_status)
    replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS mouse_bmap_id);
  else
    replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS nomouse_bmap_id);

  gui_set_mouse_enable(BX_GUI_THIS mouse_status);
}

  Boolean
bx_gui_c::gui_get_mouse_enable(void)
{
  return(bx_options.mouse_enabled);
}

  void
bx_gui_c::gui_set_mouse_enable(Boolean val)
{
  bx_options.mouse_enabled = val;
}

void
bx_gui_c::init_signal_handlers ()
{
#if BX_GUI_SIGHANDLER
  Bit32u mask = get_sighandler_mask ();
  for (Bit32u sig=0; sig<32; sig++)
  {
    if (mask & (1<<sig))
      signal (sig, bx_signal_handler);
  }
#endif
}
<|endoftext|>


<commit_before>/**
 * Unit tests for Branch module
 * @author Graudt Vladimir
 * Copyright 2020 MIPT-MIPS
 */

#include <catch.hpp>
#include <modules/branch/branch.h>
#include <modules/t/test_instr.h>
#include <numeric>

namespace Test {

/* Emulates all modules, which can communicate with Branch */
class BranchTestingEnvironment : public Module {
public:
    using Instr = PerfInstr<BranchTestInstr>;
    using RegisterUInt = typename BranchTestInstr::RegisterUInt;
    using InstructionOutput = std::array< RegisterUInt, MAX_DST_NUM>;

    ReadPort<bool> *rp_flush = nullptr;
    WritePort<bool> *wp_trap = nullptr;

    ReadPort<Target> *rp_flush_target = nullptr;
    ReadPort<BPInterface> *rp_bp_update = nullptr;

    WritePort<Instr> *wp_datapath = nullptr;
    ReadPort<Instr> *rp_datapath = nullptr;

    ReadPort<InstructionOutput> *rp_bypass = nullptr;

    ReadPort<bool> *rp_bypassing_unit_flush_notify = nullptr;

    explicit BranchTestingEnvironment( Module *parent);
};

/* Provides communication between Branch and Environment */
struct BranchTester : public Root {
    Branch<BranchTestInstr> branch;
    BranchTestingEnvironment env;

    BranchTester() : Root( "branch_tester"), branch( this), env( this)
        { init_portmap(); }
};

BranchTestingEnvironment::BranchTestingEnvironment(Module *parent) :
    Module( parent, "branch_testing_environment")
{
    rp_flush = make_read_port<bool>( "BRANCH_2_ALL_FLUSH", Port::LATENCY);
    wp_trap = make_write_port<bool>( "WRITEBACK_2_ALL_FLUSH", Port::BW);

    rp_flush_target = make_read_port<Target>( "BRANCH_2_FETCH_TARGET", Port::LATENCY);
    rp_bp_update = make_read_port<BPInterface>( "BRANCH_2_FETCH", Port::LATENCY);

    wp_datapath = make_write_port<Instr>( "EXECUTE_2_BRANCH", Port::BW);
    rp_datapath = make_read_port<Instr>( "BRANCH_2_WRITEBACK", Port::LATENCY);

    rp_bypass = make_read_port<InstructionOutput>( "BRANCH_2_EXECUTE_BYPASS", Port::LATENCY);
    rp_bypassing_unit_flush_notify = make_read_port<bool>( "BRANCH_2_BYPASSING_UNIT_FLUSH_NOTIFY", Port::LATENCY);
}

auto create_branch( Addr pc, Addr new_pc, Addr branch_target,
    bool should_be_taken, bool predicted_as_taken)
{
    BranchTestInstr func_instr( pc, (should_be_taken) ? branch_target : new_pc, branch_target, should_be_taken);
    BPInterface bpi( pc, predicted_as_taken, (predicted_as_taken) ? branch_target : new_pc, true);

    return PerfInstr<BranchTestInstr>( func_instr, bpi);
}

const Addr pc = 100; // PC of a branch
const Addr new_pc = pc + 4;
const Addr target = pc + 400; // target, if branch is taken

const auto cl_arrange = 0_cl;   // setting environment
const auto cl_act     = 1_cl;   // running branch module
const auto cl_assert  = 2_cl;   // checking results

const auto taken_and_predicted_branch    = create_branch(pc, new_pc, target, true, true);
const auto taken_and_npredicted_branch   = create_branch(pc, new_pc, target, true, false);
const auto ntaken_and_predicted_branch   = create_branch(pc, new_pc, target, false, true);
const auto ntaken_and_npredicted_branch  = create_branch(pc, new_pc, target, false, false);

using InstrPtr = const PerfInstr<BranchTestInstr> *;

TEST_CASE( "Branch::is_misprediction()", "[branch_module]")
{
    BranchTester t;
    CHECK( !t.branch.is_misprediction( taken_and_predicted_branch, taken_and_predicted_branch.get_bp_data()));
    CHECK( t.branch.is_misprediction( taken_and_npredicted_branch, taken_and_npredicted_branch.get_bp_data()));
    CHECK( t.branch.is_misprediction( ntaken_and_predicted_branch, ntaken_and_predicted_branch.get_bp_data()));
    CHECK( !t.branch.is_misprediction( ntaken_and_npredicted_branch, ntaken_and_npredicted_branch.get_bp_data()));
}

#define CHECK_PORT_READY( port) CHECK( ( port)->is_ready( cl_assert))
#define CHECK_PORT_NOT_READY( port) CHECK( !( port)->is_ready( cl_assert))
#define CHECK_PORT_READY_AND_TRUE( port) CHECK_PORT_READY( port); CHECK( ( port)->read( cl_assert) == true)
#define CHECK_PORT_NOT_READY_OR_FALSE( port) CHECK( (!(port)->is_ready( cl_assert) || ( port)->read( cl_assert) == false))

TEST_CASE( "correctly predicted branch", "[branch_module]")
{
    BranchTester t;
    InstrPtr instr = &taken_and_predicted_branch;

    SECTION( "taken_and_predicted_branch") { instr = &taken_and_predicted_branch; }
    SECTION( "ntaken_and_npredicted_branch") { instr = &ntaken_and_npredicted_branch; }

    t.env.wp_datapath->write( *instr, cl_arrange);

    t.branch.clock( cl_act);

    CHECK_PORT_READY( t.env.rp_datapath);
    CHECK_PORT_READY( t.env.rp_bp_update);
    CHECK_PORT_READY( t.env.rp_bypass);
    CHECK_PORT_NOT_READY( t.env.rp_flush_target);
    CHECK_PORT_NOT_READY_OR_FALSE( t.env.rp_flush);
    CHECK_PORT_NOT_READY_OR_FALSE( t.env.rp_bypassing_unit_flush_notify);
    CHECK( t.branch.get_mispredictions_num() == 0);
    CHECK( t.branch.get_jumps_num() == 0);
}

TEST_CASE( "mispredicted branch", "[branch_module]")
{
    BranchTester t;
    InstrPtr instr = nullptr;
    Addr expected_target = NO_VAL<Addr>;

    SECTION( "taken_and_npredicted_branch") { instr = &taken_and_npredicted_branch; expected_target = target; }
    SECTION( "ntaken_and_predicted_branch") { instr = &ntaken_and_predicted_branch; expected_target = new_pc; }

    t.env.wp_datapath->write( *instr, cl_arrange);

    t.branch.clock( cl_act);

    CHECK_PORT_READY( t.env.rp_datapath);
    CHECK_PORT_READY( t.env.rp_bp_update);
    CHECK_PORT_READY( t.env.rp_bypass);
    CHECK_PORT_READY( t.env.rp_flush);
    CHECK_PORT_READY( t.env.rp_flush_target);
    CHECK_PORT_READY_AND_TRUE( t.env.rp_bypassing_unit_flush_notify);
    CHECK( t.branch.get_mispredictions_num() == 1);
    CHECK( t.branch.get_jumps_num() == 0);

    auto actual_target = t.env.rp_flush_target->read( cl_assert);
    CHECK( actual_target.valid);
    CHECK( actual_target.address == expected_target);
    CHECK( actual_target.sequence_id == instr->get_sequence_id() + 1);
}

TEST_CASE( "bypass check", "[branch_module]")
{
    BranchTester t;
    auto instr = taken_and_predicted_branch;
    std::array<uint32, MAX_DST_NUM> dsts = {};

    std::iota(dsts.begin(), dsts.end(), 228);
    for ( int i = 0; i < MAX_DST_NUM; ++i)
        instr.set_v_dst(dsts[i], i);
    t.env.wp_datapath->write( instr, cl_arrange);

    t.branch.clock( cl_act);

    CHECK_PORT_READY( t.env.rp_bypass);
    auto bypass_data = t.env.rp_bypass->read( cl_assert);
    for ( int i = 0; i < MAX_DST_NUM; ++i) {
        INFO( "i = " << i);
        CHECK( bypass_data[i] == dsts[i]);
    }
}

TEST_CASE( "trap received", "[branch_module]")
{
    BranchTester t;
    InstrPtr instr = nullptr;

    SECTION( "taken_and_predicted_branch") { instr = &taken_and_predicted_branch; }
    SECTION( "taken_and_npredicted_branch") { instr = &taken_and_npredicted_branch; }
    SECTION( "ntaken_and_predicted_branch") { instr = &ntaken_and_predicted_branch; }
    SECTION( "ntaken_and_npredicted_branch") { instr = &ntaken_and_npredicted_branch; }

    t.env.wp_datapath->write( *instr, cl_arrange);
    t.env.wp_trap->write(true, cl_arrange);

    t.branch.clock( cl_act);

    CHECK_PORT_NOT_READY( t.env.rp_datapath);
    CHECK_PORT_NOT_READY( t.env.rp_bp_update);
    CHECK_PORT_NOT_READY( t.env.rp_bypass);
}

TEST_CASE( "instruction dump", "[branch_module]")
{
    std::ostringstream oss;
    oss << BranchTestInstr( 0, 0, 0, false);
    CHECK( oss.str() == "BranchTestInstr");
}

} // namespace Test
<commit_msg>Use std::at for runtime indexing<commit_after>/**
 * Unit tests for Branch module
 * @author Graudt Vladimir
 * Copyright 2020 MIPT-MIPS
 */

#include <catch.hpp>
#include <modules/branch/branch.h>
#include <modules/t/test_instr.h>
#include <numeric>

namespace Test {

/* Emulates all modules, which can communicate with Branch */
class BranchTestingEnvironment : public Module {
public:
    using Instr = PerfInstr<BranchTestInstr>;
    using RegisterUInt = typename BranchTestInstr::RegisterUInt;
    using InstructionOutput = std::array< RegisterUInt, MAX_DST_NUM>;

    ReadPort<bool> *rp_flush = nullptr;
    WritePort<bool> *wp_trap = nullptr;

    ReadPort<Target> *rp_flush_target = nullptr;
    ReadPort<BPInterface> *rp_bp_update = nullptr;

    WritePort<Instr> *wp_datapath = nullptr;
    ReadPort<Instr> *rp_datapath = nullptr;

    ReadPort<InstructionOutput> *rp_bypass = nullptr;

    ReadPort<bool> *rp_bypassing_unit_flush_notify = nullptr;

    explicit BranchTestingEnvironment( Module *parent);
};

/* Provides communication between Branch and Environment */
struct BranchTester : public Root {
    Branch<BranchTestInstr> branch;
    BranchTestingEnvironment env;

    BranchTester() : Root( "branch_tester"), branch( this), env( this)
        { init_portmap(); }
};

BranchTestingEnvironment::BranchTestingEnvironment(Module *parent) :
    Module( parent, "branch_testing_environment")
{
    rp_flush = make_read_port<bool>( "BRANCH_2_ALL_FLUSH", Port::LATENCY);
    wp_trap = make_write_port<bool>( "WRITEBACK_2_ALL_FLUSH", Port::BW);

    rp_flush_target = make_read_port<Target>( "BRANCH_2_FETCH_TARGET", Port::LATENCY);
    rp_bp_update = make_read_port<BPInterface>( "BRANCH_2_FETCH", Port::LATENCY);

    wp_datapath = make_write_port<Instr>( "EXECUTE_2_BRANCH", Port::BW);
    rp_datapath = make_read_port<Instr>( "BRANCH_2_WRITEBACK", Port::LATENCY);

    rp_bypass = make_read_port<InstructionOutput>( "BRANCH_2_EXECUTE_BYPASS", Port::LATENCY);
    rp_bypassing_unit_flush_notify = make_read_port<bool>( "BRANCH_2_BYPASSING_UNIT_FLUSH_NOTIFY", Port::LATENCY);
}

auto create_branch( Addr pc, Addr new_pc, Addr branch_target,
    bool should_be_taken, bool predicted_as_taken)
{
    BranchTestInstr func_instr( pc, (should_be_taken) ? branch_target : new_pc, branch_target, should_be_taken);
    BPInterface bpi( pc, predicted_as_taken, (predicted_as_taken) ? branch_target : new_pc, true);

    return PerfInstr<BranchTestInstr>( func_instr, bpi);
}

const Addr pc = 100; // PC of a branch
const Addr new_pc = pc + 4;
const Addr target = pc + 400; // target, if branch is taken

const auto cl_arrange = 0_cl;   // setting environment
const auto cl_act     = 1_cl;   // running branch module
const auto cl_assert  = 2_cl;   // checking results

const auto taken_and_predicted_branch    = create_branch(pc, new_pc, target, true, true);
const auto taken_and_npredicted_branch   = create_branch(pc, new_pc, target, true, false);
const auto ntaken_and_predicted_branch   = create_branch(pc, new_pc, target, false, true);
const auto ntaken_and_npredicted_branch  = create_branch(pc, new_pc, target, false, false);

using InstrPtr = const PerfInstr<BranchTestInstr> *;

TEST_CASE( "Branch::is_misprediction()", "[branch_module]")
{
    BranchTester t;
    CHECK( !t.branch.is_misprediction( taken_and_predicted_branch, taken_and_predicted_branch.get_bp_data()));
    CHECK( t.branch.is_misprediction( taken_and_npredicted_branch, taken_and_npredicted_branch.get_bp_data()));
    CHECK( t.branch.is_misprediction( ntaken_and_predicted_branch, ntaken_and_predicted_branch.get_bp_data()));
    CHECK( !t.branch.is_misprediction( ntaken_and_npredicted_branch, ntaken_and_npredicted_branch.get_bp_data()));
}

#define CHECK_PORT_READY( port) CHECK( ( port)->is_ready( cl_assert))
#define CHECK_PORT_NOT_READY( port) CHECK( !( port)->is_ready( cl_assert))
#define CHECK_PORT_READY_AND_TRUE( port) CHECK_PORT_READY( port); CHECK( ( port)->read( cl_assert) == true)
#define CHECK_PORT_NOT_READY_OR_FALSE( port) CHECK( (!(port)->is_ready( cl_assert) || ( port)->read( cl_assert) == false))

TEST_CASE( "correctly predicted branch", "[branch_module]")
{
    BranchTester t;
    InstrPtr instr = &taken_and_predicted_branch;

    SECTION( "taken_and_predicted_branch") { instr = &taken_and_predicted_branch; }
    SECTION( "ntaken_and_npredicted_branch") { instr = &ntaken_and_npredicted_branch; }

    t.env.wp_datapath->write( *instr, cl_arrange);

    t.branch.clock( cl_act);

    CHECK_PORT_READY( t.env.rp_datapath);
    CHECK_PORT_READY( t.env.rp_bp_update);
    CHECK_PORT_READY( t.env.rp_bypass);
    CHECK_PORT_NOT_READY( t.env.rp_flush_target);
    CHECK_PORT_NOT_READY_OR_FALSE( t.env.rp_flush);
    CHECK_PORT_NOT_READY_OR_FALSE( t.env.rp_bypassing_unit_flush_notify);
    CHECK( t.branch.get_mispredictions_num() == 0);
    CHECK( t.branch.get_jumps_num() == 0);
}

TEST_CASE( "mispredicted branch", "[branch_module]")
{
    BranchTester t;
    InstrPtr instr = nullptr;
    Addr expected_target = NO_VAL<Addr>;

    SECTION( "taken_and_npredicted_branch") { instr = &taken_and_npredicted_branch; expected_target = target; }
    SECTION( "ntaken_and_predicted_branch") { instr = &ntaken_and_predicted_branch; expected_target = new_pc; }

    t.env.wp_datapath->write( *instr, cl_arrange);

    t.branch.clock( cl_act);

    CHECK_PORT_READY( t.env.rp_datapath);
    CHECK_PORT_READY( t.env.rp_bp_update);
    CHECK_PORT_READY( t.env.rp_bypass);
    CHECK_PORT_READY( t.env.rp_flush);
    CHECK_PORT_READY( t.env.rp_flush_target);
    CHECK_PORT_READY_AND_TRUE( t.env.rp_bypassing_unit_flush_notify);
    CHECK( t.branch.get_mispredictions_num() == 1);
    CHECK( t.branch.get_jumps_num() == 0);

    auto actual_target = t.env.rp_flush_target->read( cl_assert);
    CHECK( actual_target.valid);
    CHECK( actual_target.address == expected_target);
    CHECK( actual_target.sequence_id == instr->get_sequence_id() + 1);
}

TEST_CASE( "bypass check", "[branch_module]")
{
    BranchTester t;
    auto instr = taken_and_predicted_branch;
    std::array<uint32, MAX_DST_NUM> dsts = {};

    std::iota(dsts.begin(), dsts.end(), 228);
    for ( int i = 0; i < MAX_DST_NUM; ++i)
        instr.set_v_dst(dsts.at(i), i);

    t.env.wp_datapath->write( instr, cl_arrange);

    t.branch.clock( cl_act);

    CHECK_PORT_READY( t.env.rp_bypass);
    auto bypass_data = t.env.rp_bypass->read( cl_assert);
    for ( int i = 0; i < MAX_DST_NUM; ++i) {
        INFO( "i = " << i);
        CHECK( bypass_data.at( i) == dsts.at( i));
    }
}

TEST_CASE( "trap received", "[branch_module]")
{
    BranchTester t;
    InstrPtr instr = nullptr;

    SECTION( "taken_and_predicted_branch") { instr = &taken_and_predicted_branch; }
    SECTION( "taken_and_npredicted_branch") { instr = &taken_and_npredicted_branch; }
    SECTION( "ntaken_and_predicted_branch") { instr = &ntaken_and_predicted_branch; }
    SECTION( "ntaken_and_npredicted_branch") { instr = &ntaken_and_npredicted_branch; }

    t.env.wp_datapath->write( *instr, cl_arrange);
    t.env.wp_trap->write(true, cl_arrange);

    t.branch.clock( cl_act);

    CHECK_PORT_NOT_READY( t.env.rp_datapath);
    CHECK_PORT_NOT_READY( t.env.rp_bp_update);
    CHECK_PORT_NOT_READY( t.env.rp_bypass);
}

TEST_CASE( "instruction dump", "[branch_module]")
{
    std::ostringstream oss;
    oss << BranchTestInstr( 0, 0, 0, false);
    CHECK( oss.str() == "BranchTestInstr");
}

} // namespace Test
<|endoftext|>


<commit_before>#include "Rendering/GeometryPass.h"
#include "Rendering/GBuffer.h"
#include "Rendering/ConstantBufferDX11.h"
#include "Rendering/PixelShaderDX11.h"
#include "Rendering/Texture2dDX11.h"
#include "Rendering/BlendState.h"

namespace Mile
{
   GeometryPass::GeometryPass(RendererDX11* renderer) :
      m_gBuffer(nullptr),
      m_transformBuffer(nullptr), m_materialBuffer(nullptr),
      RenderingPass(renderer)
   {
   }

   GeometryPass::~GeometryPass()
   {
      SafeDelete(m_transformBuffer);
      SafeDelete(m_materialBuffer);
   }

   bool GeometryPass::Init(const String& shaderPath)
   {
      if (!RenderingPass::Init(shaderPath))
      {
         return false;
      }

      m_transformBuffer = new ConstantBufferDX11(m_renderer);
      if (!m_transformBuffer->Init(sizeof(TransformConstantBuffer)))
      {
         return false;
      }

      m_materialBuffer = new ConstantBufferDX11(m_renderer);
      if (!m_materialBuffer->Init(sizeof(MaterialConstantBuffer)))
      {
         return false;
      }

      m_pixelShader->AddSampler(
         D3D11_FILTER_ANISOTROPIC,
         D3D11_TEXTURE_ADDRESS_BORDER,
         D3D11_COMPARISON_ALWAYS);

      return true;
   }

   bool GeometryPass::Bind(ID3D11DeviceContext& deviceContext)
   {
      bool bIsNotReadyToBind = !RenderingPass::Bind(deviceContext) ||
         m_transformBuffer == nullptr ||
         m_materialBuffer == nullptr ||
         m_gBuffer == nullptr;
      if (bIsNotReadyToBind)
      {
         return false;
      }

      if (!m_gBuffer->BindAsRenderTarget(deviceContext))
      {
         return false;
      }

      if (!m_transformBuffer->Bind(deviceContext, 0, EShaderType::VertexShader))
      {
         return false;
      }

      if (!m_materialBuffer->Bind(deviceContext, 0, EShaderType::PixelShader))
      {
         return false;
      }

      return true;
   }

   void GeometryPass::Unbind(ID3D11DeviceContext& deviceContext)
   {
      if (m_gBuffer != nullptr)
      {
         m_gBuffer->UnbindRenderTarget(deviceContext);
      }

      if (m_transformBuffer != nullptr)
      {
         m_transformBuffer->Unbind(deviceContext);
      }

      if (m_materialBuffer != nullptr)
      {
         m_materialBuffer->Unbind(deviceContext);
      }

      RenderingPass::Unbind(deviceContext);
   }

   void GeometryPass::UpdateTransformBuffer(ID3D11DeviceContext& deviceContext, TransformConstantBuffer buffer)
   {
      if (m_transformBuffer != nullptr)
      {
         auto mappedBuffer = reinterpret_cast<TransformConstantBuffer*>(m_transformBuffer->Map(deviceContext));
         (*mappedBuffer) = buffer;
         m_transformBuffer->UnMap(deviceContext);
      }
   }

   void GeometryPass::UpdateMaterialBuffer(ID3D11DeviceContext& deviceContext, MaterialConstantBuffer buffer)
   {
      if (m_materialBuffer != nullptr)
      {
         auto mappedBuffer = reinterpret_cast<MaterialConstantBuffer*>(m_materialBuffer->Map(deviceContext));
         (*mappedBuffer) = buffer;
         m_transformBuffer->UnMap(deviceContext);
      }
   }
}
<commit_msg>Fixed typo in geometry pass<commit_after>#include "Rendering/GeometryPass.h"
#include "Rendering/GBuffer.h"
#include "Rendering/ConstantBufferDX11.h"
#include "Rendering/PixelShaderDX11.h"
#include "Rendering/Texture2dDX11.h"
#include "Rendering/BlendState.h"

namespace Mile
{
   GeometryPass::GeometryPass(RendererDX11* renderer) :
      m_gBuffer(nullptr),
      m_transformBuffer(nullptr), m_materialBuffer(nullptr),
      RenderingPass(renderer)
   {
   }

   GeometryPass::~GeometryPass()
   {
      SafeDelete(m_transformBuffer);
      SafeDelete(m_materialBuffer);
   }

   bool GeometryPass::Init(const String& shaderPath)
   {
      if (!RenderingPass::Init(shaderPath))
      {
         return false;
      }

      m_transformBuffer = new ConstantBufferDX11(m_renderer);
      if (!m_transformBuffer->Init(sizeof(TransformConstantBuffer)))
      {
         return false;
      }

      m_materialBuffer = new ConstantBufferDX11(m_renderer);
      if (!m_materialBuffer->Init(sizeof(MaterialConstantBuffer)))
      {
         return false;
      }

      m_pixelShader->AddSampler(
         D3D11_FILTER_ANISOTROPIC,
         D3D11_TEXTURE_ADDRESS_WRAP,
         D3D11_COMPARISON_ALWAYS);

      return true;
   }

   bool GeometryPass::Bind(ID3D11DeviceContext& deviceContext)
   {
      bool bIsNotReadyToBind =
         !RenderingPass::Bind(deviceContext) ||
         m_transformBuffer == nullptr ||
         m_materialBuffer == nullptr ||
         m_gBuffer == nullptr;
      if (bIsNotReadyToBind)
      {
         return false;
      }

      if (!m_gBuffer->BindAsRenderTarget(deviceContext))
      {
         return false;
      }

      if (!m_transformBuffer->Bind(deviceContext, 0, EShaderType::VertexShader))
      {
         return false;
      }

      if (!m_materialBuffer->Bind(deviceContext, 0, EShaderType::PixelShader))
      {
         return false;
      }

      return true;
   }

   void GeometryPass::Unbind(ID3D11DeviceContext& deviceContext)
   {
      if (m_gBuffer != nullptr)
      {
         m_gBuffer->UnbindRenderTarget(deviceContext);
      }

      if (m_transformBuffer != nullptr)
      {
         m_transformBuffer->Unbind(deviceContext);
      }

      if (m_materialBuffer != nullptr)
      {
         m_materialBuffer->Unbind(deviceContext);
      }

      RenderingPass::Unbind(deviceContext);
   }

   void GeometryPass::UpdateTransformBuffer(ID3D11DeviceContext& deviceContext, TransformConstantBuffer buffer)
   {
      if (m_transformBuffer != nullptr)
      {
         auto mappedBuffer = reinterpret_cast<TransformConstantBuffer*>(m_transformBuffer->Map(deviceContext));
         (*mappedBuffer) = buffer;
         m_transformBuffer->UnMap(deviceContext);
      }
   }

   void GeometryPass::UpdateMaterialBuffer(ID3D11DeviceContext& deviceContext, MaterialConstantBuffer buffer)
   {
      if (m_materialBuffer != nullptr)
      {
         auto mappedBuffer = reinterpret_cast<MaterialConstantBuffer*>(m_materialBuffer->Map(deviceContext));
         (*mappedBuffer) = buffer;
         m_materialBuffer->UnMap(deviceContext);
      }
   }
}
<|endoftext|>


<commit_before>// @(#)root/rootx:$Name:  $:$Id: rootx.cxx,v 1.15 2004/12/06 13:38:53 brun Exp $
// Author: Fons Rademakers   19/02/98

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Rootx                                                                //
//                                                                      //
// Rootx is a small front-end program that starts the main ROOT module. //
// This program is called "root" in the $ROOTSYS/bin directory and the  //
// real ROOT executable is now called "root.exe" (formerly "root").     //
// Rootx puts up a splash screen giving some info about the current     //
// version of ROOT and, more importanly, it sets up the required        //
// LD_LIBRARY_PATH, SHLIB_PATH and LIBPATH environment variables        //
// (depending on the platform).                                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>

#include <netdb.h>
#include <sys/socket.h>

#if defined(__sgi) || defined(__sun)
#define HAVE_UTMPX_H
#define UTMP_NO_ADDR
#endif
#if (defined(__alpha) && !defined(__linux)) || defined(_AIX) || \
    defined(__FreeBSD__) || defined(__Lynx__) || defined(__APPLE__) || \
    defined(__OpenBSD__)
#define UTMP_NO_ADDR
#endif

#ifdef __sun
#   ifndef _REENTRANT
#      if __SUNPRO_CC > 0x420
#         define GLOBAL_ERRNO
#      endif
#   endif
#endif

#ifndef __VMS
# ifdef HAVE_UTMPX_H
# include <utmpx.h>
# define STRUCT_UTMP struct utmpx
# else
# if defined(__linux) && defined(__powerpc) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 90)
   extern "C" {
# endif
# include <utmp.h>
# define STRUCT_UTMP struct utmp
# endif
#endif

#if !defined(UTMP_FILE) && defined(_PATH_UTMP)      // 4.4BSD
#define UTMP_FILE _PATH_UTMP
#endif
#if defined(UTMPX_FILE)                             // Solaris, SysVr4
#undef  UTMP_FILE
#define UTMP_FILE UTMPX_FILE
#endif
#ifndef UTMP_FILE
#define UTMP_FILE "/etc/utmp"
#endif

#if defined(__CYGWIN__) && defined(__GNUC__)
#define ROOTBINARY "root_exe.exe"
#else
#define ROOTBINARY "root.exe"
#endif

extern void PopupLogo(bool);
extern void WaitLogo();
extern void PopdownLogo();
extern void CloseDisplay();

static STRUCT_UTMP *gUtmpContents;
static bool gNoLogo = false;

static int GetErrno()
{
#ifdef GLOBAL_ERRNO
   return ::errno;
#else
   return errno;
#endif
}

static void ResetErrno()
{
#ifdef GLOBAL_ERRNO
   ::errno = 0;
#else
   errno = 0;
#endif
}

static int ReadUtmp()
{
   FILE  *utmp;
   struct stat file_stats;
   size_t n_read, size;

   gUtmpContents = 0;

   utmp = fopen(UTMP_FILE, "r");
   if (!utmp)
      return 0;

   fstat(fileno(utmp), &file_stats);
   size = file_stats.st_size;
   if (size <= 0) {
      fclose(utmp);
      return 0;
   }

   gUtmpContents = (STRUCT_UTMP *) malloc(size);
   if (!gUtmpContents) return 0;

   n_read = fread(gUtmpContents, 1, size, utmp);
   if (ferror(utmp) || fclose(utmp) == EOF || n_read < size) {
      free(gUtmpContents);
      gUtmpContents = 0;
      return 0;
   }

   return size / sizeof(STRUCT_UTMP);
}

static STRUCT_UTMP *SearchEntry(int n, const char *tty)
{
   STRUCT_UTMP *ue = gUtmpContents;

   while (n--) {
      if (ue->ut_name[0] && !strncmp(tty, ue->ut_line, sizeof(ue->ut_line)))
         return ue;
      ue++;
   }
   return 0;
}

static void SetDisplay()
{
   // Set DISPLAY environment variable.

   if (!getenv("DISPLAY")) {
      char *tty = ttyname(0);  // device user is logged in on
      if (tty) {
         tty += 5;             // remove "/dev/"
         STRUCT_UTMP *utmp_entry = SearchEntry(ReadUtmp(), tty);
         if (utmp_entry) {
            static char display[64];
            if (utmp_entry->ut_host[0]) {
               if (strchr(utmp_entry->ut_host, ':')) {
                  sprintf(display, "DISPLAY=%s", utmp_entry->ut_host);
                  fprintf(stderr, "*** DISPLAY not set, setting it to %s\n",
                          utmp_entry->ut_host);
	       } else {
                  sprintf(display, "DISPLAY=%s:0.0", utmp_entry->ut_host);
                  fprintf(stderr, "*** DISPLAY not set, setting it to %s:0.0\n",
                          utmp_entry->ut_host);
               }
               putenv((char *)display);
#ifndef UTMP_NO_ADDR
            } else if (utmp_entry->ut_addr) {
               struct hostent *he;
               if ((he = gethostbyaddr((const char*)&utmp_entry->ut_addr,
                                       sizeof(utmp_entry->ut_addr), AF_INET))) {
                  sprintf(display, "DISPLAY=%s:0.0", he->h_name);
                  fprintf(stderr, "*** DISPLAY not set, setting it to %s:0.0\n",
                          he->h_name);
                  putenv((char *)display);
               }
#endif
            }
         }
         free(gUtmpContents);
      }
   }
}

static void SetLibraryPath()
{
#ifndef ROOTLIBDIR
   // Set library path for the different platforms.

   static char msg[4096];

#  if defined(__linux) || defined(__alpha) || defined(__sgi) || \
      defined(__sun) || defined(__FreeBSD__) || defined(__APPLE__) || \
      defined(__OpenBSD__)
   if (getenv("LD_LIBRARY_PATH"))
      sprintf(msg, "LD_LIBRARY_PATH=%s/lib:%s", getenv("ROOTSYS"),
                                                getenv("LD_LIBRARY_PATH"));
   else
#  if defined(__sun)
      sprintf(msg, "LD_LIBRARY_PATH=%s/lib:/usr/dt/lib", getenv("ROOTSYS"));
#  else
      sprintf(msg, "LD_LIBRARY_PATH=%s/lib", getenv("ROOTSYS"));
#  endif
#  elif defined(__hpux)  || defined(_HIUX_SOURCE)
   if (getenv("SHLIB_PATH"))
      sprintf(msg, "SHLIB_PATH=%s/lib:%s", getenv("ROOTSYS"),
                                           getenv("SHLIB_PATH"));
   else
      sprintf(msg, "SHLIB_PATH=%s/lib", getenv("ROOTSYS"));
#  elif defined(_AIX)
   if (getenv("LIBPATH"))
      sprintf(msg, "LIBPATH=%s/lib:%s", getenv("ROOTSYS"),
                                        getenv("LIBPATH"));
   else
      sprintf(msg, "LIBPATH=%s/lib:/lib:/usr/lib", getenv("ROOTSYS"));
#  endif
   putenv((char *)msg);
#endif
}

extern "C" {
   static void SigUsr1(int);
}

static void SigUsr1(int)
{
   // When we get SIGUSR1 from child (i.e. ROOT) then pop down logo.

   if (!gNoLogo)
      PopdownLogo();
}

static void WaitChild(int childpid)
{
   // Wait till child (i.e. ROOT) is finished.

   int status;

   do {
      while (waitpid(childpid, &status, WUNTRACED) < 0) {
         if (GetErrno() != EINTR)
            break;
         ResetErrno();
      }

      if (WIFEXITED(status))
         exit(WEXITSTATUS(status));

      if (WIFSIGNALED(status))
         exit(WTERMSIG(status));

      if (WIFSTOPPED(status)) {         // child got ctlr-Z
         raise(SIGTSTP);                // stop also parent
         kill(childpid, SIGCONT);       // if parent wakes up, wake up child
      }
   } while (WIFSTOPPED(status));

   exit(0);
}

static void PrintUsage(char *pname)
{
   // This is a copy of the text in TApplication::GetOptions().

   fprintf(stderr, "Usage: %s [-l] [-b] [-n] [-q] [dir] [file1.C ... fileN.C]\n", pname);
   fprintf(stderr, "Options:\n");
   fprintf(stderr, "  -b : run in batch mode without graphics\n");
   fprintf(stderr, "  -n : do not execute logon and logoff macros as specified in .rootrc\n");
   fprintf(stderr, "  -q : exit after processing command line macro files\n");
   fprintf(stderr, "  -l : do not show splash screen\n");
   fprintf(stderr, " dir : if dir is a valid directory cd to it before executing\n");
   fprintf(stderr, "\n");
   fprintf(stderr, "  -?      : print usage\n");
   fprintf(stderr, "  -h      : print usage\n");
   fprintf(stderr, "  --help  : print usage\n");
   fprintf(stderr, "  -config : print ./configure options\n");
   fprintf(stderr, "\n");
}

int main(int argc, char **argv)
{
   const int kMAXARGS = 256;
   char *argvv[kMAXARGS];
   char  arg0[256];

#ifndef ROOTPREFIX
   if (!getenv("ROOTSYS")) {
      fprintf(stderr, "%s: ROOTSYS not set. Set it before trying to run %s.\n",
              argv[0], argv[0]);
      return 1;
   }
#endif

   // In batch mode don't show splash screen, idem for no logo mode,
   // in about mode show always splash screen
   bool batch = false, about = false;
   int i;
   for (i = 1; i < argc; i++) {
      if (!strcmp(argv[i], "-?") || !strncmp(argv[i], "-h", 2) ||
          !strncmp(argv[i], "--help", 6)) {
         PrintUsage(argv[0]);
         return 1;
      }
      if (!strcmp(argv[i], "-b"))      batch   = true;
      if (!strcmp(argv[i], "-l"))      gNoLogo = true;
      if (!strcmp(argv[i], "-a"))      about   = true;
      if (!strcmp(argv[i], "-config")) gNoLogo = true;
   }
   if (batch)
      gNoLogo = true;
   if (about) {
      batch   = false;
      gNoLogo = false;
   }

   if (!batch) {
      SetDisplay();
      if (!getenv("DISPLAY")) {
         fprintf(stderr, "%s: can't figure out DISPLAY, set it manually\n", argv[0]);
         return 1;
      }
      if (about) {
         PopupLogo(true);
         WaitLogo();
         return 0;
      } else if (!gNoLogo)
         PopupLogo(false);
   }

   // Ignore SIGINT and SIGQUIT. Install handler for SIGUSR1.

   struct sigaction ignore, handle, saveintr, savequit, saveusr1;

#if defined(__sun) && !defined(__i386) && !defined(__SVR4)
   ignore.sa_handler = (void (*)())SIG_IGN;
#elif defined(__sun) && defined(__SVR4)
   ignore.sa_handler = (void (*)(int))SIG_IGN;
#else
   ignore.sa_handler = SIG_IGN;
#endif
   sigemptyset(&ignore.sa_mask);
   ignore.sa_flags = 0;
   handle = ignore;
#if defined(__sun) && !defined(__i386) && !defined(__SVR4)
   handle.sa_handler = (void (*)())SigUsr1;
#elif defined(__sun) && defined(__SVR4)
   handle.sa_handler = SigUsr1;
#elif (defined(__sgi) && !defined(__KCC)) || defined(__Lynx__)
#   if defined(IRIX64) || (__GNUG__>=3)
   handle.sa_handler = SigUsr1;
#   else
   handle.sa_handler = (void (*)(...))SigUsr1;
#   endif
#else
   handle.sa_handler = SigUsr1;
#endif
   sigaction(SIGINT,  &ignore, &saveintr);
   sigaction(SIGQUIT, &ignore, &savequit);
   sigaction(SIGUSR1, &handle, &saveusr1);

   // Create child...

   int childpid;
   if ((childpid = fork()) < 0) {
      fprintf(stderr, "%s: error forking child\n", argv[0]);
      return 1;
   } else if (childpid > 0) {
      if (!gNoLogo)
         WaitLogo();
      WaitChild(childpid);
   }

   // Continue with child...

   // Restore original signal actions
   sigaction(SIGINT,  &saveintr, 0);
   sigaction(SIGQUIT, &savequit, 0);
   sigaction(SIGUSR1, &saveusr1, 0);

   // Close X display connection
   CloseDisplay();

   // Child is going to overlay itself with the actual ROOT module...

   // Build argv vector
#ifdef ROOTBINDIR
   sprintf(arg0, "%s/%s", ROOTBINDIR, ROOTBINARY);
#else
   sprintf(arg0, "%s/bin/%s", getenv("ROOTSYS"), ROOTBINARY);
#endif
   argvv[0] = arg0;
   argvv[1] = (char *) "-splash";

   int iargc = argc;
   if (iargc > kMAXARGS-2) iargc = kMAXARGS-2;
   for (i = 1; i < iargc; i++)
      argvv[1+i] = argv[i];
   argvv[1+i] = 0;

   // Make sure library path is set
   SetLibraryPath();

   // Execute actual ROOT module
   execv(arg0, argvv);

   // Exec failed
#ifndef ROOTBINDIR
   fprintf(stderr,
	   "%s: can't start ROOT -- check that %s/bin/%s exists!\n",
           argv[0], getenv("ROOTSYS"), ROOTBINARY);
#else
   fprintf(stderr, "%s: can't start ROOT -- check that %s/%s exists!\n",
           argv[0], ROOTBINDIR, ROOTBINARY);
#endif

   return 1;
}

<commit_msg>make string containing LD_LIBRARY_PATH dynamic avoiding overflow with very long LD_LIBRARY_PATH's.<commit_after>// @(#)root/rootx:$Name:  $:$Id: rootx.cxx,v 1.16 2005/02/28 17:28:12 rdm Exp $
// Author: Fons Rademakers   19/02/98

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Rootx                                                                //
//                                                                      //
// Rootx is a small front-end program that starts the main ROOT module. //
// This program is called "root" in the $ROOTSYS/bin directory and the  //
// real ROOT executable is now called "root.exe" (formerly "root").     //
// Rootx puts up a splash screen giving some info about the current     //
// version of ROOT and, more importanly, it sets up the required        //
// LD_LIBRARY_PATH, SHLIB_PATH and LIBPATH environment variables        //
// (depending on the platform).                                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>

#include <netdb.h>
#include <sys/socket.h>

#if defined(__sgi) || defined(__sun)
#define HAVE_UTMPX_H
#define UTMP_NO_ADDR
#endif
#if (defined(__alpha) && !defined(__linux)) || defined(_AIX) || \
    defined(__FreeBSD__) || defined(__Lynx__) || defined(__APPLE__) || \
    defined(__OpenBSD__)
#define UTMP_NO_ADDR
#endif

#ifdef __sun
#   ifndef _REENTRANT
#      if __SUNPRO_CC > 0x420
#         define GLOBAL_ERRNO
#      endif
#   endif
#endif

#ifndef __VMS
# ifdef HAVE_UTMPX_H
# include <utmpx.h>
# define STRUCT_UTMP struct utmpx
# else
# if defined(__linux) && defined(__powerpc) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 90)
   extern "C" {
# endif
# include <utmp.h>
# define STRUCT_UTMP struct utmp
# endif
#endif

#if !defined(UTMP_FILE) && defined(_PATH_UTMP)      // 4.4BSD
#define UTMP_FILE _PATH_UTMP
#endif
#if defined(UTMPX_FILE)                             // Solaris, SysVr4
#undef  UTMP_FILE
#define UTMP_FILE UTMPX_FILE
#endif
#ifndef UTMP_FILE
#define UTMP_FILE "/etc/utmp"
#endif

#if defined(__CYGWIN__) && defined(__GNUC__)
#define ROOTBINARY "root_exe.exe"
#else
#define ROOTBINARY "root.exe"
#endif

extern void PopupLogo(bool);
extern void WaitLogo();
extern void PopdownLogo();
extern void CloseDisplay();

static STRUCT_UTMP *gUtmpContents;
static bool gNoLogo = false;

static int GetErrno()
{
#ifdef GLOBAL_ERRNO
   return ::errno;
#else
   return errno;
#endif
}

static void ResetErrno()
{
#ifdef GLOBAL_ERRNO
   ::errno = 0;
#else
   errno = 0;
#endif
}

static int ReadUtmp()
{
   FILE  *utmp;
   struct stat file_stats;
   size_t n_read, size;

   gUtmpContents = 0;

   utmp = fopen(UTMP_FILE, "r");
   if (!utmp)
      return 0;

   fstat(fileno(utmp), &file_stats);
   size = file_stats.st_size;
   if (size <= 0) {
      fclose(utmp);
      return 0;
   }

   gUtmpContents = (STRUCT_UTMP *) malloc(size);
   if (!gUtmpContents) return 0;

   n_read = fread(gUtmpContents, 1, size, utmp);
   if (ferror(utmp) || fclose(utmp) == EOF || n_read < size) {
      free(gUtmpContents);
      gUtmpContents = 0;
      return 0;
   }

   return size / sizeof(STRUCT_UTMP);
}

static STRUCT_UTMP *SearchEntry(int n, const char *tty)
{
   STRUCT_UTMP *ue = gUtmpContents;

   while (n--) {
      if (ue->ut_name[0] && !strncmp(tty, ue->ut_line, sizeof(ue->ut_line)))
         return ue;
      ue++;
   }
   return 0;
}

static void SetDisplay()
{
   // Set DISPLAY environment variable.

   if (!getenv("DISPLAY")) {
      char *tty = ttyname(0);  // device user is logged in on
      if (tty) {
         tty += 5;             // remove "/dev/"
         STRUCT_UTMP *utmp_entry = SearchEntry(ReadUtmp(), tty);
         if (utmp_entry) {
            static char display[64];
            if (utmp_entry->ut_host[0]) {
               if (strchr(utmp_entry->ut_host, ':')) {
                  sprintf(display, "DISPLAY=%s", utmp_entry->ut_host);
                  fprintf(stderr, "*** DISPLAY not set, setting it to %s\n",
                          utmp_entry->ut_host);
	       } else {
                  sprintf(display, "DISPLAY=%s:0.0", utmp_entry->ut_host);
                  fprintf(stderr, "*** DISPLAY not set, setting it to %s:0.0\n",
                          utmp_entry->ut_host);
               }
               putenv((char *)display);
#ifndef UTMP_NO_ADDR
            } else if (utmp_entry->ut_addr) {
               struct hostent *he;
               if ((he = gethostbyaddr((const char*)&utmp_entry->ut_addr,
                                       sizeof(utmp_entry->ut_addr), AF_INET))) {
                  sprintf(display, "DISPLAY=%s:0.0", he->h_name);
                  fprintf(stderr, "*** DISPLAY not set, setting it to %s:0.0\n",
                          he->h_name);
                  putenv((char *)display);
               }
#endif
            }
         }
         free(gUtmpContents);
      }
   }
}

static void SetLibraryPath()
{
#ifndef ROOTLIBDIR
   // Set library path for the different platforms.

   char *msg;

#  if defined(__linux) || defined(__alpha) || defined(__sgi) || \
      defined(__sun) || defined(__FreeBSD__) || defined(__APPLE__) || \
      defined(__OpenBSD__)
   if (getenv("LD_LIBRARY_PATH")) {
      msg = new char [strlen(getenv("ROOTSYS"))+strlen(getenv("LD_LIBRARY_PATH"))+100];
      sprintf(msg, "LD_LIBRARY_PATH=%s/lib:%s", getenv("ROOTSYS"),
                                                getenv("LD_LIBRARY_PATH"));
   } else {
      msg = new char [strlen(getenv("ROOTSYS"))+100];
#  if defined(__sun)
      sprintf(msg, "LD_LIBRARY_PATH=%s/lib:/usr/dt/lib", getenv("ROOTSYS"));
#  else
      sprintf(msg, "LD_LIBRARY_PATH=%s/lib", getenv("ROOTSYS"));
#  endif
   }
#  elif defined(__hpux)  || defined(_HIUX_SOURCE)
   if (getenv("SHLIB_PATH")) {
      msg = new char [strlen(getenv("ROOTSYS"))+strlen(getenv("SHLIB_PATH"))+100];
      sprintf(msg, "SHLIB_PATH=%s/lib:%s", getenv("ROOTSYS"),
                                           getenv("SHLIB_PATH"));
   } else {
      msg = new char [strlen(getenv("ROOTSYS"))+100];
      sprintf(msg, "SHLIB_PATH=%s/lib", getenv("ROOTSYS"));
   }
#  elif defined(_AIX)
   if (getenv("LIBPATH")) {
      msg = new char [strlen(getenv("ROOTSYS"))+strlen(getenv("LIBPATH"))+100];
      sprintf(msg, "LIBPATH=%s/lib:%s", getenv("ROOTSYS"),
                                        getenv("LIBPATH"));
   } else {
      msg = new char [strlen(getenv("ROOTSYS"))+100];
      sprintf(msg, "LIBPATH=%s/lib:/lib:/usr/lib", getenv("ROOTSYS"));
   }
#  endif
   putenv(msg);
#endif
}

extern "C" {
   static void SigUsr1(int);
}

static void SigUsr1(int)
{
   // When we get SIGUSR1 from child (i.e. ROOT) then pop down logo.

   if (!gNoLogo)
      PopdownLogo();
}

static void WaitChild(int childpid)
{
   // Wait till child (i.e. ROOT) is finished.

   int status;

   do {
      while (waitpid(childpid, &status, WUNTRACED) < 0) {
         if (GetErrno() != EINTR)
            break;
         ResetErrno();
      }

      if (WIFEXITED(status))
         exit(WEXITSTATUS(status));

      if (WIFSIGNALED(status))
         exit(WTERMSIG(status));

      if (WIFSTOPPED(status)) {         // child got ctlr-Z
         raise(SIGTSTP);                // stop also parent
         kill(childpid, SIGCONT);       // if parent wakes up, wake up child
      }
   } while (WIFSTOPPED(status));

   exit(0);
}

static void PrintUsage(char *pname)
{
   // This is a copy of the text in TApplication::GetOptions().

   fprintf(stderr, "Usage: %s [-l] [-b] [-n] [-q] [dir] [file1.C ... fileN.C]\n", pname);
   fprintf(stderr, "Options:\n");
   fprintf(stderr, "  -b : run in batch mode without graphics\n");
   fprintf(stderr, "  -n : do not execute logon and logoff macros as specified in .rootrc\n");
   fprintf(stderr, "  -q : exit after processing command line macro files\n");
   fprintf(stderr, "  -l : do not show splash screen\n");
   fprintf(stderr, " dir : if dir is a valid directory cd to it before executing\n");
   fprintf(stderr, "\n");
   fprintf(stderr, "  -?      : print usage\n");
   fprintf(stderr, "  -h      : print usage\n");
   fprintf(stderr, "  --help  : print usage\n");
   fprintf(stderr, "  -config : print ./configure options\n");
   fprintf(stderr, "\n");
}

int main(int argc, char **argv)
{
   const int kMAXARGS = 256;
   char *argvv[kMAXARGS];
   char  arg0[2048];

#ifndef ROOTPREFIX
   if (!getenv("ROOTSYS")) {
      fprintf(stderr, "%s: ROOTSYS not set. Set it before trying to run %s.\n",
              argv[0], argv[0]);
      return 1;
   }
#endif

   // In batch mode don't show splash screen, idem for no logo mode,
   // in about mode show always splash screen
   bool batch = false, about = false;
   int i;
   for (i = 1; i < argc; i++) {
      if (!strcmp(argv[i], "-?") || !strncmp(argv[i], "-h", 2) ||
          !strncmp(argv[i], "--help", 6)) {
         PrintUsage(argv[0]);
         return 1;
      }
      if (!strcmp(argv[i], "-b"))      batch   = true;
      if (!strcmp(argv[i], "-l"))      gNoLogo = true;
      if (!strcmp(argv[i], "-a"))      about   = true;
      if (!strcmp(argv[i], "-config")) gNoLogo = true;
   }
   if (batch)
      gNoLogo = true;
   if (about) {
      batch   = false;
      gNoLogo = false;
   }

   if (!batch) {
      SetDisplay();
      if (!getenv("DISPLAY")) {
         fprintf(stderr, "%s: can't figure out DISPLAY, set it manually\n", argv[0]);
         return 1;
      }
      if (about) {
         PopupLogo(true);
         WaitLogo();
         return 0;
      } else if (!gNoLogo)
         PopupLogo(false);
   }

   // Ignore SIGINT and SIGQUIT. Install handler for SIGUSR1.

   struct sigaction ignore, handle, saveintr, savequit, saveusr1;

#if defined(__sun) && !defined(__i386) && !defined(__SVR4)
   ignore.sa_handler = (void (*)())SIG_IGN;
#elif defined(__sun) && defined(__SVR4)
   ignore.sa_handler = (void (*)(int))SIG_IGN;
#else
   ignore.sa_handler = SIG_IGN;
#endif
   sigemptyset(&ignore.sa_mask);
   ignore.sa_flags = 0;
   handle = ignore;
#if defined(__sun) && !defined(__i386) && !defined(__SVR4)
   handle.sa_handler = (void (*)())SigUsr1;
#elif defined(__sun) && defined(__SVR4)
   handle.sa_handler = SigUsr1;
#elif (defined(__sgi) && !defined(__KCC)) || defined(__Lynx__)
#   if defined(IRIX64) || (__GNUG__>=3)
   handle.sa_handler = SigUsr1;
#   else
   handle.sa_handler = (void (*)(...))SigUsr1;
#   endif
#else
   handle.sa_handler = SigUsr1;
#endif
   sigaction(SIGINT,  &ignore, &saveintr);
   sigaction(SIGQUIT, &ignore, &savequit);
   sigaction(SIGUSR1, &handle, &saveusr1);

   // Create child...

   int childpid;
   if ((childpid = fork()) < 0) {
      fprintf(stderr, "%s: error forking child\n", argv[0]);
      return 1;
   } else if (childpid > 0) {
      if (!gNoLogo)
         WaitLogo();
      WaitChild(childpid);
   }

   // Continue with child...

   // Restore original signal actions
   sigaction(SIGINT,  &saveintr, 0);
   sigaction(SIGQUIT, &savequit, 0);
   sigaction(SIGUSR1, &saveusr1, 0);

   // Close X display connection
   CloseDisplay();

   // Child is going to overlay itself with the actual ROOT module...

   // Build argv vector
#ifdef ROOTBINDIR
   sprintf(arg0, "%s/%s", ROOTBINDIR, ROOTBINARY);
#else
   sprintf(arg0, "%s/bin/%s", getenv("ROOTSYS"), ROOTBINARY);
#endif
   argvv[0] = arg0;
   argvv[1] = (char *) "-splash";

   int iargc = argc;
   if (iargc > kMAXARGS-2) iargc = kMAXARGS-2;
   for (i = 1; i < iargc; i++)
      argvv[1+i] = argv[i];
   argvv[1+i] = 0;

   // Make sure library path is set
   SetLibraryPath();

   // Execute actual ROOT module
   execv(arg0, argvv);

   // Exec failed
#ifndef ROOTBINDIR
   fprintf(stderr,
	   "%s: can't start ROOT -- check that %s/bin/%s exists!\n",
           argv[0], getenv("ROOTSYS"), ROOTBINARY);
#else
   fprintf(stderr, "%s: can't start ROOT -- check that %s/%s exists!\n",
           argv[0], ROOTBINDIR, ROOTBINARY);
#endif

   return 1;
}

<|endoftext|>