<commit_before>// Copyright (c) 2016 ASMlover. 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 ofconditions 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 materialsprovided 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.
#include <assert.h>
#include <errno.h>
#include <poll.h>
#include <sys/epoll.h>
#include "../../basic/TLogging.h"
#include "../TChannel.h"
#include "TAsyncPollerLinux.h"

namespace tyr { namespace net {

static_assert(EPOLLIN == POLLIN, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLPRI == POLLPRI, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLOUT == POLLOUT, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLRDHUP == POLLRDHUP, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLERR == POLLERR, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLHUP == POLLHUP, "`epoll` uses same flag values as `poll`");

AsyncPoller::AsyncPoller(EventLoop* loop)
  : Poller(loop)
  , epollfd_(epoll_create1(EPOLL_CLOEXEC))
  , epoll_events_(kInitNumEvents) {
  if (epollfd_ < 0)
    TYRLOG_SYSFATAL << "AsyncPoller::AsyncPoller";
}

AsyncPoller::~AsyncPoller(void) {
  close(epollfd_);
}

basic::Timestamp AsyncPoller::poll(int timeout, std::vector<Channel*>* active_channels) {
  TYRLOG_TRACE << "AsyncPoller::poll - fd total count " << channels_.size();

  int events_count = static_cast<int>(epoll_events_.size());
  int num_events = epoll_wait(epollfd_, &*epoll_events_.begin(), events_count, timeout);
  int saved_errno = errno;
  if (num_events > 0) {
    TYRLOG_TRACE << "AsyncPoller::poll - " << num_events << " events happened";
    fill_active_channels(num_events, active_channels);
    if (num_events == events_count)
      epoll_events_.resize(events_count * 2);
  }
  else if (num_events == 0) {
    TYRLOG_TRACE << "AsyncPoller::poll - nothing happened";
  }
  else {
    if (saved_errno != EINTR) {
      errno = saved_errno;
      TYRLOG_SYSERR << "AsyncPoller::poll - errno=" << saved_errno;
    }
  }
  return basic::Timestamp::now();
}

void AsyncPoller::update_channel(Channel* channel) {
  assert_in_loopthread();

  int fd = channel->get_fd();
  const int index = channel->get_index();
  TYRLOG_TRACE << "AsyncPoller::update_channel - fd=" << fd
    << " index=" << index << " events=" << channel->get_events();

  if (index == POLLER_EVENT_NEW || index == POLLER_EVENT_DEL) {
    if (index == POLLER_EVENT_NEW) {
      assert(channels_.find(fd) == channels_.end());
      channels_[fd] = channel;
    }
    else {
      assert(channels_.find(fd) != channels_.end());
      assert(channels_[fd] == channel);
    }

    channel->set_index(POLLER_EVENT_ADD);
    update(EPOLL_CTL_ADD, channel);
  }
  else {
    assert(channels_.find(fd) != channels_.end());
    assert(channels_[fd] == channel);
    assert(index == POLLER_EVENT_ADD);
    if (channel->is_none_event()) {
      update(EPOLL_CTL_DEL, channel);
      channel->set_index(POLLER_EVENT_DEL);
    }
    else {
      update(EPOLL_CTL_MOD, channel);
    }
  }
}

void AsyncPoller::remove_channel(Channel* channel) {
  assert_in_loopthread();

  int fd = channel->get_fd();
  const int index = channel->get_index();
  TYRLOG_TRACE << "AsyncPoller::remove_channel - fd=" << fd;

  assert(channels_.find(fd) != channels_.end());
  assert(channels_[fd] == channel);
  assert(channel->is_none_event());
  assert(index == POLLER_EVENT_ADD || index == POLLER_EVENT_DEL);
  size_t n = channels_.erase(fd);
  assert(n == 1); UNUSED(n);

  if (index == POLLER_EVENT_ADD)
    update(EPOLL_CTL_DEL,  channel);
  channel->set_index(POLLER_EVENT_NEW);
}

const char* AsyncPoller::operation_to_string(int op) {
  switch (op) {
  case EPOLL_CTL_ADD:
    return "ADD";
  case EPOLL_CTL_DEL:
    return "DEL";
  case EPOLL_CTL_MOD:
    return "MOD";
  default:
    return "Unknown Operation";
  }
}

void AsyncPoller::update(int operation, Channel* channel) {
  int fd = channel->get_fd();
  TYRLOG_TRACE << "AsyncPoller::update - epoll_ctl op=" << operation_to_string(operation)
    << " fd=" << fd << " event={" << channel->events_to_string() << "}";

  struct epoll_event event = {0};
  event.events = channel->get_events();
  event.data.ptr = channel;
  if (epoll_ctl(epollfd_, operation, fd, &event) < 0) {
    if (operation == EPOLL_CTL_DEL)
      TYRLOG_SYSERR << "AsyncPoller::update - epoll_ctl op=" << operation_to_string(operation) << " fd=" << fd;
    else
      TYRLOG_SYSFATAL << "AsyncPoller::update - epoll_ctl op=" << operation_to_string(operation) << " fd=" << fd;
  }
}

void AsyncPoller::fill_active_channels(int nevents, std::vector<Channel*>* active_channels) const {
  assert(basic::implicit_cast<size_t>(nevents) <= epoll_events_.size());
  for (auto i = 0; i < num_events; ++i) {
    Channel* channel = static_cast<Channel*>(epoll_events_[i].data.ptr);
    channel->set_revents(epoll_events_[i].events);
    active_channels->push_back(channel);
  }
}

}}
<commit_msg>:penguin: fix(include): fixed lose including for linux<commit_after>// Copyright (c) 2016 ASMlover. 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 ofconditions 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 materialsprovided 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.
#include <assert.h>
#include <errno.h>
#include <poll.h>
#include <sys/epoll.h>
#include "../../basic/TTypes.h"
#include "../../basic/TLogging.h"
#include "../TChannel.h"
#include "TAsyncPollerLinux.h"

