<commit_before>
#ifdef _WIN32

#include "vtrc-asio.h"

#include "vtrc-application.h"
#include "vtrc-common/vtrc-enviroment.h"
#include "vtrc-common/vtrc-exception.h"
#include "vtrc-common/vtrc-transport-win-pipe.h"
#include "vtrc-common/vtrc-connection-list.h"

#include "vtrc-common/vtrc-protocol-accessor-iface.h"

#include "vtrc-rpc-lowlevel.pb.h"

#include "vtrc-connection-impl.h"

#include "vtrc-common/vtrc-closure.h"

namespace vtrc { namespace server { namespace listeners {

namespace {

    namespace basio = VTRC_ASIO;
    typedef basio::windows::stream_handle    socket_type;
    typedef common::transport_win_pipe       connection_type;
    typedef connection_impl<connection_type> connection_impl_type;

    typedef vtrc::server::connection_close_closure close_closure;

    struct commection_pipe_impl: public connection_impl_type {

        typedef commection_pipe_impl this_type;
        std::string name_;

        commection_pipe_impl( listener &listen,
                              vtrc::shared_ptr<socket_type> sock,
                              const close_closure &on_close_cb,
                              const std::string &name )
            :connection_impl_type(listen, sock, on_close_cb)
            ,name_(name)
        { }

        std::string name(  ) const
        {
            return name_;
        }

        bool is_local( ) const
        {
            return true;
        }

        static vtrc::shared_ptr<this_type> create( listener &listnr,
                                 vtrc::shared_ptr<socket_type> sock,
                                 const close_closure &on_close_cb,
                                 const std::string &name )
        {
            vtrc::shared_ptr<this_type> new_inst
                    (vtrc::make_shared<this_type>(vtrc::ref(listnr),
                                        sock,
                                        vtrc::ref(on_close_cb),
                                        vtrc::ref(name)));

            rpc::session_options const &opts(listnr.get_options( ));

            new_inst->protocol_.reset(
                    new protocol_layer_s( new_inst->app_,
                                            new_inst.get( ), opts ) );

            //new_inst->protocol_ ->init( );
            //new_inst->init( );
            return new_inst;
        }
    };

    typedef commection_pipe_impl transport_type;

    struct pipe_listener: public listener {

        typedef pipe_listener this_type;

        basio::io_service       &ios_;

        std::string              endpoint_;
        size_t                   pipe_max_inst_;
        size_t                   in_buf_size_;
        size_t                   out_buf_size_;

        basio::windows::overlapped_ptr overlapped_;
        bool                           working_;

        pipe_listener( application &app,
                const rpc::session_options &opts,
                const std::string &pipe_name,
                size_t max_inst)
            :listener(app, opts)
            ,ios_(app.get_io_service( ))
            ,endpoint_(pipe_name)
            ,pipe_max_inst_(max_inst)
            ,in_buf_size_(opts.read_buffer_size( ))
            ,out_buf_size_(opts.read_buffer_size( ))
            ,working_(false)
        { }

        virtual ~pipe_listener( ) { }

        void on_client_destroy( vtrc::weak_ptr<listener> inst,
                                common::connection_iface *conn )
        {
            vtrc::shared_ptr<listener> lock( inst.lock( ) );
            if( lock ) {
                this->stop_connection( conn );
            }
        }

        close_closure get_on_close_cb( )
        {
            return vtrc::bind( &this_type::on_client_destroy, this,
                                weak_from_this( ),
                                vtrc::placeholders::_1 );
        }

        std::string name( ) const
        {
            return std::string("pipe://") + endpoint_;
        }

        bool is_local( ) const
        {
            return true;
        }

        void start_accept( bool throw_if_fail )
        {
            if( !working_ ) return;

            SECURITY_DESCRIPTOR secdesc;
            SECURITY_ATTRIBUTES secarttr;
            InitializeSecurityDescriptor( &secdesc,
                                          SECURITY_DESCRIPTOR_REVISION );

            SetSecurityDescriptorDacl( &secdesc, TRUE,
                                       static_cast<PACL>(NULL), FALSE );

            secarttr.nLength              = sizeof(SECURITY_ATTRIBUTES);
            secarttr.bInheritHandle       = FALSE;
            secarttr.lpSecurityDescriptor = &secdesc;

            HANDLE pipe_hdl = CreateNamedPipeA( endpoint_.c_str( ),
                PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
                PIPE_TYPE_BYTE     | PIPE_READMODE_BYTE,
                pipe_max_inst_,
                out_buf_size_, in_buf_size_,
                0, &secarttr );

            if( INVALID_HANDLE_VALUE != pipe_hdl ) {

                vtrc::shared_ptr<socket_type> new_sock
                        (vtrc::make_shared<socket_type>(vtrc::ref(ios_)));
                new_sock->assign( pipe_hdl );

                overlapped_.reset( ios_,
                        vtrc::bind( &this_type::on_accept, this,
                            vtrc::placeholders::error, new_sock,
                            weak_from_this( ) ) );

                BOOL res = ConnectNamedPipe( pipe_hdl, overlapped_.get( ) );

                DWORD last_error( GetLastError( ) );

                if( res || ( last_error ==  ERROR_IO_PENDING ) ) {

                    overlapped_.release();

                } else if( last_error == ERROR_PIPE_CONNECTED ) {

                    bsys::error_code ec( 0,
                            basio::error::get_system_category( ));
                    overlapped_.complete( ec, 0 );

                } else {

                    bsys::error_code ec(last_error,
                                basio::error::get_system_category( ));

                    if( throw_if_fail ) {
                        vtrc::common::raise( bsys::system_error( ec ) );
                        return;
                    } else {
                        overlapped_.complete( ec, 0 );
                    }

                }
            } else {
                bsys::error_code ec( GetLastError( ),
                            basio::error::get_system_category( ));
                if( throw_if_fail ) {
                    vtrc::common::raise( bsys::system_error( ec ) );
                    return;
                } else {
                    overlapped_.complete( ec, 0 );
                }
            }
        }

        void start( )
        {
            working_ = true;
            start_accept( true );
            call_on_start( );
        }

        void stop ( )
        {
            working_ = false;
            bsys::error_code ec( ERROR_CANCELLED,
                        basio::error::get_system_category( ));
            overlapped_.complete( ec, 0 );
            call_on_stop( );
        }

        bool is_active( ) const
        {
            return working_;
        }

        void on_accept( const bsys::error_code &error,
                        vtrc::shared_ptr<socket_type> sock,
                        vtrc::weak_ptr<listener> &inst)
        {
            vtrc::shared_ptr<listener> locked( inst.lock( ));
            if( !locked ) {
                return;
            }

            if( !error ) {
                try {
                    vtrc::shared_ptr<transport_type> new_conn
                             (transport_type::create(
                                *this, sock, get_on_close_cb( ),
                                name( )));

                    namespace ph = vtrc::placeholders;

                    new_conn->get_protocol( )
                            .set_precall( vtrc::bind(
                                              &this_type::mk_precall, this,
                                               ph::_1, ph::_2, ph::_3 ) );
                    new_conn->get_protocol( )
                            .set_postcall( vtrc::bind(
                                              &this_type::mk_postcall, this,
                                               ph::_1, ph::_2 ) );

                    new_conn->get_protocol( )
                             .assign_lowlevel_factory(
                                lowlevel_protocol_factory( ) );

                    get_application( ).get_clients( )->store( new_conn );
                    new_connection( new_conn.get( ) );

                    //new_conn->init( );

                    get_application( ).get_io_service( )
                        .dispatch( vtrc::bind( &connection_type::init,
                                                new_conn ) );

                } catch( ... ) {
                    ;;;
                }
                start_accept( false );
            } else {
                if( working_ ) {
                    stop( );
                    call_on_accept_failed( error );
                } else {
                    call_on_stop( );
                }
            }
        }

    };
}

    namespace win_pipe {
        listener_sptr create( application &app,
                              const rpc::session_options &opts,
                              const std::string &name )
        {
            vtrc::shared_ptr<pipe_listener>new_l
                    (vtrc::make_shared<pipe_listener>(
                         vtrc::ref(app), vtrc::ref(opts),
                         vtrc::ref(name),
                         PIPE_UNLIMITED_INSTANCES));
            return new_l;
        }

        listener_sptr create( application &app, const std::string &name )
        {
            const rpc::session_options
                    def_opts( common::defaults::session_options( ) );

            return create( app, def_opts, name );
        }

        //endpoint_iface *create( application &app, const std::wstring &name )
        //{
        //
        //}
    }

}}}

#endif
<commit_msg>remove precall postcall;<commit_after>
#ifdef _WIN32

#include "vtrc-asio.h"

#include "vtrc-application.h"
#include "vtrc-common/vtrc-enviroment.h"
#include "vtrc-common/vtrc-exception.h"
#include "vtrc-common/vtrc-transport-win-pipe.h"
#include "vtrc-common/vtrc-connection-list.h"

#include "vtrc-common/vtrc-protocol-accessor-iface.h"

#include "vtrc-rpc-lowlevel.pb.h"

#include "vtrc-connection-impl.h"

#include "vtrc-common/vtrc-closure.h"

namespace vtrc { namespace server { namespace listeners {

namespace {