namespace tyr { namespace net {

static_assert(EPOLLIN == POLLIN, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLPRI == POLLPRI, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLOUT == POLLOUT, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLRDHUP == POLLRDHUP, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLERR == POLLERR, "`epoll` uses same flag values as `poll`");
static_assert(EPOLLHUP == POLLHUP, "`epoll` uses same flag values as `poll`");

AsyncPoller::AsyncPoller(EventLoop* loop)
  : Poller(loop)
  , epollfd_(epoll_create1(EPOLL_CLOEXEC))
  , epoll_events_(kInitNumEvents) {
  if (epollfd_ < 0)
    TYRLOG_SYSFATAL << "AsyncPoller::AsyncPoller";
}

AsyncPoller::~AsyncPoller(void) {
  close(epollfd_);
}

basic::Timestamp AsyncPoller::poll(int timeout, std::vector<Channel*>* active_channels) {
  TYRLOG_TRACE << "AsyncPoller::poll - fd total count " << channels_.size();

  int events_count = static_cast<int>(epoll_events_.size());
  int num_events = epoll_wait(epollfd_, &*epoll_events_.begin(), events_count, timeout);
  int saved_errno = errno;
  if (num_events > 0) {
    TYRLOG_TRACE << "AsyncPoller::poll - " << num_events << " events happened";
    fill_active_channels(num_events, active_channels);
    if (num_events == events_count)
      epoll_events_.resize(events_count * 2);
  }
  else if (num_events == 0) {
    TYRLOG_TRACE << "AsyncPoller::poll - nothing happened";
  }
  else {
    if (saved_errno != EINTR) {
      errno = saved_errno;
      TYRLOG_SYSERR << "AsyncPoller::poll - errno=" << saved_errno;
    }
  }
  return basic::Timestamp::now();
}

void AsyncPoller::update_channel(Channel* channel) {
  assert_in_loopthread();

  int fd = channel->get_fd();
  const int index = channel->get_index();
  TYRLOG_TRACE << "AsyncPoller::update_channel - fd=" << fd
    << " index=" << index << " events=" << channel->get_events();

  if (index == POLLER_EVENT_NEW || index == POLLER_EVENT_DEL) {
    if (index == POLLER_EVENT_NEW) {
      assert(channels_.find(fd) == channels_.end());
      channels_[fd] = channel;
    }
    else {
      assert(channels_.find(fd) != channels_.end());
      assert(channels_[fd] == channel);
    }

    channel->set_index(POLLER_EVENT_ADD);
    update(EPOLL_CTL_ADD, channel);
  }
  else {
    assert(channels_.find(fd) != channels_.end());
    assert(channels_[fd] == channel);
    assert(index == POLLER_EVENT_ADD);
    if (channel->is_none_event()) {
      update(EPOLL_CTL_DEL, channel);
      channel->set_index(POLLER_EVENT_DEL);
    }
    else {
      update(EPOLL_CTL_MOD, channel);
    }
  }
}

void AsyncPoller::remove_channel(Channel* channel) {
  assert_in_loopthread();

  int fd = channel->get_fd();
  const int index = channel->get_index();
  TYRLOG_TRACE << "AsyncPoller::remove_channel - fd=" << fd;

  assert(channels_.find(fd) != channels_.end());
  assert(channels_[fd] == channel);
  assert(channel->is_none_event());
  assert(index == POLLER_EVENT_ADD || index == POLLER_EVENT_DEL);
  size_t n = channels_.erase(fd);
  assert(n == 1); UNUSED(n);

  if (index == POLLER_EVENT_ADD)
    update(EPOLL_CTL_DEL,  channel);
  channel->set_index(POLLER_EVENT_NEW);
}

const char* AsyncPoller::operation_to_string(int op) {
  switch (op) {
  case EPOLL_CTL_ADD:
    return "ADD";
  case EPOLL_CTL_DEL:
    return "DEL";
  case EPOLL_CTL_MOD:
    return "MOD";
  default:
    return "Unknown Operation";
  }
}

void AsyncPoller::update(int operation, Channel* channel) {
  int fd = channel->get_fd();
  TYRLOG_TRACE << "AsyncPoller::update - epoll_ctl op=" << operation_to_string(operation)
    << " fd=" << fd << " event={" << channel->events_to_string() << "}";

  struct epoll_event event = {0};
  event.events = channel->get_events();
  event.data.ptr = channel;
  if (epoll_ctl(epollfd_, operation, fd, &event) < 0) {
    if (operation == EPOLL_CTL_DEL)
      TYRLOG_SYSERR << "AsyncPoller::update - epoll_ctl op=" << operation_to_string(operation) << " fd=" << fd;
    else
      TYRLOG_SYSFATAL << "AsyncPoller::update - epoll_ctl op=" << operation_to_string(operation) << " fd=" << fd;
  }
}

void AsyncPoller::fill_active_channels(int nevents, std::vector<Channel*>* active_channels) const {
  assert(basic::implicit_cast<size_t>(nevents) <= epoll_events_.size());
  for (auto i = 0; i < num_events; ++i) {
    Channel* channel = static_cast<Channel*>(epoll_events_[i].data.ptr);
    channel->set_revents(epoll_events_[i].events);
    active_channels->push_back(channel);
  }
}

}}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: activedatasink.hxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: kso $ $Date: 2001-02-05 15:49:26 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _UCBHELPER_ACTIVEDATASINK_HXX
#define _UCBHELPER_ACTIVEDATASINK_HXX

#ifndef _COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_
#include <com/sun/star/lang/XTypeProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
#include <com/sun/star/io/XActiveDataSink.hpp>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#ifndef _UCBHELPER_MACROS_HXX
#include <ucbhelper/macros.hxx>
#endif

namespace ucb
{

//=========================================================================

/**
  * This class implements the interface com::sun::star::io::XActiveDataSink.
  * Instances of this class can be passed with the parameters of an
  * "open" command.
  */

class ActiveDataSink : public cppu::OWeakObject,
                       public com::sun::star::lang::XTypeProvider,
                       public com::sun::star::io::XActiveDataSink
{
    com::sun::star::uno::Reference<
        com::sun::star::io::XInputStream > m_xStream;

public:
     // XInterface
    XINTERFACE_DECL()

    // XTypeProvider
    XTYPEPROVIDER_DECL()

    // XActiveDataSink methods.
    virtual void SAL_CALL
    setInputStream( const com::sun::star::uno::Reference<
                            com::sun::star::io::XInputStream >& aStream )
        throw( com::sun::star::uno::RuntimeException );
    virtual com::sun::star::uno::Reference<
        com::sun::star::io::XInputStream > SAL_CALL
    getInputStream()
        throw( com::sun::star::uno::RuntimeException );
};

} /* namespace ucb */

#endif /* !_UCBHELPER_ACTIVEDATASINK_HXX */
<commit_msg>INTEGRATION: CWS ooo19126 (1.1.178); FILE MERGED 2005/09/05 13:13:41 rt 1.1.178.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: activedatasink.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 16:23:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

#ifndef _UCBHELPER_ACTIVEDATASINK_HXX
#define _UCBHELPER_ACTIVEDATASINK_HXX

#ifndef _COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_
#include <com/sun/star/lang/XTypeProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
#include <com/sun/star/io/XActiveDataSink.hpp>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#ifndef _UCBHELPER_MACROS_HXX
#include <ucbhelper/macros.hxx>
#endif

namespace ucb
{

//=========================================================================

/**
  * This class implements the interface com::sun::star::io::XActiveDataSink.
  * Instances of this class can be passed with the parameters of an
  * "open" command.
  */

class ActiveDataSink : public cppu::OWeakObject,
                       public com::sun::star::lang::XTypeProvider,
                       public com::sun::star::io::XActiveDataSink
{
    com::sun::star::uno::Reference<
        com::sun::star::io::XInputStream > m_xStream;

public:
     // XInterface
    XINTERFACE_DECL()

    // XTypeProvider
    XTYPEPROVIDER_DECL()

    // XActiveDataSink methods.
    virtual void SAL_CALL
    setInputStream( const com::sun::star::uno::Reference<
                            com::sun::star::io::XInputStream >& aStream )
        throw( com::sun::star::uno::RuntimeException );
    virtual com::sun::star::uno::Reference<
        com::sun::star::io::XInputStream > SAL_CALL
    getInputStream()
        throw( com::sun::star::uno::RuntimeException );
};

} /* namespace ucb */

#endif /* !_UCBHELPER_ACTIVEDATASINK_HXX */
<|endoftext|>


<commit_before>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1999 Stefan Seefeld <stefan@berlin-consortium.org>
 * Copyright (C) 1999 Graydon Hoare <graydon@pobox.com>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include <Warsaw/config.hh>
#include <Warsaw/resolve.hh>
#include <Warsaw/LayoutKit.hh>
#include <Warsaw/WidgetKit.hh>
#include <Warsaw/DrawingKit.hh>
#include <Berlin/ScreenImpl.hh>
#include <Berlin/ScreenManager.hh>
#include <Berlin/ServerImpl.hh>
#include <Berlin/Logger.hh>
#include <Berlin/DesktopImpl.hh>
#include <Prague/Sys/Tracer.hh>
#include <Prague/Sys/Signal.hh>
#include <Prague/Sys/Profiler.hh>
#include <Prague/Sys/Timer.hh>
#include <Prague/Sys/GetOpt.hh>

#ifdef JPROF
// probably need to change include path
#include "jprof.h"
#endif

using namespace Prague;

struct Dump : Signal::Notifier
{
  void notify(int signo)
    {
      switch (signo)
	{
	case Signal::hangup: Profiler::dump(cerr); break;
	case Signal::abort:
	case Signal::segv:
	  cerr << "Something went wrong. Here's a debugging log. \n"
	       << "Please mail this output to bugs@berlin-consortium.org :\n\n";
	  Logger::dump(cerr);
	  cerr << "\n\nDetailed Trace:\n";
	  Tracer::dump(cerr);
	  exit(-1);
	}
    }
};