    namespace basio = VTRC_ASIO;
    typedef basio::windows::stream_handle    socket_type;
    typedef common::transport_win_pipe       connection_type;
    typedef connection_impl<connection_type> connection_impl_type;

    typedef vtrc::server::connection_close_closure close_closure;

    struct commection_pipe_impl: public connection_impl_type {

        typedef commection_pipe_impl this_type;
        std::string name_;

        commection_pipe_impl( listener &listen,
                              vtrc::shared_ptr<socket_type> sock,
                              const close_closure &on_close_cb,
                              const std::string &name )
            :connection_impl_type(listen, sock, on_close_cb)
            ,name_(name)
        { }

        std::string name(  ) const
        {
            return name_;
        }

        bool is_local( ) const
        {
            return true;
        }

        static vtrc::shared_ptr<this_type> create( listener &listnr,
                                 vtrc::shared_ptr<socket_type> sock,
                                 const close_closure &on_close_cb,
                                 const std::string &name )
        {
            vtrc::shared_ptr<this_type> new_inst
                    (vtrc::make_shared<this_type>(vtrc::ref(listnr),
                                        sock,
                                        vtrc::ref(on_close_cb),
                                        vtrc::ref(name)));

            rpc::session_options const &opts(listnr.get_options( ));

            new_inst->protocol_.reset(
                    new protocol_layer_s( new_inst->app_,
                                            new_inst.get( ), opts ) );

            //new_inst->protocol_ ->init( );
            //new_inst->init( );
            return new_inst;
        }
    };

    typedef commection_pipe_impl transport_type;

    struct pipe_listener: public listener {

        typedef pipe_listener this_type;

        basio::io_service       &ios_;

        std::string              endpoint_;
        size_t                   pipe_max_inst_;
        size_t                   in_buf_size_;
        size_t                   out_buf_size_;

        basio::windows::overlapped_ptr overlapped_;
        bool                           working_;

        pipe_listener( application &app,
                const rpc::session_options &opts,
                const std::string &pipe_name,
                size_t max_inst)
            :listener(app, opts)
            ,ios_(app.get_io_service( ))
            ,endpoint_(pipe_name)
            ,pipe_max_inst_(max_inst)
            ,in_buf_size_(opts.read_buffer_size( ))
            ,out_buf_size_(opts.read_buffer_size( ))
            ,working_(false)
        { }

        virtual ~pipe_listener( ) { }

        void on_client_destroy( vtrc::weak_ptr<listener> inst,
                                common::connection_iface *conn )
        {
            vtrc::shared_ptr<listener> lock( inst.lock( ) );
            if( lock ) {
                this->stop_connection( conn );
            }
        }

        close_closure get_on_close_cb( )
        {
            return vtrc::bind( &this_type::on_client_destroy, this,
                                weak_from_this( ),
                                vtrc::placeholders::_1 );
        }

        std::string name( ) const
        {
            return std::string("pipe://") + endpoint_;
        }

        bool is_local( ) const
        {
            return true;
        }

        void start_accept( bool throw_if_fail )
        {
            if( !working_ ) return;

            SECURITY_DESCRIPTOR secdesc;
            SECURITY_ATTRIBUTES secarttr;
            InitializeSecurityDescriptor( &secdesc,
                                          SECURITY_DESCRIPTOR_REVISION );

            SetSecurityDescriptorDacl( &secdesc, TRUE,
                                       static_cast<PACL>(NULL), FALSE );

            secarttr.nLength              = sizeof(SECURITY_ATTRIBUTES);
            secarttr.bInheritHandle       = FALSE;
            secarttr.lpSecurityDescriptor = &secdesc;

            HANDLE pipe_hdl = CreateNamedPipeA( endpoint_.c_str( ),
                PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
                PIPE_TYPE_BYTE     | PIPE_READMODE_BYTE,
                pipe_max_inst_,
                out_buf_size_, in_buf_size_,
                0, &secarttr );

            if( INVALID_HANDLE_VALUE != pipe_hdl ) {

                vtrc::shared_ptr<socket_type> new_sock
                        (vtrc::make_shared<socket_type>(vtrc::ref(ios_)));
                new_sock->assign( pipe_hdl );

                overlapped_.reset( ios_,
                        vtrc::bind( &this_type::on_accept, this,
                            vtrc::placeholders::error, new_sock,
                            weak_from_this( ) ) );

                BOOL res = ConnectNamedPipe( pipe_hdl, overlapped_.get( ) );

                DWORD last_error( GetLastError( ) );

                if( res || ( last_error ==  ERROR_IO_PENDING ) ) {

                    overlapped_.release();

                } else if( last_error == ERROR_PIPE_CONNECTED ) {

                    bsys::error_code ec( 0,
                            basio::error::get_system_category( ));
                    overlapped_.complete( ec, 0 );

                } else {

                    bsys::error_code ec(last_error,
                                basio::error::get_system_category( ));

                    if( throw_if_fail ) {
                        vtrc::common::raise( bsys::system_error( ec ) );
                        return;
                    } else {
                        overlapped_.complete( ec, 0 );
                    }

                }
            } else {
                bsys::error_code ec( GetLastError( ),
                            basio::error::get_system_category( ));
                if( throw_if_fail ) {
                    vtrc::common::raise( bsys::system_error( ec ) );
                    return;
                } else {
                    overlapped_.complete( ec, 0 );
                }
            }
        }

        void start( )
        {
            working_ = true;
            start_accept( true );
            call_on_start( );
        }

        void stop ( )
        {
            working_ = false;
            bsys::error_code ec( ERROR_CANCELLED,
                        basio::error::get_system_category( ));
            overlapped_.complete( ec, 0 );
            call_on_stop( );
        }

        bool is_active( ) const
        {
            return working_;
        }

        void on_accept( const bsys::error_code &error,
                        vtrc::shared_ptr<socket_type> sock,
                        vtrc::weak_ptr<listener> &inst)
        {
            vtrc::shared_ptr<listener> locked( inst.lock( ));
            if( !locked ) {
                return;
            }

            if( !error ) {
                try {
                    vtrc::shared_ptr<transport_type> new_conn
                             (transport_type::create(
                                *this, sock, get_on_close_cb( ),
                                name( )));

                    namespace ph = vtrc::placeholders;

                    new_conn->get_protocol( )
                             .assign_lowlevel_factory(
                                lowlevel_protocol_factory( ) );

                    get_application( ).get_clients( )->store( new_conn );
                    new_connection( new_conn.get( ) );

                    //new_conn->init( );

                    get_application( ).get_io_service( )
                        .dispatch( vtrc::bind( &connection_type::init,
                                                new_conn ) );

                } catch( ... ) {
                    ;;;
                }
                start_accept( false );
            } else {
                if( working_ ) {
                    stop( );
                    call_on_accept_failed( error );
                } else {
                    call_on_stop( );
                }
            }
        }

    };
}

    namespace win_pipe {
        listener_sptr create( application &app,
                              const rpc::session_options &opts,
                              const std::string &name )
        {
            vtrc::shared_ptr<pipe_listener>new_l
                    (vtrc::make_shared<pipe_listener>(
                         vtrc::ref(app), vtrc::ref(opts),
                         vtrc::ref(name),
                         PIPE_UNLIMITED_INSTANCES));
            return new_l;
        }

        listener_sptr create( application &app, const std::string &name )
        {
            const rpc::session_options
                    def_opts( common::defaults::session_options( ) );

            return create( app, def_opts, name );
        }

        //endpoint_iface *create( application &app, const std::wstring &name )
        //{
        //
        //}
    }

}}}

#endif
<|endoftext|>


<commit_before>#pragma once

#include <algorithm>   // fill
#include <cassert>
#include <functional>  // hash
#include <tuple>
#include <type_traits> // enable_if
#include <utility>     // make_pair, pair

#include "sdd/util/next_power.hh"
#include "sdd/util/packed.hh"

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief It must be stored by the hash table's data as a member named 'hook'.
template <typename Data>
struct intrusive_member_hook
{
  /// @brief Store the next data in a bucket.
  mutable Data* next = nullptr;
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief An intrusive hash table.
///
/// It's modeled after boost::intrusive. Only the interfaces needed by the libsdd are implemented.
/// It uses chaining to handle collisions.
template <typename Data, bool Rehash = true>
class hash_table
{
public:

  /// @brief Used by insert_check
  struct insert_commit_data
  {
    std::size_t hash;
  };

private:

  /// @brief
  std::size_t nb_buckets_;

  /// @brief
  std::size_t size_;

  /// @brief
  Data** buckets_;

  /// @brief The maximal allowed load factor.
  const double max_load_factor_;

  /// @brief The number of times this hash table has been rehashed.
  std::size_t nb_rehash_;

public:

  /// @brief Constructor
  hash_table(std::size_t size, double max_load_factor = 0.75)
    : nb_buckets_(util::next_power_of_2(size))
    , size_(0)
    , buckets_(new Data*[nb_buckets_])
    , max_load_factor_(max_load_factor)
    , nb_rehash_(0)
  {
    std::fill(buckets_, buckets_ + nb_buckets_, nullptr);
  }

  /// @brief Destructor
  ~hash_table()
  {
    delete[] buckets_;
  }