int main(int argc, char **argv)
{
  Dump *dump = new Dump;
  Signal::set(Signal::abort, dump);
  Signal::set(Signal::segv, dump);
  Signal::set(Signal::hangup, dump);

  CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB2");
  CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB2_BOA");

  GetOpt getopt(argv[0], "a berlin display server");
  getopt.add('v', "version", GetOpt::novalue, "version number");
  getopt.add('h', "help", GetOpt::novalue, "help message");
  getopt.add('l', "logging", GetOpt::novalue, "switch logging on");
  getopt.add('p', "profiling", GetOpt::novalue, "switch profiling on");
  getopt.add('d', "drawing", GetOpt::mandatory, "the DrawingKit to choose");
  getopt.parse(argc - 1, argv + 1);
  string value;
  getopt.get("version", &value);
  if (value == "true") { cout << "version is " << "0.2" << endl; exit(0);}
  value == "";
  getopt.get("help", &value);
  if (value == "true") { getopt.usage(); exit(0);}
  value == "";
  getopt.get("logging", &value);
  if (value == "true")
    {
      Logger::set(Logger::corba);
      Logger::set(Logger::focus);
      Logger::set(Logger::image);
      Logger::set(Logger::loader);
      Logger::set(Logger::subject);
      Logger::set(Logger::layout);
      Logger::set(Logger::picking);
      Logger::set(Logger::drawing);
      Logger::set(Logger::traversal);
      Logger::set(Logger::widget);
      Tracer::logging(true);
    }

#ifdef JPROF
  value == "";
  getopt.get("profiling", &value);
  if (value == "true") setupProfilingStuff();
#endif

  boa->impl_is_ready(0,1);
  Logger::log(Logger::corba) << "[0/5] BOA is running" << endl;

  ServerImpl *server = new ServerImpl;

  char *pluginDir = getenv("BERLIN_ROOT");
  if (!pluginDir)
    {
      cerr << "Please set environment variable BERLIN_ROOT first" << endl;
      exit(-1);
    }
  string modules = string(pluginDir) + "/modules";
  server->scan(modules.c_str());

  Logger::log(Logger::loader) << "[1/5] initialized loadable modules" << endl;

  Kit::PropertySeq props;
  props.length(1);
  props[0].name = CORBA::string_dup("implementation");
  value = "";
  getopt.get("drawing", &value);
  if (!value.empty()) props[0].value = CORBA::string_dup(value.c_str());
  else props[0].value = CORBA::string_dup("GLDrawingKit");
  DrawingKit_var drawing = server->resolve<DrawingKit>(interface(DrawingKit), props);
  if (CORBA::is_nil(drawing))
    {
      cerr << "unable to open " << interface(DrawingKit) << " with " << props[0].name << '=' << props[0].value << endl;
      exit(-1);
    }

  Logger::log(Logger::drawing) << "[2/5] built drawing system" << endl;

  // make a Screen graphic to hold this server's scene graph
  ScreenImpl *screen = new ScreenImpl(drawing);
  screen->_obj_is_ready(boa);

  DesktopImpl *desktop = new DesktopImpl;
  desktop->_obj_is_ready(boa);
  screen->body(Desktop_var(desktop->_this()));
  screen->appendController(Desktop_var(desktop->_this()));
  props.length(0);
  LayoutKit_var layout = server->resolve<LayoutKit>(interface(LayoutKit), props);
  Stage_var stage = layout->createStage();
  desktop->init(stage);

  Logger::log(Logger::layout) << "[3/5] created desktop" << endl;

  // initialize the client listener
  server->setSingleton(interface(Desktop), Desktop_var(desktop->_this()));
  server->setSingleton(interface(DrawingKit), drawing);
  server->_obj_is_ready(boa);
  server->start();

  Logger::log(Logger::layout) << "started server" << endl;
  bind_name(orb, Server_var(server->_this()), interface(Server));

  Logger::log(Logger::corba) << "[4/5] listening for clients" << endl;
  // initialize the event distributor and draw thread
  ScreenManager *smanager = screen->manager();
  Logger::log(Logger::corba) << "[5/5] event distributor constructed, about to enter main loop" << endl;
  try
    {
      smanager->run();
    }
  catch (CORBA::SystemException &se)
    {
      cout << "system exception " << se.NP_RepositoryId() << endl;
    }
  catch(omniORB::fatalException &fe)
    {
      cerr << "fatal exception at " << fe.file() << " " << fe.line() << ":" << fe.errmsg() << endl;
    }
  catch (...)
    {
      cout << "unknown exception caught" << endl;
    };
  return 0;
}
<commit_msg>server logging output is redirected to 'server.log'<commit_after>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1999 Stefan Seefeld <stefan@berlin-consortium.org>
 * Copyright (C) 1999 Graydon Hoare <graydon@pobox.com>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include <Warsaw/config.hh>
#include <Warsaw/resolve.hh>
#include <Warsaw/LayoutKit.hh>
#include <Warsaw/WidgetKit.hh>
#include <Warsaw/DrawingKit.hh>
#include <Berlin/ScreenImpl.hh>
#include <Berlin/ScreenManager.hh>
#include <Berlin/ServerImpl.hh>
#include <Berlin/Logger.hh>
#include <Berlin/DesktopImpl.hh>
#include <Prague/Sys/Tracer.hh>
#include <Prague/Sys/Signal.hh>
#include <Prague/Sys/Profiler.hh>
#include <Prague/Sys/Timer.hh>
#include <Prague/Sys/GetOpt.hh>
#include <fstream>

#ifdef JPROF
// probably need to change include path
#include "jprof.h"
#endif

using namespace Prague;

struct Dump : Signal::Notifier
{
  void notify(int signo)
    {
      switch (signo)
	{
	case Signal::hangup: Profiler::dump(cerr); break;
	case Signal::abort:
	case Signal::segv:
          {
            string output = "server.log";
            ofstream ofs(output.c_str());
	    Logger::dump(ofs);
	    ofs << "\n\nDetailed Trace:\n";
	    Tracer::dump(ofs);
	    cerr << "Something went wrong. " << output << " contains a debugging log.\n"
                 << "Please mail this output to bugs@berlin-consortium.org :\n\n";
            exit(-1);
          }
	}
    }
};