  /// @brief
  template <typename T, typename EqT>
  std::pair<Data*, bool>
  insert_check(const T& x, EqT eq, insert_commit_data& commit_data)
  const noexcept(noexcept(std::hash<T>()(x)))
  {
    commit_data.hash = std::hash<T>()(x);
    // same as commit_data.h % nb_buckets_, but much more efficient (works only with powers of 2)
    const std::size_t pos = commit_data.hash & (nb_buckets_ - 1);

    Data* current = buckets_[pos];
    bool insertion = true;
    while (current != nullptr)
    {
      if (eq(x, *current))
      {
        insertion = false;
        break;
      }
      current = current->hook.next;
    }

    return std::make_pair(current, insertion);
  }

  /// @brief
  void
  insert_commit(Data* x, const insert_commit_data& commit_data)
  noexcept(Rehash == false)
  {
    assert(x != nullptr);
    const std::size_t pos = commit_data.hash & (nb_buckets_ - 1);

    Data* previous = nullptr;
    Data* current = buckets_[pos];

    while (current != nullptr)
    {
      if (*x == *current)
      {
        return;
      }
      previous = current;
      current = current->hook.next;
    }

    if (previous != nullptr)
    {
      previous->hook.next = x;
    }
    else
    {
      buckets_[pos] = x;
    }

    ++size_;

    rehash<Rehash>();
  }

  /// @brief Insert an element.
  std::pair<Data*, bool>
  insert(Data* x)
  {
    auto res = insert_impl(x, buckets_, nb_buckets_);
    rehash<Rehash>();
    return res;
  }

  /// @brief Return the number of elements.
  std::size_t
  size()
  const noexcept
  {
    return size_;
  }

  /// @brief Return the number of buckets.
  std::size_t
  bucket_count()
  const noexcept
  {
    return nb_buckets_;
  }

  /// @brief Remove an element given its value.
  void
  erase(const Data* x)
  noexcept
  {
    const std::size_t pos = std::hash<Data>()(*x) & (nb_buckets_ - 1);
    Data* previous = nullptr;
    Data* current = buckets_[pos];
    while (current != nullptr)
    {
      if (*x == *current)
      {
        if (previous == nullptr) // first element in bucket
        {
          buckets_[pos] = current->hook.next;
        }
        else
        {
          previous->hook.next = current->hook.next;
        }
        --size_;
        return;
      }
      previous = current;
      current = current->hook.next;
    }
    assert(false && "Data to erase not found");
  }

  /// @brief Clear the whole table.
  template <typename Disposer>
  void
  clear_and_dispose(Disposer disposer)
  {
    for (std::size_t i = 0; i < nb_buckets_; ++i)
    {
      Data* current = buckets_[i];
      while (current != nullptr)
      {
        const auto to_erase = current;
        current = current->hook.next;
        disposer(to_erase);
      }
      buckets_[i] = nullptr;
    }
    size_ = 0;
  }

  /// @brief Get the load factor of the internal hash table.
  double
  load_factor()
  const noexcept
  {
    return static_cast<double>(size()) / static_cast<double>(bucket_count());
  }

  /// @brief The number of times this hash table has been rehashed.
  std::size_t
  nb_rehash()
  const noexcept
  {
    return nb_rehash_;
  }

  /// @brief The number of collisions.
  std::tuple<std::size_t /* collisions */, std::size_t /* alone */, std::size_t /* empty */>
  collisions()
  const noexcept
  {
    std::size_t col = 0;
    std::size_t alone = 0;
    std::size_t empty = 0;
    for (auto i = 0ul; i < nb_buckets_; ++i)
    {
      std::size_t nb = 0;
      auto current = buckets_[i];
      while (current != nullptr)
      {
        ++nb;
        current = current->hook.next;
      }
      if      (nb == 0) ++empty;
      else if (nb == 1) ++alone;
      else if (nb > 1)  ++col;
    }
    return {col, alone, empty};
  }

private:

  template<bool DoRehash>
  std::enable_if_t<DoRehash, void>
  rehash()
  {
    if (load_factor() < max_load_factor_) // no need to rehash
    {
      return;
    }
    ++nb_rehash_;
    auto new_nb_buckets = nb_buckets_ * 2;
    auto new_buckets = new Data*[new_nb_buckets];
    std::fill(new_buckets, new_buckets + new_nb_buckets, nullptr);
    size_ = 0;
    for (std::size_t i = 0; i < nb_buckets_; ++i)
    {
      Data* data_ptr = buckets_[i];
      while (data_ptr)
      {
        Data* next = data_ptr->hook.next;
        data_ptr->hook.next = nullptr;
        insert_impl(data_ptr, new_buckets, new_nb_buckets);
        data_ptr = next;
      }
      // else empty bucket
    }
    std::swap(new_buckets, buckets_);
    std::swap(new_nb_buckets, nb_buckets_);
    delete[] new_buckets;
  }

  template<bool DoRehash>
  std::enable_if_t<not DoRehash, void>
  rehash()
  noexcept
  {}

  /// @brief Insert an element.
  std::pair<Data*, bool>
  insert_impl(Data* x, Data** buckets, std::size_t nb_buckets)
  noexcept(noexcept(std::hash<Data>()(*x)))
  {
    const std::size_t pos = std::hash<Data>()(*x) & (nb_buckets - 1);

    Data* current = buckets[pos];

    while (current != nullptr)
    {
      if (*x == *current)
      {
        return {current, false /* no insertion */};
      }
      current = current->hook.next;
    }

    // Push in front of the list.
    x->hook.next = buckets[pos];
    buckets[pos] = x;

    current = x;
    ++size_;
    return {current, true /* insertion */};
  }
};

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem
<commit_msg>Compile with GCC 4.9<commit_after>#pragma once

#include <algorithm>   // fill
#include <cassert>
#include <functional>  // hash
#include <tuple>
#include <type_traits> // enable_if
#include <utility>     // make_pair, pair

#include "sdd/util/next_power.hh"
#include "sdd/util/packed.hh"

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief It must be stored by the hash table's data as a member named 'hook'.
template <typename Data>
struct intrusive_member_hook
{
  /// @brief Store the next data in a bucket.
  mutable Data* next = nullptr;
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief An intrusive hash table.
///
/// It's modeled after boost::intrusive. Only the interfaces needed by the libsdd are implemented.
/// It uses chaining to handle collisions.
template <typename Data, bool Rehash = true>
class hash_table
{
public:

  /// @brief Used by insert_check
  struct insert_commit_data
  {
    std::size_t hash;
  };

private:

  /// @brief
  std::size_t nb_buckets_;

  /// @brief
  std::size_t size_;

  /// @brief
  Data** buckets_;

  /// @brief The maximal allowed load factor.
  const double max_load_factor_;

  /// @brief The number of times this hash table has been rehashed.
  std::size_t nb_rehash_;

public:

  /// @brief Constructor
  hash_table(std::size_t size, double max_load_factor = 0.75)
    : nb_buckets_(util::next_power_of_2(size))
    , size_(0)
    , buckets_(new Data*[nb_buckets_])
    , max_load_factor_(max_load_factor)
    , nb_rehash_(0)
  {
    std::fill(buckets_, buckets_ + nb_buckets_, nullptr);
  }

  /// @brief Destructor
  ~hash_table()
  {
    delete[] buckets_;
  }

  /// @brief
  template <typename T, typename EqT>
  std::pair<Data*, bool>
  insert_check(const T& x, EqT eq, insert_commit_data& commit_data)
  const noexcept(noexcept(std::hash<T>()(x)))
  {
    commit_data.hash = std::hash<T>()(x);
    // same as commit_data.h % nb_buckets_, but much more efficient (works only with powers of 2)
    const std::size_t pos = commit_data.hash & (nb_buckets_ - 1);

    Data* current = buckets_[pos];
    bool insertion = true;
    while (current != nullptr)
    {
      if (eq(x, *current))
      {
        insertion = false;
        break;
      }
      current = current->hook.next;
    }

    return std::make_pair(current, insertion);
  }

  /// @brief
  void
  insert_commit(Data* x, const insert_commit_data& commit_data)
  noexcept(Rehash == false)
  {
    assert(x != nullptr);
    const std::size_t pos = commit_data.hash & (nb_buckets_ - 1);

    Data* previous = nullptr;
    Data* current = buckets_[pos];

    while (current != nullptr)
    {
      if (*x == *current)
      {
        return;
      }
      previous = current;
      current = current->hook.next;
    }

    if (previous != nullptr)
    {
      previous->hook.next = x;
    }
    else
    {
      buckets_[pos] = x;
    }

    ++size_;

    rehash<Rehash>();
  }

  /// @brief Insert an element.
  std::pair<Data*, bool>
  insert(Data* x)
  {
    auto res = insert_impl(x, buckets_, nb_buckets_);
    rehash<Rehash>();
    return res;
  }

  /// @brief Return the number of elements.
  std::size_t
  size()
  const noexcept
  {
    return size_;
  }

  /// @brief Return the number of buckets.
  std::size_t
  bucket_count()
  const noexcept
  {
    return nb_buckets_;
  }

  /// @brief Remove an element given its value.
  void
  erase(const Data* x)
  noexcept
  {
    const std::size_t pos = std::hash<Data>()(*x) & (nb_buckets_ - 1);
    Data* previous = nullptr;
    Data* current = buckets_[pos];
    while (current != nullptr)
    {
      if (*x == *current)
      {
        if (previous == nullptr) // first element in bucket
        {
          buckets_[pos] = current->hook.next;
        }
        else
        {
          previous->hook.next = current->hook.next;
        }
        --size_;
        return;
      }
      previous = current;
      current = current->hook.next;
    }
    assert(false && "Data to erase not found");
  }