int main(int argc, char **argv)
{
  Dump *dump = new Dump;
  Signal::set(Signal::abort, dump);
  Signal::set(Signal::segv, dump);
  Signal::set(Signal::hangup, dump);

  CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB2");
  CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB2_BOA");

  GetOpt getopt(argv[0], "a berlin display server");
  getopt.add('v', "version", GetOpt::novalue, "version number");
  getopt.add('h', "help", GetOpt::novalue, "help message");
  getopt.add('l', "logging", GetOpt::novalue, "switch logging on");
  getopt.add('p', "profiling", GetOpt::novalue, "switch profiling on");
  getopt.add('d', "drawing", GetOpt::mandatory, "the DrawingKit to choose");
  getopt.parse(argc - 1, argv + 1);
  string value;
  getopt.get("version", &value);
  if (value == "true") { cout << "version is " << "0.2" << endl; exit(0);}
  value == "";
  getopt.get("help", &value);
  if (value == "true") { getopt.usage(); exit(0);}
  value == "";
  getopt.get("logging", &value);
  if (value == "true")
    {
      Logger::set(Logger::corba);
      Logger::set(Logger::focus);
      Logger::set(Logger::image);
      Logger::set(Logger::loader);
      Logger::set(Logger::subject);
      Logger::set(Logger::layout);
      Logger::set(Logger::picking);
      Logger::set(Logger::drawing);
      Logger::set(Logger::traversal);
      Logger::set(Logger::widget);
      Tracer::logging(true);
    }

#ifdef JPROF
  value == "";
  getopt.get("profiling", &value);
  if (value == "true") setupProfilingStuff();
#endif

  boa->impl_is_ready(0,1);
  Logger::log(Logger::corba) << "[0/5] BOA is running" << endl;

  ServerImpl *server = new ServerImpl;

  char *pluginDir = getenv("BERLIN_ROOT");
  if (!pluginDir)
    {
      cerr << "Please set environment variable BERLIN_ROOT first" << endl;
      exit(-1);
    }
  string modules = string(pluginDir) + "/modules";
  server->scan(modules.c_str());

  Logger::log(Logger::loader) << "[1/5] initialized loadable modules" << endl;

  Kit::PropertySeq props;
  props.length(1);
  props[0].name = CORBA::string_dup("implementation");
  value = "";
  getopt.get("drawing", &value);
  if (!value.empty()) props[0].value = CORBA::string_dup(value.c_str());
  else props[0].value = CORBA::string_dup("GLDrawingKit");
  DrawingKit_var drawing = server->resolve<DrawingKit>(interface(DrawingKit), props);
  if (CORBA::is_nil(drawing))
    {
      cerr << "unable to open " << interface(DrawingKit) << " with " << props[0].name << '=' << props[0].value << endl;
      exit(-1);
    }

  Logger::log(Logger::drawing) << "[2/5] built drawing system" << endl;

  // make a Screen graphic to hold this server's scene graph
  ScreenImpl *screen = new ScreenImpl(drawing);
  screen->_obj_is_ready(boa);

  DesktopImpl *desktop = new DesktopImpl;
  desktop->_obj_is_ready(boa);
  screen->body(Desktop_var(desktop->_this()));
  screen->appendController(Desktop_var(desktop->_this()));
  props.length(0);
  LayoutKit_var layout = server->resolve<LayoutKit>(interface(LayoutKit), props);
  Stage_var stage = layout->createStage();
  desktop->init(stage);

  Logger::log(Logger::layout) << "[3/5] created desktop" << endl;

  // initialize the client listener
  server->setSingleton(interface(Desktop), Desktop_var(desktop->_this()));
  server->setSingleton(interface(DrawingKit), drawing);
  server->_obj_is_ready(boa);
  server->start();

  Logger::log(Logger::layout) << "started server" << endl;
  bind_name(orb, Server_var(server->_this()), interface(Server));

  Logger::log(Logger::corba) << "[4/5] listening for clients" << endl;
  // initialize the event distributor and draw thread
  ScreenManager *smanager = screen->manager();
  Logger::log(Logger::corba) << "[5/5] event distributor constructed, about to enter main loop" << endl;
  try
    {
      smanager->run();
    }
  catch (CORBA::SystemException &se)
    {
      cout << "system exception " << se.NP_RepositoryId() << endl;
    }
  catch(omniORB::fatalException &fe)
    {
      cerr << "fatal exception at " << fe.file() << " " << fe.line() << ":" << fe.errmsg() << endl;
    }
  catch (...)
    {
      cout << "unknown exception caught" << endl;
    };
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008-2016 the MRtrix3 contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix 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.
 *
 * For more details, see www.mrtrix.org
 *
 */

// to extract all documented configuration options from the code, use this
// command (or a modification of it):
//
// grep -rn --include=\*.h --include=\*.cpp '^\s*//CONF\b ' . | sed -ne 's/^.*CONF \(.*\)/\1/p'

#include "file/path.h"
#include "file/config.h"

#define MRTRIX_CONFIG_FILE "mrtrix.conf"

#ifdef MRTRIX_WINDOWS
#define MRTRIX_SYS_CONFIG_FILE "C:\\" MRTRIX_CONFIG_FILE
#define MRTRIX_USER_CONFIG_FILE MRTRIX_CONFIG_FILE
#else
#define MRTRIX_SYS_CONFIG_FILE "/etc/" MRTRIX_CONFIG_FILE
#define MRTRIX_USER_CONFIG_FILE "." MRTRIX_CONFIG_FILE
#endif

namespace MR
{
  namespace File
  {

    std::map<std::string, std::string> Config::config;

    void Config::init ()
    {
      if (Path::is_file (MRTRIX_SYS_CONFIG_FILE)) {
        INFO ("reading config file \"" MRTRIX_SYS_CONFIG_FILE "\"...");
        try {
          KeyValue kv (MRTRIX_SYS_CONFIG_FILE);
          while (kv.next()) {
            config[kv.key()] = kv.value();
          }
        }
        catch (...) { }
      }

      std::string path = Path::join (Path::home(), MRTRIX_USER_CONFIG_FILE);
      if (Path::is_file (path)) {
        INFO ("reading config file \"" + path + "\"...");
        try {
          KeyValue kv (path);
          while (kv.next()) {
            config[kv.key()] = kv.value();
          }
        }
        catch (...) { }
      }
    }

    bool Config::get_bool (const std::string& key, bool default_value)
    {
      std::string value = get (key);
      if (value.empty())
        return default_value;
      try {
        return to<bool> (value);
      }
      catch (...) {
        WARN ("malformed boolean entry \"" + value + "\" for key \"" + key + "\" in configuration file - ignored");
        return default_value;
      }
    }

    int Config::get_int (const std::string& key, int default_value)
    {
      std::string value = get (key);
      if (value.empty())
        return default_value;
      try {
        return to<int> (value);
      }
      catch (...) {
        WARN ("malformed integer entry \"" + value + "\" for key \"" + key + "\" in configuration file - ignored");
        return default_value;
      }
    }

    float Config::get_float (const std::string& key, float default_value)
    {
      std::string value = get (key);
      if (value.empty())
        return default_value;
      try {
        return to<float> (value);
      }
      catch (...) {
        WARN ("malformed floating-point entry \"" + value + "\" for key \"" + key + "\" in configuration file - ignored");
        return default_value;
      }
    }

    void Config::get_RGB (const std::string& key, float* ret, float default_R, float default_G, float default_B)
    {
      std::string value = get (key);
      if (value.size()) {
        try {
          std::vector<default_type> V (parse_floats (value));
          if (V.size() < 3)
            throw Exception ("malformed RGB entry \"" + value + "\" for key \"" + key + "\" in configuration file - ignored");
          ret[0] = V[0];
          ret[1] = V[1];
          ret[2] = V[2];
        }
        catch (Exception) { }
      }
      else {
        ret[0] = default_R;
        ret[1] = default_G;
        ret[2] = default_B;
      }
    }

  }
}

<commit_msg>Windows: config file location is the same as for Unix<commit_after>/*
 * Copyright (c) 2008-2016 the MRtrix3 contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix 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.
 *
 * For more details, see www.mrtrix.org
 *
 */

// to extract all documented configuration options from the code, use this
// command (or a modification of it):
//
// grep -rn --include=\*.h --include=\*.cpp '^\s*//CONF\b ' . | sed -ne 's/^.*CONF \(.*\)/\1/p'

#include "file/path.h"
#include "file/config.h"

#define MRTRIX_CONFIG_FILE "mrtrix.conf"
#define MRTRIX_SYS_CONFIG_FILE "/etc/" MRTRIX_CONFIG_FILE
#define MRTRIX_USER_CONFIG_FILE "." MRTRIX_CONFIG_FILE

namespace MR
{
  namespace File
  {

    std::map<std::string, std::string> Config::config;

    void Config::init ()
    {
      if (Path::is_file (MRTRIX_SYS_CONFIG_FILE)) {
        INFO ("reading config file \"" MRTRIX_SYS_CONFIG_FILE "\"...");
        try {
          KeyValue kv (MRTRIX_SYS_CONFIG_FILE);
          while (kv.next()) {
            config[kv.key()] = kv.value();
          }
        }
        catch (...) { }
      }

      std::string path = Path::join (Path::home(), MRTRIX_USER_CONFIG_FILE);
      if (Path::is_file (path)) {
        INFO ("reading config file \"" + path + "\"...");
        try {
          KeyValue kv (path);
          while (kv.next()) {
            config[kv.key()] = kv.value();
          }
        }
        catch (...) { }
      }
    }

    bool Config::get_bool (const std::string& key, bool default_value)
    {
      std::string value = get (key);
      if (value.empty())
        return default_value;
      try {
        return to<bool> (value);
      }
      catch (...) {
        WARN ("malformed boolean entry \"" + value + "\" for key \"" + key + "\" in configuration file - ignored");
        return default_value;
      }
    }

    int Config::get_int (const std::string& key, int default_value)
    {
      std::string value = get (key);
      if (value.empty())
        return default_value;
      try {
        return to<int> (value);
      }
      catch (...) {
        WARN ("malformed integer entry \"" + value + "\" for key \"" + key + "\" in configuration file - ignored");
        return default_value;
      }
    }

    float Config::get_float (const std::string& key, float default_value)
    {
      std::string value = get (key);
      if (value.empty())
        return default_value;
      try {
        return to<float> (value);
      }
      catch (...) {
        WARN ("malformed floating-point entry \"" + value + "\" for key \"" + key + "\" in configuration file - ignored");
        return default_value;
      }
    }

    void Config::get_RGB (const std::string& key, float* ret, float default_R, float default_G, float default_B)
    {
      std::string value = get (key);
      if (value.size()) {
        try {
          std::vector<default_type> V (parse_floats (value));
          if (V.size() < 3)
            throw Exception ("malformed RGB entry \"" + value + "\" for key \"" + key + "\" in configuration file - ignored");
          ret[0] = V[0];
          ret[1] = V[1];
          ret[2] = V[2];
        }
        catch (Exception) { }
      }
      else {
        ret[0] = default_R;
        ret[1] = default_G;
        ret[2] = default_B;
      }
    }

  }
}

<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2019-2022 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "vk_test.h"

RD_TEST(VK_SPIRV_13_Shaders, VulkanGraphicsTest)
{
  static constexpr const char *Description =
      "Draws a triangle using SPIR-V 1.3 shaders to ensure they are handled correctly.";

  const std::string vertex = R"EOSHADER(

void vertmain(in float3 pos : INPOS, in float4 col : INCOL, in float2 uv : UV,
              out float4 opos : SV_Position, out float4 outcol : COL)
{
	opos = float4(pos.xyz*float3(1,-1,1), 1);
	outcol = col;
}

)EOSHADER";

  const std::string pixel = R"EOSHADER(

void fragmain(in float4 incol : COL, out float4 ocol : SV_Target0)
{
	ocol = incol;
}

)EOSHADER";

  void Prepare(int argc, char **argv)
  {
    VulkanGraphicsTest::Prepare(argc, argv);

    if(!Avail.empty())
      return;

    if(devVersion < VK_API_VERSION_1_1)
      Avail = "Vulkan device version isn't 1.1";
  }

  int main()
  {
    // initialise, create window, create context, etc
    if(!Init())
      return 3;

    VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo());

    vkh::GraphicsPipelineCreateInfo pipeCreateInfo;

    pipeCreateInfo.layout = layout;
    pipeCreateInfo.renderPass = mainWindow->rp;

    pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
    pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
        vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
        vkh::vertexAttr(2, 0, DefaultA2V, uv),
    };

    pipeCreateInfo.stages = {
        CompileShaderModule(vertex, ShaderLang::hlsl, ShaderStage::vert, "vertmain", {},
                            SPIRVTarget::vulkan11),
        CompileShaderModule(pixel, ShaderLang::hlsl, ShaderStage::frag, "fragmain", {},
                            SPIRVTarget::vulkan11),
    };

    VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);

    const DefaultA2V tri[3] = {
        {Vec3f(-0.5f, -0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(0.0f, 0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)},
        {Vec3f(0.5f, -0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)},
    };

    AllocatedBuffer vb(this, vkh::BufferCreateInfo(sizeof(tri), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
                                                                    VK_BUFFER_USAGE_TRANSFER_DST_BIT),
                       VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    vb.upload(tri);

    while(Running())
    {
      VkCommandBuffer cmd = GetCommandBuffer();

      vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());

      VkImage swapimg =
          StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
                           vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
                           vkh::ImageSubresourceRange());

      vkCmdBeginRenderPass(
          cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
          VK_SUBPASS_CONTENTS_INLINE);

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
      vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
      vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
      vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
      vkCmdDraw(cmd, 3, 1, 0, 0);

      vkCmdEndRenderPass(cmd);

      FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkEndCommandBuffer(cmd);

      Submit(0, 1, {cmd});

      Present();
    }

    return 0;
  }
};

REGISTER_TEST();
<commit_msg>Fix test failing if compiler eliminates dead inputs<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2019-2022 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "vk_test.h"

RD_TEST(VK_SPIRV_13_Shaders, VulkanGraphicsTest)
{
  static constexpr const char *Description =
      "Draws a triangle using SPIR-V 1.3 shaders to ensure they are handled correctly.";

  const std::string vertex = R"EOSHADER(

void vertmain(in float3 pos : INPOS, in float4 col : INCOL, in float2 uv : UV,
              out float4 opos : SV_Position, out float4 outcol : COL)
{
	opos = float4(pos.xyz*float3(1,-1,1), 1);
	outcol = col + 1.0e-10 * uv.xyxy;
}

)EOSHADER";

  const std::string pixel = R"EOSHADER(

void fragmain(in float4 incol : COL, out float4 ocol : SV_Target0)
{
	ocol = incol;
}

)EOSHADER";

  void Prepare(int argc, char **argv)
  {
    VulkanGraphicsTest::Prepare(argc, argv);

    if(!Avail.empty())
      return;

    if(devVersion < VK_API_VERSION_1_1)
      Avail = "Vulkan device version isn't 1.1";
  }

  int main()
  {
    // initialise, create window, create context, etc
    if(!Init())
      return 3;

    VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo());

    vkh::GraphicsPipelineCreateInfo pipeCreateInfo;

    pipeCreateInfo.layout = layout;
    pipeCreateInfo.renderPass = mainWindow->rp;

    pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
    pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
        vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
        vkh::vertexAttr(2, 0, DefaultA2V, uv),
    };

    pipeCreateInfo.stages = {
        CompileShaderModule(vertex, ShaderLang::hlsl, ShaderStage::vert, "vertmain", {},
                            SPIRVTarget::vulkan11),
        CompileShaderModule(pixel, ShaderLang::hlsl, ShaderStage::frag, "fragmain", {},
                            SPIRVTarget::vulkan11),
    };

    VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);

    const DefaultA2V tri[3] = {
        {Vec3f(-0.5f, -0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(0.0f, 0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)},
        {Vec3f(0.5f, -0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)},
    };

    AllocatedBuffer vb(this, vkh::BufferCreateInfo(sizeof(tri), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
                                                                    VK_BUFFER_USAGE_TRANSFER_DST_BIT),
                       VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    vb.upload(tri);

    while(Running())
    {
      VkCommandBuffer cmd = GetCommandBuffer();

      vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());

      VkImage swapimg =
          StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
                           vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
                           vkh::ImageSubresourceRange());

      vkCmdBeginRenderPass(
          cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
          VK_SUBPASS_CONTENTS_INLINE);

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
      vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
      vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
      vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
      vkCmdDraw(cmd, 3, 1, 0, 0);

      vkCmdEndRenderPass(cmd);

      FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkEndCommandBuffer(cmd);

      Submit(0, 1, {cmd});

      Present();
    }

    return 0;
  }
};

REGISTER_TEST();
<|endoftext|>


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

#include <vector>

#include "FliImpl.h"
#include "acc_vhdl.h"   // Messy :(
#include "acc_user.h"

extern "C" {

static FliImpl *fli_table;

void fli_elab_cb(void *nothing) {
    LOG_INFO("fli_elab_cb called\n");

    fli_table = new FliImpl("FLI");
    gpi_register_impl(fli_table);
    gpi_load_extra_libs();

    // Elaboration has already happened so jump straight in!
    gpi_sim_info_t sim_info;

    char *version = mti_GetProductVersion();      // Returned pointer must not be freed

    // copy in sim_info.product
    // FIXME split product and version from returned string?
    sim_info.argc = 0;
    sim_info.argv = NULL;
    sim_info.product = version;
    sim_info.version = version;

    gpi_embed_init(&sim_info);
}

void cocotb_init(void) {
    LOG_INFO("cocotb_init called\n");
    mti_AddLoadDoneCB(fli_elab_cb, NULL);
}

// Main re-entry point for callbacks from simulator
void handle_fli_callback(void *data)
{
    FliCbHdl *cb_hdl = (FliCbHdl*)data;

    if (!cb_hdl)
        LOG_CRITICAL("FLI: Callback data corrupted");

    gpi_cb_state_e old_state = cb_hdl->get_call_state();

    if (old_state == GPI_PRIMED) {

        cb_hdl->set_call_state(GPI_CALL);
        cb_hdl->run_callback();

        gpi_cb_state_e new_state = cb_hdl->get_call_state();

        /* We have re-primed in the handler */
        if (new_state != GPI_PRIMED)
            if (cb_hdl->cleanup_callback())
                delete cb_hdl;
    }
};

} // extern "C"

void FliImpl::sim_end(void)
{
    mti_Quit();
}

/**
 * @name    Native Check Create
 * @brief   Determine whether a simulation object is native to FLI and create
 *          a handle if it is
 */
GpiObjHdl*  FliImpl::native_check_create(std::string &name, GpiObjHdl *parent)
{
    LOG_INFO("Looking for child %s from %s", name.c_str(), parent->get_name_str());

    GpiObjHdl *new_obj = NULL;
    std::vector<char> writable(name.begin(), name.end());
    writable.push_back('\0');

    mtiSignalIdT sig_hdl;
    sig_hdl = mti_FindSignal(&writable[0]);
    if (sig_hdl) {
        LOG_INFO("Found a signal %s -> %p", &writable[0], sig_hdl);
        new_obj = new FliSignalObjHdl(this, sig_hdl);
    }

    if (NULL == new_obj) {
        LOG_WARN("Didn't find anything named %s", &writable[0]);
        return NULL;
    }

    new_obj->initialise(name);
    return new_obj;
}

/**
 * @name    Native Check Create
 * @brief   Determine whether a simulation object is native to FLI and create
 *          a handle if it is
 */