  /// @brief Clear the whole table.
  template <typename Disposer>
  void
  clear_and_dispose(Disposer disposer)
  {
    for (std::size_t i = 0; i < nb_buckets_; ++i)
    {
      Data* current = buckets_[i];
      while (current != nullptr)
      {
        const auto to_erase = current;
        current = current->hook.next;
        disposer(to_erase);
      }
      buckets_[i] = nullptr;
    }
    size_ = 0;
  }

  /// @brief Get the load factor of the internal hash table.
  double
  load_factor()
  const noexcept
  {
    return static_cast<double>(size()) / static_cast<double>(bucket_count());
  }

  /// @brief The number of times this hash table has been rehashed.
  std::size_t
  nb_rehash()
  const noexcept
  {
    return nb_rehash_;
  }

  /// @brief The number of collisions.
  std::tuple<std::size_t /* collisions */, std::size_t /* alone */, std::size_t /* empty */>
  collisions()
  const noexcept
  {
    std::size_t col = 0;
    std::size_t alone = 0;
    std::size_t empty = 0;
    for (auto i = 0ul; i < nb_buckets_; ++i)
    {
      std::size_t nb = 0;
      auto current = buckets_[i];
      while (current != nullptr)
      {
        ++nb;
        current = current->hook.next;
      }
      if      (nb == 0) ++empty;
      else if (nb == 1) ++alone;
      else if (nb > 1)  ++col;
    }
    return std::make_tuple(col, alone, empty);
  }

private:

  template<bool DoRehash>
  std::enable_if_t<DoRehash, void>
  rehash()
  {
    if (load_factor() < max_load_factor_) // no need to rehash
    {
      return;
    }
    ++nb_rehash_;
    auto new_nb_buckets = nb_buckets_ * 2;
    auto new_buckets = new Data*[new_nb_buckets];
    std::fill(new_buckets, new_buckets + new_nb_buckets, nullptr);
    size_ = 0;
    for (std::size_t i = 0; i < nb_buckets_; ++i)
    {
      Data* data_ptr = buckets_[i];
      while (data_ptr)
      {
        Data* next = data_ptr->hook.next;
        data_ptr->hook.next = nullptr;
        insert_impl(data_ptr, new_buckets, new_nb_buckets);
        data_ptr = next;
      }
      // else empty bucket
    }
    std::swap(new_buckets, buckets_);
    std::swap(new_nb_buckets, nb_buckets_);
    delete[] new_buckets;
  }

  template<bool DoRehash>
  std::enable_if_t<not DoRehash, void>
  rehash()
  noexcept
  {}