GpiObjHdl*  FliImpl::native_check_create(uint32_t index, GpiObjHdl *parent)
{
    return NULL;
}

const char *FliImpl::reason_to_string(int reason)
{
    return "Who can explain it, who can tell you why?";
}

/**
 * @name    Get current simulation time
 * @brief   Get current simulation time
 *
 * NB units depend on the simulation configuration
 */
void FliImpl::get_sim_time(uint32_t *high, uint32_t *low)
{
    *high = mti_NowUpper();
    *low = mti_Now();
}

#if 0
/**
 * @name    Find the root handle
 * @brief   Find the root handle using an optional name
 *
 * Get a handle to the root simulator object.  This is usually the toplevel.
 *
 * If no name is provided, we return the first root instance.
 *
 * If name is provided, we check the name against the available objects until
 * we find a match.  If no match is found we return NULL
 */
int FliObjHdl::initialise(std::string &name) {
    m_name = name;
    m_type = "unknown";

    return 0;
}
#endif

/**
 * @name    Find the root handle
 * @brief   Find the root handle using an optional name
 *
 * Get a handle to the root simulator object.  This is usually the toplevel.
 *
 * If no name is provided, we return the first root instance.
 *
 * If name is provided, we check the name against the available objects until
 * we find a match.  If no match is found we return NULL
 */
GpiObjHdl *FliImpl::get_root_handle(const char *name)
{
    mtiRegionIdT root;
    GpiObjHdl *rv;
    std::string root_name = name;

    for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) {
        LOG_INFO("Iterating over: %s", mti_GetRegionName(root));
        if (name == NULL || !strcmp(name, mti_GetRegionName(root)))
            break;
    }

    if (!root) {
        goto error;
    }

    LOG_INFO("Found toplevel: %s, creating handle....", name);

    rv = new FliRegionObjHdl(this, root);
    rv->initialise(root_name);

    LOG_INFO("Returning root handle %p", rv);
    return rv;

  error:

    LOG_CRITICAL("FLI: Couldn't find root handle %s", name);

    for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) {

        LOG_CRITICAL("FLI: Toplevel instances: %s != %s...", name, mti_GetRegionName(root));

        if (name == NULL)
            break;
    }
    return NULL;
}

GpiCbHdl *FliImpl::register_timed_callback(uint64_t time_ps)
{
    FliTimedCbHdl *hdl = new FliTimedCbHdl(this, time_ps);

    if (hdl->arm_callback()) {
        delete(hdl);
        hdl = NULL;
    }
    return hdl;
}

GpiCbHdl *FliImpl::register_readonly_callback(void)
{
    if (m_readonly_cbhdl.arm_callback()) {
        return NULL;
    }
    return &m_readonly_cbhdl;
}

GpiCbHdl *FliImpl::register_readwrite_callback(void)
{
    if (m_readwrite_cbhdl.arm_callback()) {
        return NULL;
    }
    return &m_readwrite_cbhdl;
}

GpiCbHdl *FliImpl::register_nexttime_callback(void)
{
    if (m_nexttime_cbhdl.arm_callback()) {
        return NULL;
    }
    return &m_nexttime_cbhdl;
}

int FliImpl::deregister_callback(GpiCbHdl *gpi_hdl)
{
    int rc = gpi_hdl->cleanup_callback();
    // TOOD: Don't delete if it's a re-usable doobery
//     delete(gpi_hdl);
    return rc;
}

/**
 * @name    cleanup callback
 * @brief   Called while unwinding after a GPI callback
 *
 * We keep the process but de-sensitise it
 *
 * NB need a way to determine if should leave it sensitised, hmmm...
 *
 */
int FliProcessCbHdl::cleanup_callback(void) {

    if (m_sensitised)
        mti_Desensitize(m_proc_hdl);
    m_sensitised = false;
    return 0;
}

int FliTimedCbHdl::arm_callback(void) {
    LOG_INFO("Creating a new process to sensitise with timer");
    m_proc_hdl = mti_CreateProcessWithPriority(NULL, handle_fli_callback, (void *)this, MTI_PROC_IMMEDIATE);
    mti_ScheduleWakeup(m_proc_hdl, m_time_ps);
    LOG_INFO("Wakeup scheduled on %p for %llu", m_proc_hdl, m_time_ps);
    m_sensitised = true;
    return 0;
}

int FliSignalCbHdl::arm_callback(void) {

    if (NULL == m_proc_hdl) {
        LOG_INFO("Creating a new process to sensitise to signal %s", mti_GetSignalName(m_sig_hdl));
        m_proc_hdl = mti_CreateProcess(NULL, handle_fli_callback, (void *)this);
    }

    mti_Sensitize(m_proc_hdl, m_sig_hdl, MTI_EVENT);
    m_sensitised = true;
    return 0;
}

int FliSimPhaseCbHdl::arm_callback(void) {

    if (NULL == m_proc_hdl) {
        LOG_INFO("Creating a new process to sensitise with priority %d", m_priority);
        m_proc_hdl = mti_CreateProcessWithPriority(NULL, handle_fli_callback, (void *)this, m_priority);
    }

    mti_ScheduleWakeup(m_proc_hdl, 0);
    m_sensitised = true;
    return 0;
}

GPI_ENTRY_POINT(fli, cocotb_init);

GpiCbHdl *FliSignalObjHdl::value_change_cb(unsigned int edge) {

    LOG_INFO("Creating value change callback for %s", m_name.c_str());

    if (NULL == m_cb_hdl) {
        m_cb_hdl = new FliSignalCbHdl(m_impl, m_fli_hdl);
    }
    m_cb_hdl->arm_callback();

    return m_cb_hdl;
}

const char* FliSignalObjHdl::get_signal_value_binstr(void) {
    return "010101";
}

int FliSignalObjHdl::set_signal_value(const int value) {
    return 0;
}

int FliSignalObjHdl::set_signal_value(std::string &value) {
    return 0;
}

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

#include <vector>

#include "FliImpl.h"
#include "acc_vhdl.h"   // Messy :(
#include "acc_user.h"

extern "C" {

static FliImpl *fli_table;

void fli_elab_cb(void *nothing) {
    LOG_INFO("fli_elab_cb called\n");

    fli_table = new FliImpl("FLI");
    gpi_register_impl(fli_table);
    gpi_load_extra_libs();

    // Elaboration has already happened so jump straight in!
    gpi_sim_info_t sim_info;

    char *version = mti_GetProductVersion();      // Returned pointer must not be freed

    // copy in sim_info.product
    // FIXME split product and version from returned string?
    sim_info.argc = 0;
    sim_info.argv = NULL;
    sim_info.product = version;
    sim_info.version = version;

    gpi_embed_init(&sim_info);
}

void cocotb_init(void) {
    LOG_INFO("cocotb_init called\n");
    mti_AddLoadDoneCB(fli_elab_cb, NULL);
}

// Main re-entry point for callbacks from simulator
void handle_fli_callback(void *data)
{
    fprintf(stderr, "Got a callback\n");
    fflush(stderr);

    FliCbHdl *cb_hdl = (FliCbHdl*)data;

    if (!cb_hdl)
        LOG_CRITICAL("FLI: Callback data corrupted");

    gpi_cb_state_e old_state = cb_hdl->get_call_state();

    fprintf(stderr, "FLI: Old state was %d!\n", old_state);
    fflush(stderr);

    if (old_state == GPI_PRIMED) {

        cb_hdl->set_call_state(GPI_CALL);
        cb_hdl->run_callback();

        gpi_cb_state_e new_state = cb_hdl->get_call_state();

        /* We have re-primed in the handler */
        if (new_state != GPI_PRIMED)
            if (cb_hdl->cleanup_callback())
                delete cb_hdl;
    }
};

} // extern "C"

void FliImpl::sim_end(void)
{
    mti_Quit();
}

/**
 * @name    Native Check Create
 * @brief   Determine whether a simulation object is native to FLI and create
 *          a handle if it is
 */
GpiObjHdl*  FliImpl::native_check_create(std::string &name, GpiObjHdl *parent)
{
    LOG_INFO("Looking for child %s from %s", name.c_str(), parent->get_name_str());

    GpiObjHdl *new_obj = NULL;
    std::vector<char> writable(name.begin(), name.end());
    writable.push_back('\0');

    mtiSignalIdT sig_hdl;
    sig_hdl = mti_FindSignal(&writable[0]);
    if (sig_hdl) {
        LOG_INFO("Found a signal %s -> %p", &writable[0], sig_hdl);
        new_obj = new FliSignalObjHdl(this, sig_hdl);
    }

    if (NULL == new_obj) {
        LOG_WARN("Didn't find anything named %s", &writable[0]);
        return NULL;
    }

    new_obj->initialise(name);
    return new_obj;
}

/**
 * @name    Native Check Create
 * @brief   Determine whether a simulation object is native to FLI and create
 *          a handle if it is
 */
GpiObjHdl*  FliImpl::native_check_create(uint32_t index, GpiObjHdl *parent)
{
    return NULL;
}

const char *FliImpl::reason_to_string(int reason)
{
    return "Who can explain it, who can tell you why?";
}

/**
 * @name    Get current simulation time
 * @brief   Get current simulation time
 *
 * NB units depend on the simulation configuration
 */
void FliImpl::get_sim_time(uint32_t *high, uint32_t *low)
{
    *high = mti_NowUpper();
    *low = mti_Now();
}

#if 0
/**
 * @name    Find the root handle
 * @brief   Find the root handle using an optional name
 *
 * Get a handle to the root simulator object.  This is usually the toplevel.
 *
 * If no name is provided, we return the first root instance.
 *
 * If name is provided, we check the name against the available objects until
 * we find a match.  If no match is found we return NULL
 */
int FliObjHdl::initialise(std::string &name) {
    m_name = name;
    m_type = "unknown";

    return 0;
}
#endif

/**
 * @name    Find the root handle
 * @brief   Find the root handle using an optional name
 *
 * Get a handle to the root simulator object.  This is usually the toplevel.
 *
 * If no name is provided, we return the first root instance.
 *
 * If name is provided, we check the name against the available objects until
 * we find a match.  If no match is found we return NULL
 */
GpiObjHdl *FliImpl::get_root_handle(const char *name)
{
    mtiRegionIdT root;
    GpiObjHdl *rv;
    std::string root_name = name;

    for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) {
        LOG_INFO("Iterating over: %s", mti_GetRegionName(root));
        if (name == NULL || !strcmp(name, mti_GetRegionName(root)))
            break;
    }

    if (!root) {
        goto error;
    }

    LOG_INFO("Found toplevel: %s, creating handle....", name);

    rv = new FliRegionObjHdl(this, root);
    rv->initialise(root_name);

    LOG_INFO("Returning root handle %p", rv);
    return rv;

  error:

    LOG_CRITICAL("FLI: Couldn't find root handle %s", name);

    for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) {

        LOG_CRITICAL("FLI: Toplevel instances: %s != %s...", name, mti_GetRegionName(root));

        if (name == NULL)
            break;
    }
    return NULL;
}

GpiCbHdl *FliImpl::register_timed_callback(uint64_t time_ps)
{
    FliTimedCbHdl *hdl = new FliTimedCbHdl(this, time_ps);

    if (hdl->arm_callback()) {
        delete(hdl);
        hdl = NULL;
    }
    return hdl;
}

GpiCbHdl *FliImpl::register_readonly_callback(void)
{
    if (m_readonly_cbhdl.arm_callback()) {
        return NULL;
    }
    return &m_readonly_cbhdl;
}

GpiCbHdl *FliImpl::register_readwrite_callback(void)
{
    if (m_readwrite_cbhdl.arm_callback()) {
        return NULL;
    }
    return &m_readwrite_cbhdl;
}

GpiCbHdl *FliImpl::register_nexttime_callback(void)
{
    if (m_nexttime_cbhdl.arm_callback()) {
        return NULL;
    }
    return &m_nexttime_cbhdl;
}

int FliImpl::deregister_callback(GpiCbHdl *gpi_hdl)
{
    int rc = gpi_hdl->cleanup_callback();
    // TOOD: Don't delete if it's a re-usable doobery
//     delete(gpi_hdl);
    return rc;
}

/**
 * @name    cleanup callback
 * @brief   Called while unwinding after a GPI callback
 *
 * We keep the process but de-sensitise it
 *
 * NB need a way to determine if should leave it sensitised, hmmm...
 *
 */
int FliProcessCbHdl::cleanup_callback(void) {

    if (m_sensitised)
        mti_Desensitize(m_proc_hdl);
    m_sensitised = false;
    return 0;
}

int FliTimedCbHdl::arm_callback(void) {
    LOG_INFO("Creating a new process to sensitise with timer");
    m_proc_hdl = mti_CreateProcessWithPriority(NULL, handle_fli_callback, (void *)this, MTI_PROC_IMMEDIATE);
    mti_ScheduleWakeup(m_proc_hdl, m_time_ps);
    LOG_INFO("Wakeup scheduled on %p for %llu", m_proc_hdl, m_time_ps);
    m_sensitised = true;
    m_state = GPI_PRIMED;
    return 0;
}

int FliSignalCbHdl::arm_callback(void) {

    if (NULL == m_proc_hdl) {
        LOG_INFO("Creating a new process to sensitise to signal %s", mti_GetSignalName(m_sig_hdl));
        m_proc_hdl = mti_CreateProcess(NULL, handle_fli_callback, (void *)this);
    }

    mti_Sensitize(m_proc_hdl, m_sig_hdl, MTI_EVENT);
    m_sensitised = true;
    m_state = GPI_PRIMED;
    return 0;
}

int FliSimPhaseCbHdl::arm_callback(void) {

    if (NULL == m_proc_hdl) {
        LOG_INFO("Creating a new process to sensitise with priority %d", m_priority);
        m_proc_hdl = mti_CreateProcessWithPriority(NULL, handle_fli_callback, (void *)this, m_priority);
    }

    mti_ScheduleWakeup(m_proc_hdl, 0);
    m_sensitised = true;
    m_state = GPI_PRIMED;
    return 0;
}

GPI_ENTRY_POINT(fli, cocotb_init);

GpiCbHdl *FliSignalObjHdl::value_change_cb(unsigned int edge) {

    LOG_INFO("Creating value change callback for %s", m_name.c_str());

    if (NULL == m_cb_hdl) {
        m_cb_hdl = new FliSignalCbHdl(m_impl, m_fli_hdl);
    }
    m_cb_hdl->arm_callback();

    return m_cb_hdl;
}

const char* FliSignalObjHdl::get_signal_value_binstr(void) {
    return "010101";
}

int FliSignalObjHdl::set_signal_value(const int value) {
    return 0;
}