  /// @brief Insert an element.
  std::pair<Data*, bool>
  insert_impl(Data* x, Data** buckets, std::size_t nb_buckets)
  noexcept(noexcept(std::hash<Data>()(*x)))
  {
    const std::size_t pos = std::hash<Data>()(*x) & (nb_buckets - 1);

    Data* current = buckets[pos];

    while (current != nullptr)
    {
      if (*x == *current)
      {
        return {current, false /* no insertion */};
      }
      current = current->hook.next;
    }

    // Push in front of the list.
    x->hook.next = buckets[pos];
    buckets[pos] = x;

    current = x;
    ++size_;
    return {current, true /* insertion */};
  }
};

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: XMLAutoMarkFileContext.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: dvo $ $Date: 2001-06-29 21:07:21 $
 *
 *  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 _XMLOFF_XMLAUTOMARKFILECONTEXT_HXX_
#include "XMLAutoMarkFileContext.hxx"
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef _COM_SUN_STAR_XML_SAX_XATTRIBUTELIST_HPP_
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

using ::rtl::OUString;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::beans::XPropertySet;

using ::xmloff::token::IsXMLToken;
using ::xmloff::token::XML_HREF;

TYPEINIT1( XMLAutoMarkFileContext, SvXMLImportContext );

XMLAutoMarkFileContext::XMLAutoMarkFileContext(
    SvXMLImport& rImport,
    sal_uInt16 nPrefix,
    const OUString& rLocalName) :
        SvXMLImportContext(rImport, nPrefix, rLocalName),
        sIndexAutoMarkFileURL(
            RTL_CONSTASCII_USTRINGPARAM("IndexAutoMarkFileURL"))
{
}

XMLAutoMarkFileContext::~XMLAutoMarkFileContext()
{
}

void XMLAutoMarkFileContext::StartElement(
    const Reference<XAttributeList> & xAttrList)
{
    // scan for text:alphabetical-index-auto-mark-file attribute, and if
    // found set value with the document

    sal_Int16 nLength = xAttrList->getLength();
    for( sal_Int16 i = 0; i < nLength; i++ )
    {
        OUString sLocalName;
        sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
            GetKeyByAttrName( xAttrList->getNameByIndex(i), &sLocalName );

        if ( ( XML_NAMESPACE_XLINK == nPrefix ) &&
             IsXMLToken(sLocalName, XML_HREF) )
        {
            Any aAny;
            aAny <<= GetImport().GetAbsoluteReference( xAttrList->getValueByIndex(i) );
            Reference<XPropertySet> xPropertySet(
                GetImport().GetModel(), UNO_QUERY );
            if (xPropertySet.is())
            {
                xPropertySet->setPropertyValue( sIndexAutoMarkFileURL, aAny );
            }
        }
    }
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.636); FILE MERGED 2005/09/05 14:39:41 rt 1.3.636.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLAutoMarkFileContext.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:56:07 $
 *
 *  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 _XMLOFF_XMLAUTOMARKFILECONTEXT_HXX_
#include "XMLAutoMarkFileContext.hxx"
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef _COM_SUN_STAR_XML_SAX_XATTRIBUTELIST_HPP_
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

using ::rtl::OUString;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::beans::XPropertySet;

using ::xmloff::token::IsXMLToken;
using ::xmloff::token::XML_HREF;

TYPEINIT1( XMLAutoMarkFileContext, SvXMLImportContext );

XMLAutoMarkFileContext::XMLAutoMarkFileContext(
    SvXMLImport& rImport,
    sal_uInt16 nPrefix,
    const OUString& rLocalName) :
        SvXMLImportContext(rImport, nPrefix, rLocalName),
        sIndexAutoMarkFileURL(
            RTL_CONSTASCII_USTRINGPARAM("IndexAutoMarkFileURL"))
{
}

XMLAutoMarkFileContext::~XMLAutoMarkFileContext()
{
}

void XMLAutoMarkFileContext::StartElement(
    const Reference<XAttributeList> & xAttrList)
{
    // scan for text:alphabetical-index-auto-mark-file attribute, and if
    // found set value with the document

    sal_Int16 nLength = xAttrList->getLength();
    for( sal_Int16 i = 0; i < nLength; i++ )
    {
        OUString sLocalName;
        sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
            GetKeyByAttrName( xAttrList->getNameByIndex(i), &sLocalName );

        if ( ( XML_NAMESPACE_XLINK == nPrefix ) &&
             IsXMLToken(sLocalName, XML_HREF) )
        {
            Any aAny;
            aAny <<= GetImport().GetAbsoluteReference( xAttrList->getValueByIndex(i) );
            Reference<XPropertySet> xPropertySet(
                GetImport().GetModel(), UNO_QUERY );
            if (xPropertySet.is())
            {
                xPropertySet->setPropertyValue( sIndexAutoMarkFileURL, aAny );
            }
        }
    }
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////
// This file is part of Grappa, a system for scaling irregular
// applications on commodity clusters.

// Copyright (C) 2010-2014 University of Washington and Battelle
// Memorial Institute. University of Washington authorizes use of this
// Grappa software.

// Grappa is free software: you can redistribute it and/or modify it
// under the terms of the Affero General Public License as published
// by Affero, Inc., either version 1 of the License, or (at your
// option) any later version.

// Grappa 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
// Affero General Public License for more details.

// You should have received a copy of the Affero General Public
// License along with this program. If not, you may obtain one from
// http://www.affero.org/oagpl.html.
////////////////////////////////////////////////////////////////////////
#include <gflags/gflags.h>
#include <glog/logging.h>

#include "stack.h"
#include "Worker.hpp"
#include "Scheduler.hpp"
#include "PerformanceTools.hpp"
#include <stdlib.h> // valloc
#include "LocaleSharedMemory.hpp"

DEFINE_int64( stack_size, MIN_STACK_SIZE, "Default stack size" );

namespace Grappa {
namespace impl {

/// list of all coroutines (used only for debugging)
Worker * all_coros = NULL;
/// total number of coroutines (used only for debugging)
size_t total_coros = 0;

DEFINE_int32( stack_offset, 64, "offset between coroutine stacks" );
size_t current_stack_offset = 0;

/// insert a coroutine into the list of all coroutines
/// (used only for debugging)
void insert_coro( Worker * c ) {
  // try to insert us in list going left
  if( all_coros ) {
    CHECK( all_coros->tracking_prev == NULL ) << "Head coroutine should not have a prev";
    all_coros->tracking_prev = c;
  }

  // insert us in list going right
  c->tracking_next = all_coros;
  all_coros = c;
}

/// remove a coroutine from the list of all coroutines
/// (used only for debugging)
void remove_coro( Worker * c ) {
  // is there something to our left?
  if( c->tracking_prev ) {
    // remove us from next list
    c->tracking_prev->tracking_next = c->tracking_next;
  }
  // is there something to our right?
  if( c->tracking_next ) {
    // remove us from next list
    c->tracking_next->tracking_prev = c->tracking_prev;
  }
}

#ifdef GRAPPA_TRACE
// keeps track of last id assigned
int thread_last_tau_taskid=0;
#endif

Worker * convert_to_master( Worker * me ) {
  if (!me) me = new Worker();

  me->running = 1;
  me->suspended = 0;
  me->idle = 0;

  // We don't need to free this (it's just the main stack segment)
  // so ignore it.
  me->base = NULL;
  // This'll get overridden when we swapstacks out of here.
  me->stack = NULL;

#ifdef ENABLE_VALGRIND
  me->valgrind_stack_id = -1;
#endif

  // debugging state
  me->tracking_prev = NULL;
  me->tracking_next = NULL;

  total_coros++;
  insert_coro( me ); // insert into debugging list of coros

  me->sched = NULL;
  me->next = NULL;
  me->id = 0; // master is id 0
  me->done = false;

#ifdef GRAPPA_TRACE
  master->tau_taskid=0;
#endif

#ifdef CORO_PROTECT_UNUSED_STACK
  // disable writes to stack until we're swtiched in again.
  //assert( 0 == mprotect( (void*)((intptr_t)me->base + 4096), ssize, PROT_READ ) );
  assert( 0 == mprotect( (void*)(me), 4096, PROT_READ ) );
#endif

  return me;
}

#include <errno.h>
void coro_spawn(Worker * me, Worker * c, coro_func f, size_t ssize) {
  CHECK(c != NULL) << "Must provide a valid Worker";
  c->running = 0;
  c->suspended = 0;
  c->idle = 0;

  // allocate stack and guard page
  c->base = Grappa::impl::locale_shared_memory.allocate_aligned( ssize+4096*2, 4096 );
  CHECK_NOTNULL( c->base );
  c->ssize = ssize;

  // set stack pointer
  c->stack = (char*) c->base + ssize + 4096 - current_stack_offset;

  // try to make sure we don't stuff all our stacks at the same cache index
  const int num_offsets = 128;
  const int cache_line_size = 64;
  current_stack_offset += FLAGS_stack_offset;
  current_stack_offset &= ((cache_line_size * num_offsets) - 1);

  c->tracking_prev = NULL;
  c->tracking_next = NULL;

#ifdef ENABLE_VALGRIND
  c->valgrind_stack_id = VALGRIND_STACK_REGISTER( (char *) c->base + 4096, c->stack );
#endif

  // clear stack
  memset(c->base, 0, ssize);

#ifdef GUARD_PAGES_ON_STACK
  // arm guard page
  checked_mprotect( c->base, 4096, PROT_NONE );
  checked_mprotect( (char*)c->base + ssize + 4096, 4096, PROT_NONE );
#endif

  // set up coroutine to be able to run next time we're switched in
  makestack(&me->stack, &c->stack, f, c);

  insert_coro( c ); // insert into debugging list of coros

#ifdef CORO_PROTECT_UNUSED_STACK
  // disable writes to stack until we're swtiched in again.
  checked_mprotect( (void*)((intptr_t)c->base + 4096), ssize, PROT_READ );
  checked_mprotect( (void*)(c), 4096, PROT_READ );
#endif

  total_coros++;
}

// TODO: refactor not to take <me> argument
Worker * worker_spawn(Worker * me, Scheduler * sched, thread_func f, void * arg) {
  CHECK( sched->get_current_thread() == me ) << "parent arg differs from current thread";

  // allocate the Worker and stack
  Worker * thr = new Worker( );
  thr->sched = sched;
  sched->assignTid( thr );

  coro_spawn(me, thr, tramp, FLAGS_stack_size);

  // Pass control to the trampoline a few times quickly to set up
  // the call of <f>.  Could also create a struct with all this data?

  coro_invoke(me, thr, (void *)me);
  coro_invoke(me, thr, thr);
  coro_invoke(me, thr, (void *)f);
  coro_invoke(me, thr, (void *)arg);

  return thr;
}

void destroy_coro(Worker * c) {
  total_coros--;
#ifdef ENABLE_VALGRIND
  if( c->valgrind_stack_id != -1 ) {
    VALGRIND_STACK_DEREGISTER( c->valgrind_stack_id );
  }
#endif
  if( c->base != NULL ) {
    // disarm guard page
    checked_mprotect( c->base, 4096, PROT_READ | PROT_WRITE );
    checked_mprotect( (char*)c->base + c->ssize + 4096, 4096, PROT_READ | PROT_WRITE );
#ifdef CORO_PROTECT_UNUSED_STACK
    // enable writes to stack so we can deallocate
    checked_mprotect( (void*)((intptr_t)c->base + 4096), c->ssize, PROT_READ | PROT_WRITE );
    checked_mprotect( (void*)(c), 4096, PROT_READ | PROT_WRITE );
#endif
    remove_coro(c); // remove from debugging list of coros
    Grappa::impl::locale_shared_memory.deallocate(c->base);
  }
}

void destroy_thread(Worker * thr) {
  destroy_coro(thr);
  free (thr);
}

void thread_exit(Worker * me, void * retval) {

  // Reuse the queue field for a return value.
  me->next = (Worker *)retval;

  // call master Worker
  me->sched->thread_on_exit();

  // never returns
  exit(EXIT_FAILURE);
}

void checked_mprotect( void *addr, size_t len, int prot ) {
  CHECK( 0 == mprotect( addr, len, prot ) )
    << "mprotect failed"
    << "; addr= "<< addr
    << "; len= " << len
    << "; errno=" << errno << "; "
    << ((errno == EINVAL) ? "errno==EINVAL (addr not a valid pointer or not a multiple of the system page size)"
    : (errno == ENOMEM) ? "errno==ENOMEM (internal kernel structures could not be allocated OR invalid addresses in range"
    : "(unrecognized)");
}

} // namespace impl
} // namespace Grappa
<commit_msg>make memory debugging easier by clearing full worker stacks and allocating work structs aligned to page boundaries<commit_after>////////////////////////////////////////////////////////////////////////
// This file is part of Grappa, a system for scaling irregular
// applications on commodity clusters.

// Copyright (C) 2010-2014 University of Washington and Battelle
// Memorial Institute. University of Washington authorizes use of this
// Grappa software.

// Grappa is free software: you can redistribute it and/or modify it
// under the terms of the Affero General Public License as published
// by Affero, Inc., either version 1 of the License, or (at your
// option) any later version.

// Grappa 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
// Affero General Public License for more details.

// You should have received a copy of the Affero General Public
// License along with this program. If not, you may obtain one from
// http://www.affero.org/oagpl.html.
////////////////////////////////////////////////////////////////////////
#include <gflags/gflags.h>
#include <glog/logging.h>

#include "stack.h"
#include "Worker.hpp"
#include "Scheduler.hpp"
#include "PerformanceTools.hpp"
#include <stdlib.h> // valloc
#include "LocaleSharedMemory.hpp"

DEFINE_int64( stack_size, MIN_STACK_SIZE, "Default stack size" );

namespace Grappa {
namespace impl {

/// list of all coroutines (used only for debugging)
Worker * all_coros = NULL;
/// total number of coroutines (used only for debugging)
size_t total_coros = 0;

DEFINE_int32( stack_offset, 64, "offset between coroutine stacks" );
size_t current_stack_offset = 0;

/// insert a coroutine into the list of all coroutines
/// (used only for debugging)
void insert_coro( Worker * c ) {
  // try to insert us in list going left
  if( all_coros ) {
    CHECK( all_coros->tracking_prev == NULL ) << "Head coroutine should not have a prev";
    all_coros->tracking_prev = c;
  }

  // insert us in list going right
  c->tracking_next = all_coros;
  all_coros = c;
}

/// remove a coroutine from the list of all coroutines
/// (used only for debugging)
void remove_coro( Worker * c ) {
  // is there something to our left?
  if( c->tracking_prev ) {
    // remove us from next list
    c->tracking_prev->tracking_next = c->tracking_next;
  }
  // is there something to our right?
  if( c->tracking_next ) {
    // remove us from next list
    c->tracking_next->tracking_prev = c->tracking_prev;
  }
}

#ifdef GRAPPA_TRACE
// keeps track of last id assigned
int thread_last_tau_taskid=0;
#endif

Worker * convert_to_master( Worker * me ) {
  if (!me) me = new Worker();

  me->running = 1;
  me->suspended = 0;
  me->idle = 0;

  // We don't need to free this (it's just the main stack segment)
  // so ignore it.
  me->base = NULL;
  // This'll get overridden when we swapstacks out of here.
  me->stack = NULL;

#ifdef ENABLE_VALGRIND
  me->valgrind_stack_id = -1;
#endif

  // debugging state
  me->tracking_prev = NULL;
  me->tracking_next = NULL;

  total_coros++;
  insert_coro( me ); // insert into debugging list of coros

  me->sched = NULL;
  me->next = NULL;
  me->id = 0; // master is id 0
  me->done = false;

#ifdef GRAPPA_TRACE
  master->tau_taskid=0;
#endif

#ifdef CORO_PROTECT_UNUSED_STACK
  // disable writes to stack until we're swtiched in again.
  //assert( 0 == mprotect( (void*)((intptr_t)me->base + 4096), ssize, PROT_READ ) );
  assert( 0 == mprotect( (void*)(me), 4096, PROT_READ ) );
#endif

  return me;
}

#include <errno.h>
void coro_spawn(Worker * me, Worker * c, coro_func f, size_t ssize) {
  CHECK(c != NULL) << "Must provide a valid Worker";
  c->running = 0;
  c->suspended = 0;
  c->idle = 0;

  // allocate stack and guard page
  c->base = Grappa::impl::locale_shared_memory.allocate_aligned( ssize+4096*2, 4096 );
  CHECK_NOTNULL( c->base );
  c->ssize = ssize;

  // set stack pointer
  c->stack = (char*) c->base + ssize + 4096 - current_stack_offset;

  // try to make sure we don't stuff all our stacks at the same cache index
  const int num_offsets = 128;
  const int cache_line_size = 64;
  current_stack_offset += FLAGS_stack_offset;
  current_stack_offset &= ((cache_line_size * num_offsets) - 1);

  c->tracking_prev = NULL;
  c->tracking_next = NULL;

#ifdef ENABLE_VALGRIND
  c->valgrind_stack_id = VALGRIND_STACK_REGISTER( (char *) c->base + 4096, c->stack );
#endif

  // clear stack
  memset(c->base, 0, ssize+4096*2);

#ifdef GUARD_PAGES_ON_STACK
  // arm guard page
  checked_mprotect( c->base, 4096, PROT_NONE );
  checked_mprotect( (char*)c->base + ssize + 4096, 4096, PROT_NONE );
#endif

  // set up coroutine to be able to run next time we're switched in
  makestack(&me->stack, &c->stack, f, c);

  insert_coro( c ); // insert into debugging list of coros

#ifdef CORO_PROTECT_UNUSED_STACK
  // disable writes to stack until we're swtiched in again.
  checked_mprotect( (void*)((intptr_t)c->base + 4096), ssize, PROT_READ );
  checked_mprotect( (void*)(c), 4096, PROT_READ );
#endif

  total_coros++;
}

// TODO: refactor not to take <me> argument
Worker * worker_spawn(Worker * me, Scheduler * sched, thread_func f, void * arg) {
  CHECK( sched->get_current_thread() == me ) << "parent arg differs from current thread";

  // allocate the Worker and stack
  Worker * thr = nullptr;
  posix_memalign( reinterpret_cast<void**>( &thr ), 4096, sizeof(Worker) );
  thr->sched = sched;
  sched->assignTid( thr );

  coro_spawn(me, thr, tramp, FLAGS_stack_size);

  // Pass control to the trampoline a few times quickly to set up
  // the call of <f>.  Could also create a struct with all this data?

  coro_invoke(me, thr, (void *)me);
  coro_invoke(me, thr, thr);
  coro_invoke(me, thr, (void *)f);
  coro_invoke(me, thr, (void *)arg);

  return thr;
}

void destroy_coro(Worker * c) {
  total_coros--;
#ifdef ENABLE_VALGRIND
  if( c->valgrind_stack_id != -1 ) {
    VALGRIND_STACK_DEREGISTER( c->valgrind_stack_id );
  }
#endif
  if( c->base != NULL ) {
    // disarm guard page
    checked_mprotect( c->base, 4096, PROT_READ | PROT_WRITE );
    checked_mprotect( (char*)c->base + c->ssize + 4096, 4096, PROT_READ | PROT_WRITE );
#ifdef CORO_PROTECT_UNUSED_STACK
    // enable writes to stack so we can deallocate
    checked_mprotect( (void*)((intptr_t)c->base + 4096), c->ssize, PROT_READ | PROT_WRITE );
    checked_mprotect( (void*)(c), 4096, PROT_READ | PROT_WRITE );
#endif
    remove_coro(c); // remove from debugging list of coros
    Grappa::impl::locale_shared_memory.deallocate(c->base);
  }
}

void destroy_thread(Worker * thr) {
  destroy_coro(thr);
  free (thr);
}

void thread_exit(Worker * me, void * retval) {

  // Reuse the queue field for a return value.
  me->next = (Worker *)retval;

  // call master Worker
  me->sched->thread_on_exit();

  // never returns
  exit(EXIT_FAILURE);
}

void checked_mprotect( void *addr, size_t len, int prot ) {
  CHECK( 0 == mprotect( addr, len, prot ) )
    << "mprotect failed"
    << "; addr= "<< addr
    << "; len= " << len
    << "; errno=" << errno << "; "
    << ((errno == EINVAL) ? "errno==EINVAL (addr not a valid pointer or not a multiple of the system page size)"
    : (errno == ENOMEM) ? "errno==ENOMEM (internal kernel structures could not be allocated OR invalid addresses in range"
    : "(unrecognized)");
}

} // namespace impl
} // namespace Grappa
<|endoftext|>


<commit_before>static int fuzzEncoderWithStringFilename(const std::string encoder, const uint8_t *Data, size_t Size)
{
  // Allow a bit extra to make sure we do proper bounds checking in Magick++
  if (Size > MagickPathExtent)
    return 0;
  std::string color(reinterpret_cast<const char*>(Data), Size);

  Magick::Image image;
  try {
    image.read(encoder + ":" + color);
  }
  catch (Magick::Exception &e) {
  }
  return 0;
}<commit_msg>Renamed variable.<commit_after>static int fuzzEncoderWithStringFilename(const std::string encoder, const uint8_t *Data, size_t Size)
{
  // Allow a bit extra to make sure we do proper bounds checking in Magick++
  if (Size > MagickPathExtent)
    return 0;

  std::string fileName(reinterpret_cast<const char*>(Data), Size);

  Magick::Image image;
  try {
    image.read(encoder + ":" + fileName);
  }
  catch (Magick::Exception &e) {
  }
  return 0;
}<|endoftext|>


<commit_before>#include "np-divs/np_divs.hpp"

// most code templated, so it's in the header
<commit_msg>add explicit instantiations of the np_divs overrides for float and double<commit_after>#include "np-divs/np_divs.hpp"

namespace NPDivs{

// explicit instantiations for np_divs() overloads with doubles

template void np_divs(
    const flann::Matrix<double> *bags, size_t num_bags,
    flann::Matrix<double> *results,
    int k,
    const flann::IndexParams &index_params,
    const flann::SearchParams &search_params,
    size_t num_threads,
    bool verify_results_alloced);

template void np_divs(
    const flann::Matrix<double> *bags, size_t num_bags,
    const boost::ptr_vector<DivFunc> &div_funcs,
    flann::Matrix<double> *results,
    int k,
    const flann::IndexParams &index_params,
    const flann::SearchParams &search_params,
    size_t num_threads,
    bool verify_results_alloced);

template void np_divs(
    const flann::Matrix<double> *x_bags, size_t num_x,
    const flann::Matrix<double> *y_bags, size_t num_y,
    flann::Matrix<double>* results,
    int k,
    const flann::IndexParams &index_params,
    const flann::SearchParams &search_params,
    size_t num_threads,
    bool verify_results_alloced);

template void np_divs(
    const flann::Matrix<double> *x_bags, size_t num_x,
    const flann::Matrix<double> *y_bags, size_t num_y,
    const boost::ptr_vector<DivFunc> &div_funcs,
    flann::Matrix<double>* results,
    int k,
    const flann::IndexParams &index_params,
    const flann::SearchParams &search_params,
    size_t num_threads,
    bool verify_results_alloced);

// explicit instantiations for np_divs() overloads with floats

template void np_divs(
    const flann::Matrix<float> *bags, size_t num_bags,
    flann::Matrix<double> *results,
    int k,
    const flann::IndexParams &index_params,
    const flann::SearchParams &search_params,
    size_t num_threads,
    bool verify_results_alloced);

template void np_divs(
    const flann::Matrix<float> *bags, size_t num_bags,
    const boost::ptr_vector<DivFunc> &div_funcs,
    flann::Matrix<double> *results,
    int k,
    const flann::IndexParams &index_params,
    const flann::SearchParams &search_params,
    size_t num_threads,
    bool verify_results_alloced);

template void np_divs(
    const flann::Matrix<float> *x_bags, size_t num_x,
    const flann::Matrix<float> *y_bags, size_t num_y,
    flann::Matrix<double>* results,
    int k,
    const flann::IndexParams &index_params,
    const flann::SearchParams &search_params,
    size_t num_threads,
    bool verify_results_alloced);

template void np_divs(
    const flann::Matrix<float> *x_bags, size_t num_x,
    const flann::Matrix<float> *y_bags, size_t num_y,
    const boost::ptr_vector<DivFunc> &div_funcs,
    flann::Matrix<double>* results,
    int k,
    const flann::IndexParams &index_params,
    const flann::SearchParams &search_params,
    size_t num_threads,
    bool verify_results_alloced);

} // end namespace
<|endoftext|>


<commit_before>#include "sampler.h"

#include "phrase_location.h"
#include "suffix_array.h"

namespace extractor {

Sampler::Sampler(shared_ptr<SuffixArray> suffix_array, int max_samples) :
    suffix_array(suffix_array), max_samples(max_samples) {}

Sampler::Sampler() {}

Sampler::~Sampler() {}

PhraseLocation Sampler::Sample(const PhraseLocation& location, unordered_set<int> blacklisted_sentence_ids, const shared_ptr<DataArray> source_data_array) const {
  vector<int> sample;
  int num_subpatterns;
  if (location.matchings == NULL) {
    // Sample suffix array range.
    num_subpatterns = 1;
    int low = location.sa_low, high = location.sa_high;
    double step = Round(max(1.0, (double) (high - low) / max_samples));
    int i = location.sa_low;
    bool found = false;
    while (sample.size() < max_samples && i <= location.sa_high) {
      int x = suffix_array->GetSuffix(i);
      int id = source_data_array->GetSentenceId(x);
      if (find(blacklisted_sentence_ids.begin(), blacklisted_sentence_ids.end(), id) != blacklisted_sentence_ids.end()) {
        int backoff_step = 1;
        while (true) {
          int j = i - backoff_step;
          x = suffix_array->GetSuffix(j);
          id = source_data_array->GetSentenceId(x);
          if ((j >= location.sa_low) && (find(blacklisted_sentence_ids.begin(), blacklisted_sentence_ids.end(), id) == blacklisted_sentence_ids.end())
              && (find(sample.begin(), sample.end(), x) == sample.end())) { found = true; break; }
          int k = i + backoff_step;
          x = suffix_array->GetSuffix(k);
          id = source_data_array->GetSentenceId(x);
          if ((k <= location.sa_high) && (find(blacklisted_sentence_ids.begin(), blacklisted_sentence_ids.end(), id) == blacklisted_sentence_ids.end())
              && (find(sample.begin(), sample.end(), x) == sample.end())) { found = true; break; }
          if (j <= location.sa_low && k >= location.sa_high) break;
          backoff_step++;
        }
      } else {
        found = true;
      }
      if (found && (find(sample.begin(), sample.end(), x) == sample.end())) sample.push_back(x);
      i += step;
      found = false;
    }
  } else { // when do we get here?
    // Sample vector of occurrences.
    num_subpatterns = location.num_subpatterns;
    int num_matchings = location.matchings->size() / num_subpatterns;
    double step = max(1.0, (double) num_matchings / max_samples);
    for (double i = 0, num_samples = 0;
         i < num_matchings && num_samples < max_samples;
         i += step, ++num_samples) {
      int start = Round(i) * num_subpatterns;
      sample.insert(sample.end(), location.matchings->begin() + start,
          location.matchings->begin() + start + num_subpatterns);
    }
  }
  return PhraseLocation(sample, num_subpatterns);
}

int Sampler::Round(double x) const {
  return x + 0.5;
}

} // namespace extractor
<commit_msg>loo #2<commit_after>#include "sampler.h"

#include "phrase_location.h"
#include "suffix_array.h"

namespace extractor {

Sampler::Sampler(shared_ptr<SuffixArray> suffix_array, int max_samples) :
    suffix_array(suffix_array), max_samples(max_samples) {}

Sampler::Sampler() {}

Sampler::~Sampler() {}

PhraseLocation Sampler::Sample(const PhraseLocation& location, unordered_set<int> blacklisted_sentence_ids, const shared_ptr<DataArray> source_data_array) const {
  vector<int> sample;
  int num_subpatterns;
  if (location.matchings == NULL) {
    // Sample suffix array range.
    num_subpatterns = 1;
    int low = location.sa_low, high = location.sa_high;
    double step = Round(max(1.0, (double) (high - low) / max_samples));
    int i = low, last = i;
    bool found;
    while (sample.size() < max_samples && i < high) {
      int x = suffix_array->GetSuffix(i);
      int id = source_data_array->GetSentenceId(x);
      if (find(blacklisted_sentence_ids.begin(), blacklisted_sentence_ids.end(), id) != blacklisted_sentence_ids.end()) {
        found = false;
        int backoff_step = 1;
        while (true) {
          if ((double)backoff_step >= step) break;
          int j = i - backoff_step;
          x = suffix_array->GetSuffix(j);
          id = source_data_array->GetSentenceId(x);
          if (j > last && find(blacklisted_sentence_ids.begin(), blacklisted_sentence_ids.end(), id) == blacklisted_sentence_ids.end()) {
            found = true; last = i; break;
          }
          int k = i + backoff_step;
          x = suffix_array->GetSuffix(k);
          id = source_data_array->GetSentenceId(x);
          if (k < min(i+step, (double)high) && find(blacklisted_sentence_ids.begin(), blacklisted_sentence_ids.end(), id) == blacklisted_sentence_ids.end()) {
            found = true; last = k; break;
          }
          if (j <= last && k >= high) break;
          backoff_step++;
        }
      } else {
        found = true;
        last = i;
      }
      if (found) sample.push_back(x);
      i += step;
    }
  } else {
    // Sample vector of occurrences.
    num_subpatterns = location.num_subpatterns;
    int num_matchings = location.matchings->size() / num_subpatterns;
    double step = max(1.0, (double) num_matchings / max_samples);
    for (double i = 0, num_samples = 0;
         i < num_matchings && num_samples < max_samples;
         i += step, ++num_samples) {
      int start = Round(i) * num_subpatterns;
      sample.insert(sample.end(), location.matchings->begin() + start,
          location.matchings->begin() + start + num_subpatterns);
    }
  }
  return PhraseLocation(sample, num_subpatterns);
}

int Sampler::Round(double x) const {
  return x + 0.5;
}

} // namespace extractor
<|endoftext|>


<commit_before>//
// Created by piotrek on 16.10.16.
//

#include <sstream>
#include "Selector.hpp"

const std::string CSSP::AST::Selector::debugString() const {
    std::stringstream stream;
    if (this->getToken().isWhitespacePrefixed()) {
        stream << " ";
    }
    stream << this->getSelectorPrefix() << this->name;
    if (this->value != nullptr) {
        stream << "=" << value->debugString();
    }
    if (this->type == SelectorType::ATTRIBUTE || this->type == SelectorType::ATTRIBUTE_VALUE) {
        stream << "]";
    };
    return stream.str();
}

const std::string CSSP::AST::Selector::generate(CSSP::Generator *generator) const {
    std::stringstream stream;
    if (this->getToken().isWhitespacePrefixed()) {
        stream << " ";
    }
    stream << this->getSelectorPrefix() << this->name;
    if (this->value != nullptr) {
        stream << "=" << value->generate(generator);
    }
    if (this->type == SelectorType::ATTRIBUTE || this->type == SelectorType::ATTRIBUTE_VALUE) {
        stream << "]";
    };
    return stream.str();
}

std::string CSSP::AST::Selector::getSelectorType() const {
    return (this->selectorToStringMap.at(this->type)).first;
}

std::string CSSP::AST::Selector::getSelectorPrefix() const {
    return (this->selectorToStringMap.at(this->type)).second;
}
<commit_msg>block with variables<commit_after>//
// Created by piotrek on 16.10.16.
//

#include <sstream>
#include "Selector.hpp"

const std::string CSSP::AST::Selector::debugString() const {
    std::stringstream stream;
    if (this->getToken().isWhitespacePrefixed()) {
        stream << " ";
    }
    stream << this->getSelectorPrefix() << this->name;
    if (this->value != nullptr) {
        stream << "=" << value->debugString();
    }
    if (this->type == SelectorType::ATTRIBUTE || this->type == SelectorType::ATTRIBUTE_VALUE) {
        stream << "]";
    };
    return stream.str();
}

const std::string CSSP::AST::Selector::generate(CSSP::Generator *generator) const {
    std::stringstream stream;
    if (this->getToken().isWhitespacePrefixed()) {
        stream << " ";
    }
    stream << this->getSelectorPrefix();
    if (this->variable != nullptr) {
        stream << this->variable->generate(generator);
    } else {
        stream << this->name;
    }

    if (this->value != nullptr) {
        stream << "=" << value->generate(generator);
    }
    if (this->type == SelectorType::ATTRIBUTE || this->type == SelectorType::ATTRIBUTE_VALUE) {
        stream << "]";
    }
    return stream.str();
}

std::string CSSP::AST::Selector::getSelectorType() const {
    return (this->selectorToStringMap.at(this->type)).first;
}

std::string CSSP::AST::Selector::getSelectorPrefix() const {
    return (this->selectorToStringMap.at(this->type)).second;
}
<|endoftext|>


<commit_before>AliAnalysisTaskSEImpParRes *AddTaskImpParRes(Bool_t readMC=kFALSE,Int_t selPdg=-1,Bool_t diamond=kTRUE)
{
  //
  // Configuration for the study of the impact parameter resolution
  //
  // xianbao.yuan@pd.infn.it, andrea.dainese@pd.infn.it
  //

  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskImpParRes", "No analysis manager to connect to.");
    return NULL;
  }

  // Aanalysis task
  AliAnalysisTaskSEImpParRes *d0ResTask = new AliAnalysisTaskSEImpParRes("d0ResAnalysis");
  d0ResTask->SetDebugLevel(2);
  d0ResTask->SetReadMC(readMC);
  d0ResTask->SetSelectedPdg(selPdg);
  d0ResTask->SetUseDiamond(diamond);
  mgr->AddTask(d0ResTask);

  //
  // Create containers for input/output
  AliAnalysisDataContainer *cinputd0distr = mgr->CreateContainer("cinputd0distr",TChain::Class(),
								 AliAnalysisManager::kInputContainer);

  AliAnalysisDataContainer *coutputd0ITSpureSARec = mgr->CreateContainer("coutputd0ITSpureSARec",TList::Class(),
								   AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0ITSpureSASkip = mgr->CreateContainer("coutputd0ITSpureSASkip",TList::Class(),
								   AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0allPointRec = mgr->CreateContainer("coutputd0allPointRec",TList::Class(),
								   AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0allPointSkip = mgr->CreateContainer("coutputd0allPointSkip",TList::Class(),
								   AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0partPointRec = mgr->CreateContainer("coutputd0partPointRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0partPointSkip = mgr->CreateContainer("coutputd0partPointSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0onepointSPDRec = mgr->CreateContainer("coutputd0onepointSPDRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0onepointSPDSkip = mgr->CreateContainer("coutputd0onepointSPDSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0postvTracRec = mgr->CreateContainer("coutputd0postvTracRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0postvTracSkip = mgr->CreateContainer("coutputd0postvTracSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0negtvTracRec = mgr->CreateContainer("coutputd0negtvTracRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0negtvTracSkip = mgr->CreateContainer("coutputd0negtvTracSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0pullAllpointRec = mgr->CreateContainer("coutputd0pullAllpointRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0pullAllpointSkip = mgr->CreateContainer("coutputd0pullAllpointSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0onlyRefitRec = mgr->CreateContainer("coutputd0onlyRefitRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0onlyRefitSkip = mgr->CreateContainer("coutputd0onlyRefitSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0Pt = mgr->CreateContainer("coutputd0Pt",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputNentries = mgr->CreateContainer("coutputNentries",TH1F::Class(),
								     AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputEstimVtx = mgr->CreateContainer("coutputEstimVtx",TH1F::Class(),
								     AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  mgr->ConnectInput(d0ResTask,0,mgr->GetCommonInputContainer());
  //mgr->ConnectOutput(d0ResTask,0,mgr->GetCommonOutputContainer());
  mgr->ConnectOutput(d0ResTask,1,coutputd0ITSpureSARec);
  mgr->ConnectOutput(d0ResTask,2,coutputd0ITSpureSASkip);
  mgr->ConnectOutput(d0ResTask,3,coutputd0allPointRec);
  mgr->ConnectOutput(d0ResTask,4,coutputd0allPointSkip);
  mgr->ConnectOutput(d0ResTask,5,coutputd0partPointRec);
  mgr->ConnectOutput(d0ResTask,6,coutputd0partPointSkip);
  mgr->ConnectOutput(d0ResTask,7,coutputd0onepointSPDRec);
  mgr->ConnectOutput(d0ResTask,8,coutputd0onepointSPDSkip);
  mgr->ConnectOutput(d0ResTask,9,coutputd0postvTracRec);
  mgr->ConnectOutput(d0ResTask,10,coutputd0postvTracSkip);
  mgr->ConnectOutput(d0ResTask,11,coutputd0negtvTracRec);
  mgr->ConnectOutput(d0ResTask,12,coutputd0negtvTracSkip);
  mgr->ConnectOutput(d0ResTask,13,coutputd0pullAllpointRec);
  mgr->ConnectOutput(d0ResTask,14,coutputd0pullAllpointSkip);
  mgr->ConnectOutput(d0ResTask,15,coutputd0onlyRefitRec);
  mgr->ConnectOutput(d0ResTask,16,coutputd0onlyRefitSkip);
  mgr->ConnectOutput(d0ResTask,17,coutputd0Pt);
  mgr->ConnectOutput(d0ResTask,18,coutputNentries);
  mgr->ConnectOutput(d0ResTask,19,coutputEstimVtx);

  return d0ResTask;
}
<commit_msg>Added output containers for theta-dep histograms<commit_after>AliAnalysisTaskSEImpParRes *AddTaskImpParRes(Bool_t readMC=kFALSE,Int_t selPdg=-1,Bool_t diamond=kTRUE)
{
  //
  // Configuration for the study of the impact parameter resolution
  //
  // xianbao.yuan@pd.infn.it, andrea.dainese@pd.infn.it
  //

  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskImpParRes", "No analysis manager to connect to.");
    return NULL;
  }

  // Aanalysis task
  AliAnalysisTaskSEImpParRes *d0ResTask = new AliAnalysisTaskSEImpParRes("d0ResAnalysis");
  d0ResTask->SetDebugLevel(2);
  d0ResTask->SetReadMC(readMC);
  d0ResTask->SetSelectedPdg(selPdg);
  d0ResTask->SetUseDiamond(diamond);
  mgr->AddTask(d0ResTask);

  //
  // Create containers for input/output
  AliAnalysisDataContainer *cinputd0distr = mgr->CreateContainer("cinputd0distr",TChain::Class(),
								 AliAnalysisManager::kInputContainer);

  AliAnalysisDataContainer *coutputd0ITSpureSARec = mgr->CreateContainer("coutputd0ITSpureSARec",TList::Class(),
								   AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0ITSpureSASkip = mgr->CreateContainer("coutputd0ITSpureSASkip",TList::Class(),
								   AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0allPointRec = mgr->CreateContainer("coutputd0allPointRec",TList::Class(),
								   AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0allPointSkip = mgr->CreateContainer("coutputd0allPointSkip",TList::Class(),
								   AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0partPointRec = mgr->CreateContainer("coutputd0partPointRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0partPointSkip = mgr->CreateContainer("coutputd0partPointSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0onepointSPDRec = mgr->CreateContainer("coutputd0onepointSPDRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0onepointSPDSkip = mgr->CreateContainer("coutputd0onepointSPDSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0postvTracRec = mgr->CreateContainer("coutputd0postvTracRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0postvTracSkip = mgr->CreateContainer("coutputd0postvTracSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0negtvTracRec = mgr->CreateContainer("coutputd0negtvTracRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0negtvTracSkip = mgr->CreateContainer("coutputd0negtvTracSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0pullAllpointRec = mgr->CreateContainer("coutputd0pullAllpointRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0pullAllpointSkip = mgr->CreateContainer("coutputd0pullAllpointSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0onlyRefitRec = mgr->CreateContainer("coutputd0onlyRefitRec",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0onlyRefitSkip = mgr->CreateContainer("coutputd0onlyRefitSkip",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0sinThetaRec = mgr->CreateContainer("coutputd0sinThetaRec",TList::Class(),
 									AliAnalysisManager::kOutputContainer,
 									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0sinThetaSkip = mgr->CreateContainer("coutputd0sinThetaSkip",TList::Class(),
									 AliAnalysisManager::kOutputContainer,
									 "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputd0Pt = mgr->CreateContainer("coutputd0Pt",TList::Class(),
									AliAnalysisManager::kOutputContainer,
									"ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputNentries = mgr->CreateContainer("coutputNentries",TH1F::Class(),
								     AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  AliAnalysisDataContainer *coutputEstimVtx = mgr->CreateContainer("coutputEstimVtx",TH1F::Class(),
								     AliAnalysisManager::kOutputContainer,
								   "ImpParRes.Performance.root");

  mgr->ConnectInput(d0ResTask,0,mgr->GetCommonInputContainer());
  //mgr->ConnectOutput(d0ResTask,0,mgr->GetCommonOutputContainer());
  mgr->ConnectOutput(d0ResTask,1,coutputd0ITSpureSARec);
  mgr->ConnectOutput(d0ResTask,2,coutputd0ITSpureSASkip);
  mgr->ConnectOutput(d0ResTask,3,coutputd0allPointRec);
  mgr->ConnectOutput(d0ResTask,4,coutputd0allPointSkip);
  mgr->ConnectOutput(d0ResTask,5,coutputd0partPointRec);
  mgr->ConnectOutput(d0ResTask,6,coutputd0partPointSkip);
  mgr->ConnectOutput(d0ResTask,7,coutputd0onepointSPDRec);
  mgr->ConnectOutput(d0ResTask,8,coutputd0onepointSPDSkip);
  mgr->ConnectOutput(d0ResTask,9,coutputd0postvTracRec);
  mgr->ConnectOutput(d0ResTask,10,coutputd0postvTracSkip);
  mgr->ConnectOutput(d0ResTask,11,coutputd0negtvTracRec);
  mgr->ConnectOutput(d0ResTask,12,coutputd0negtvTracSkip);
  mgr->ConnectOutput(d0ResTask,13,coutputd0pullAllpointRec);
  mgr->ConnectOutput(d0ResTask,14,coutputd0pullAllpointSkip);
  mgr->ConnectOutput(d0ResTask,15,coutputd0onlyRefitRec);
  mgr->ConnectOutput(d0ResTask,16,coutputd0onlyRefitSkip);
  mgr->ConnectOutput(d0ResTask,17,coutputd0sinThetaRec);
  mgr->ConnectOutput(d0ResTask,18,coutputd0sinThetaSkip);
  mgr->ConnectOutput(d0ResTask,19,coutputd0Pt);
  mgr->ConnectOutput(d0ResTask,20,coutputNentries);
  mgr->ConnectOutput(d0ResTask,21,coutputEstimVtx);

  return d0ResTask;
}
<|endoftext|>