int FliSignalObjHdl::set_signal_value(std::string &value) {
    return 0;
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2012 Couchbase, Inc
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#include "config.h"
#include <algorithm>
#include <cerrno>
#include <cstdlib>
#include <string.h>
#include <strings.h>
#include <cerrno>
#include <getopt.h>
#include <sys/stat.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <ctype.h>

#include "cJSON.h"

using namespace std;

/**
 * Print the JSON object quoted
 */
static ostream& operator <<(ostream &out, cJSON *json)
{
    char *data = cJSON_PrintUnformatted(json);
    int ii = 0;

    out << '"';
    while (data[ii] != '\0') {
        if (data[ii] == '"') {
            out << '\\';
        }
        out << data[ii];
        ++ii;
    }

    out << '"';
    free(data);
    return out;
}

static void usage(void)
{
    cerr << "Usage: gencode -j JSON -c cfile -h headerfile -f function"
         << endl
         << "\tThe JSON file will be read to generate the c and h file."
         << endl;
    exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
    int cmd;
    const char *json = NULL;
    const char *hfile = NULL;
    const char *cfile = NULL;
    const char *function = NULL;

    while ((cmd = getopt(argc, argv, "j:c:h:f:")) != -1) {
        switch (cmd) {
        case 'j' :
            json = optarg;
            break;
        case 'c' :
            cfile = optarg;
            break;
        case 'h':
            hfile = optarg;
            break;
        case 'f':
            function = optarg;
            break;
        default:
            usage();
        }
    }

    if (json == NULL || hfile == NULL || cfile == NULL || function == NULL) {
        usage();
    }

    struct stat st;
    if (stat(json, &st) == -1) {
        cerr << "Failed to look up \"" << json << "\": "
             << strerror(errno) << endl;
        exit(EXIT_FAILURE);
    }

    char *data = new char[st.st_size + 1];
    data[st.st_size] = 0;
    ifstream input(json);
    input.read(data, st.st_size);
    input.close();

    cJSON *c = cJSON_Parse(data);
    if (c == NULL) {
        cerr << "Failed to parse JSON.. probably syntax error" << endl;
        exit(EXIT_FAILURE);
    }

    ofstream headerfile(hfile);

    std::string macro(hfile);
    std::replace(macro.begin(), macro.end(), '/', '_');
    std::replace(macro.begin(), macro.end(), '-', '_');
    std::replace(macro.begin(), macro.end(), '.', '_');
    std::replace(macro.begin(), macro.end(), ':', '_');
    std::transform(macro.begin(), macro.end(), macro.begin(), ::toupper);

    headerfile
        << "/*" << endl
        << " *     Copyright 2014 Couchbase, Inc" << endl
        << " *" << endl
        << " *   Licensed under the Apache License, Version 2.0 (the \"License\");" << endl
        << " *   you may not use this file except in compliance with the License." << endl
        << " *   You may obtain a copy of the License at" << endl
        << " *" << endl
        << " *       http://www.apache.org/licenses/LICENSE-2.0" << endl
        << " *" << endl
        << " *   Unless required by applicable law or agreed to in writing, software" << endl
        << " *   distributed under the License is distributed on an \"AS IS\" BASIS," << endl
        << " *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." << endl
        << " *   See the License for the specific language governing permissions and" << endl
        << " *   limitations under the License." << endl
        << " */" << endl
        << endl
        << "/********************************" << endl
        << "** Generated file, do not edit **" << endl
        << "*********************************/" << endl
        << "#ifndef " << macro << endl
        << "#define " << macro << endl
        << endl
        << "#include \"config.h\"" << endl
        << endl
        << "#ifdef __cplusplus" << endl
        << "extern \"C\" {" << endl
        << "#endif" << endl
        << endl
        << "const char *" << function << "(void);" << endl
        << endl
        << "#ifdef __cplusplus" << endl
        << "}" << endl
        << "#endif" << endl
        << "#endif  /* " << macro << "*/" << endl;
    headerfile.close();

    ofstream sourcefile(cfile);
    sourcefile
        << "/*" << endl
        << " *     Copyright 2014 Couchbase, Inc" << endl
        << " *" << endl
        << " *   Licensed under the Apache License, Version 2.0 (the \"License\");" << endl
        << " *   you may not use this file except in compliance with the License." << endl
        << " *   You may obtain a copy of the License at" << endl
        << " *" << endl
        << " *       http://www.apache.org/licenses/LICENSE-2.0" << endl
        << " *" << endl
        << " *   Unless required by applicable law or agreed to in writing, software" << endl
        << " *   distributed under the License is distributed on an \"AS IS\" BASIS," << endl
        << " *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." << endl
        << " *   See the License for the specific language governing permissions and" << endl
        << " *   limitations under the License." << endl
        << " */" << endl
        << endl
        << "/********************************" << endl
        << "** Generated file, do not edit **" << endl
        << "*********************************/" << endl
        << "#include \"config.h\"" << endl
        << "#include \"" << hfile << "\"" << endl
        << endl
        << "const char *" << function << "(void)" << endl
        << "{" << endl
        << "    return " << c << ";" << endl
        << "}" << endl;

    cJSON_Delete(c);

    return 0;
}
<commit_msg>Don't allow ' ' in the preprocessor macro<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2012 Couchbase, Inc
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#include "config.h"
#include <algorithm>
#include <cerrno>
#include <cstdlib>
#include <string.h>
#include <strings.h>
#include <cerrno>
#include <getopt.h>
#include <sys/stat.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <ctype.h>

#include "cJSON.h"

using namespace std;

/**
 * Print the JSON object quoted
 */
static ostream& operator <<(ostream &out, cJSON *json)
{
    char *data = cJSON_PrintUnformatted(json);
    int ii = 0;

    out << '"';
    while (data[ii] != '\0') {
        if (data[ii] == '"') {
            out << '\\';
        }
        out << data[ii];
        ++ii;
    }

    out << '"';
    free(data);
    return out;
}

static void usage(void)
{
    cerr << "Usage: gencode -j JSON -c cfile -h headerfile -f function"
         << endl
         << "\tThe JSON file will be read to generate the c and h file."
         << endl;
    exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
    int cmd;
    const char *json = NULL;
    const char *hfile = NULL;
    const char *cfile = NULL;
    const char *function = NULL;

    while ((cmd = getopt(argc, argv, "j:c:h:f:")) != -1) {
        switch (cmd) {
        case 'j' :
            json = optarg;
            break;
        case 'c' :
            cfile = optarg;
            break;
        case 'h':
            hfile = optarg;
            break;
        case 'f':
            function = optarg;
            break;
        default:
            usage();
        }
    }

    if (json == NULL || hfile == NULL || cfile == NULL || function == NULL) {
        usage();
    }

    struct stat st;
    if (stat(json, &st) == -1) {
        cerr << "Failed to look up \"" << json << "\": "
             << strerror(errno) << endl;
        exit(EXIT_FAILURE);
    }

    char *data = new char[st.st_size + 1];
    data[st.st_size] = 0;
    ifstream input(json);
    input.read(data, st.st_size);
    input.close();

    cJSON *c = cJSON_Parse(data);
    if (c == NULL) {
        cerr << "Failed to parse JSON.. probably syntax error" << endl;
        exit(EXIT_FAILURE);
    }

    ofstream headerfile(hfile);

    std::string macro(hfile);
    std::replace(macro.begin(), macro.end(), ' ', '_');
    std::replace(macro.begin(), macro.end(), '/', '_');
    std::replace(macro.begin(), macro.end(), '-', '_');
    std::replace(macro.begin(), macro.end(), '.', '_');
    std::replace(macro.begin(), macro.end(), ':', '_');
    std::transform(macro.begin(), macro.end(), macro.begin(), ::toupper);

    headerfile
        << "/*" << endl
        << " *     Copyright 2014 Couchbase, Inc" << endl
        << " *" << endl
        << " *   Licensed under the Apache License, Version 2.0 (the \"License\");" << endl
        << " *   you may not use this file except in compliance with the License." << endl
        << " *   You may obtain a copy of the License at" << endl
        << " *" << endl
        << " *       http://www.apache.org/licenses/LICENSE-2.0" << endl
        << " *" << endl
        << " *   Unless required by applicable law or agreed to in writing, software" << endl
        << " *   distributed under the License is distributed on an \"AS IS\" BASIS," << endl
        << " *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." << endl
        << " *   See the License for the specific language governing permissions and" << endl
        << " *   limitations under the License." << endl
        << " */" << endl
        << endl
        << "/********************************" << endl
        << "** Generated file, do not edit **" << endl
        << "*********************************/" << endl
        << "#ifndef " << macro << endl
        << "#define " << macro << endl
        << endl
        << "#include \"config.h\"" << endl
        << endl
        << "#ifdef __cplusplus" << endl
        << "extern \"C\" {" << endl
        << "#endif" << endl
        << endl
        << "const char *" << function << "(void);" << endl
        << endl
        << "#ifdef __cplusplus" << endl
        << "}" << endl
        << "#endif" << endl
        << "#endif  /* " << macro << "*/" << endl;
    headerfile.close();

    ofstream sourcefile(cfile);
    sourcefile
        << "/*" << endl
        << " *     Copyright 2014 Couchbase, Inc" << endl
        << " *" << endl
        << " *   Licensed under the Apache License, Version 2.0 (the \"License\");" << endl
        << " *   you may not use this file except in compliance with the License." << endl
        << " *   You may obtain a copy of the License at" << endl
        << " *" << endl
        << " *       http://www.apache.org/licenses/LICENSE-2.0" << endl
        << " *" << endl
        << " *   Unless required by applicable law or agreed to in writing, software" << endl
        << " *   distributed under the License is distributed on an \"AS IS\" BASIS," << endl
        << " *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." << endl
        << " *   See the License for the specific language governing permissions and" << endl
        << " *   limitations under the License." << endl
        << " */" << endl
        << endl
        << "/********************************" << endl
        << "** Generated file, do not edit **" << endl
        << "*********************************/" << endl
        << "#include \"config.h\"" << endl
        << "#include \"" << hfile << "\"" << endl
        << endl
        << "const char *" << function << "(void)" << endl
        << "{" << endl
        << "    return " << c << ";" << endl
        << "}" << endl;

    cJSON_Delete(c);

    return 0;
}
<|endoftext|>