<commit_before>// @(#)root/meta:$Id$
// Author: Markus Frank 20/05/2005

/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/

#include "TClass.h"
#include "TError.h"
#include "TInterpreter.h"
#include "TIsAProxy.h"

#include <map>

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TClass                                                               //
//                                                                      //
// TIsAProxy implementation class.                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

namespace {
   struct DynamicType {
      // Helper class to enable typeid on any address
      // Used in code similar to:
      //    typeid( * (DynamicType*) void_ptr );
      virtual ~DynamicType() {}
   };
}

typedef std::map<long, TClass*> ClassMap_t; // Internal type map
inline ClassMap_t *GetMap(void* p)
{
   return (ClassMap_t*)p;
}

//______________________________________________________________________________
TIsAProxy::TIsAProxy(const std::type_info& typ, void* ctxt)
   : fType(&typ), fLastType(&typ), fClass(0), fLastClass(0),
     fVirtual(false), fContext(ctxt), fInit(false)
{
   // Standard initializing constructor

   ::new(fSubTypes) ClassMap_t();
   if ( sizeof(ClassMap_t) > sizeof(fSubTypes) ) {
      Fatal("TIsAProxy::TIsAProxy",
         "Classmap size is badly adjusted: it needs %d instead of %d bytes.",
         sizeof(ClassMap_t), sizeof(fSubTypes));
   }
}

//______________________________________________________________________________
TIsAProxy::TIsAProxy(const TIsAProxy& iap) :
  TVirtualIsAProxy(iap),
  fType(iap.fType),
  fLastType(iap.fLastType),
  fClass(iap.fClass),
  fLastClass(iap.fLastClass),
  fVirtual(iap.fVirtual),
  fContext(iap.fContext),
  fInit(iap.fInit)
{
   //copy constructor
   for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
}

//______________________________________________________________________________
TIsAProxy& TIsAProxy::operator=(const TIsAProxy& iap)
{
   //assignement operator
   if(this!=&iap) {
      TVirtualIsAProxy::operator=(iap);
      fType=iap.fType;
      fLastType=iap.fLastType;
      fClass=iap.fClass;
      fLastClass=iap.fLastClass;
      for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
      fVirtual=iap.fVirtual;
      fContext=iap.fContext;
      fInit=iap.fInit;
   }
   return *this;
}

//______________________________________________________________________________
TIsAProxy::~TIsAProxy()
{
   // Standard destructor

   ClassMap_t* m = GetMap(fSubTypes);
   m->clear();
   m->~ClassMap_t();
}

//______________________________________________________________________________
void TIsAProxy::SetClass(TClass *cl)
{
   // Set class pointer
   GetMap(fSubTypes)->clear();
   fClass = fLastClass = cl;
}

//______________________________________________________________________________
TClass* TIsAProxy::operator()(const void *obj)
{
   // IsA callback

   if ( !fInit )  {
      fInit = kTRUE;
      if ( !fClass && fType ) fClass = TClass::GetClass(*fType);
      fClass->Property();
      if ( fClass->GetClassInfo() )  {
         fVirtual = (gCint->ClassInfo_ClassProperty(fClass->GetClassInfo())&G__CLS_HASVIRTUAL) == G__CLS_HASVIRTUAL;
      }
   }
   if ( !obj || !fVirtual )  {
      return fClass;
   } else  {
      // Avoid the case that the first word is a virtual_base_offset_table instead of
      // a virtual_function_table
      Long_t offset = **(Long_t**)obj;
      if ( offset == 0 ) return fClass;

      DynamicType* ptr = (DynamicType*)obj;
      const std::type_info* typ = &typeid(*ptr);

      if ( typ == fType )  {
         return fClass;
      }
      else if ( typ == fLastType )  {
         return fLastClass;
      }
      // Check if type is already in sub-class cache
      else if ( 0 != (fLastClass=(*GetMap(fSubTypes))[long(typ)]) )  {
         fLastType = typ;
      }
      // Last resort: lookup root class
      else   {
         fLastClass = TClass::GetClass(*typ);
         fLastType = typ;
         (*GetMap(fSubTypes))[long(fLastType)] = fLastClass;
      }
   }
   return fLastClass;
}
<commit_msg>fix format warning.<commit_after>// @(#)root/meta:$Id$
// Author: Markus Frank 20/05/2005

/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/

#include "TClass.h"
#include "TError.h"
#include "TInterpreter.h"
#include "TIsAProxy.h"

#include <map>

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TClass                                                               //
//                                                                      //
// TIsAProxy implementation class.                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

namespace {
   struct DynamicType {
      // Helper class to enable typeid on any address
      // Used in code similar to:
      //    typeid( * (DynamicType*) void_ptr );
      virtual ~DynamicType() {}
   };
}

typedef std::map<long, TClass*> ClassMap_t; // Internal type map
inline ClassMap_t *GetMap(void* p)
{
   return (ClassMap_t*)p;
}

//______________________________________________________________________________
TIsAProxy::TIsAProxy(const std::type_info& typ, void* ctxt)
   : fType(&typ), fLastType(&typ), fClass(0), fLastClass(0),
     fVirtual(false), fContext(ctxt), fInit(false)
{
   // Standard initializing constructor

   ::new(fSubTypes) ClassMap_t();
   if ( sizeof(ClassMap_t) > sizeof(fSubTypes) ) {
      Fatal("TIsAProxy::TIsAProxy",
         "Classmap size is badly adjusted: it needs %u instead of %u bytes.",
         (UInt_t)sizeof(ClassMap_t), (UInt_t)sizeof(fSubTypes));
   }
}

//______________________________________________________________________________
TIsAProxy::TIsAProxy(const TIsAProxy& iap) :
  TVirtualIsAProxy(iap),
  fType(iap.fType),
  fLastType(iap.fLastType),
  fClass(iap.fClass),
  fLastClass(iap.fLastClass),
  fVirtual(iap.fVirtual),
  fContext(iap.fContext),
  fInit(iap.fInit)
{
   //copy constructor
   for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
}

//______________________________________________________________________________
TIsAProxy& TIsAProxy::operator=(const TIsAProxy& iap)
{
   //assignement operator
   if(this!=&iap) {
      TVirtualIsAProxy::operator=(iap);
      fType=iap.fType;
      fLastType=iap.fLastType;
      fClass=iap.fClass;
      fLastClass=iap.fLastClass;
      for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
      fVirtual=iap.fVirtual;
      fContext=iap.fContext;
      fInit=iap.fInit;
   }
   return *this;
}

//______________________________________________________________________________
TIsAProxy::~TIsAProxy()
{
   // Standard destructor

   ClassMap_t* m = GetMap(fSubTypes);
   m->clear();
   m->~ClassMap_t();
}

//______________________________________________________________________________
void TIsAProxy::SetClass(TClass *cl)
{
   // Set class pointer
   GetMap(fSubTypes)->clear();
   fClass = fLastClass = cl;
}

//______________________________________________________________________________
TClass* TIsAProxy::operator()(const void *obj)
{
   // IsA callback

   if ( !fInit )  {
      fInit = kTRUE;
      if ( !fClass && fType ) fClass = TClass::GetClass(*fType);
      fClass->Property();
      if ( fClass->GetClassInfo() )  {
         fVirtual = (gCint->ClassInfo_ClassProperty(fClass->GetClassInfo())&G__CLS_HASVIRTUAL) == G__CLS_HASVIRTUAL;
      }
   }
   if ( !obj || !fVirtual )  {
      return fClass;
   } else  {
      // Avoid the case that the first word is a virtual_base_offset_table instead of
      // a virtual_function_table
      Long_t offset = **(Long_t**)obj;
      if ( offset == 0 ) return fClass;

      DynamicType* ptr = (DynamicType*)obj;
      const std::type_info* typ = &typeid(*ptr);

      if ( typ == fType )  {
         return fClass;
      }
      else if ( typ == fLastType )  {
         return fLastClass;
      }
      // Check if type is already in sub-class cache
      else if ( 0 != (fLastClass=(*GetMap(fSubTypes))[long(typ)]) )  {
         fLastType = typ;
      }
      // Last resort: lookup root class
      else   {
         fLastClass = TClass::GetClass(*typ);
         fLastType = typ;
         (*GetMap(fSubTypes))[long(fLastType)] = fLastClass;
      }
   }
   return fLastClass;
}
<|endoftext|>


<commit_before>/*
 * The Biomechanical ToolKit
 * Copyright (c) 2009-2013, Arnaud Barré
 * 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(s) of the copyright holders nor the names
 *       of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written
 *       permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "btkMEXObjectHandle.h"
#include "btkMXMetaData.h"

#include <btkAcquisition.h>

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(nrhs < 3)
    mexErrMsgTxt("Minimum of three inputs required.");
  if (nlhs > 1)
    mexErrMsgTxt("Too many output arguments.");

  for (int i = 1 ; i < nrhs-2 ; ++i)
  {
    if (mxIsEmpty(prhs[i]) || (!mxIsChar(prhs[i]) && ((mxGetClassID(prhs[i]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[i]) || (mxGetNumberOfElements(prhs[i]) != 1))))
      mexErrMsgTxt("Metadata's label or index must be set by a non-empty string or an integer respectively.");
  }
  if ((mxGetClassID(prhs[nrhs-2]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[nrhs-2]) || (mxGetNumberOfElements(prhs[nrhs-2]) != 1))
    mexErrMsgTxt("The index for the metadata's value must be set by a single integer");
  if ((mxIsCell(prhs[nrhs-1]) && (mxGetNumberOfElements(prhs[nrhs-1]) != 1))
       || (mxIsChar(prhs[nrhs-1]) && (mxGetM(prhs[nrhs-1]) != 1))
       || ((mxGetClassID(prhs[nrhs-1]) != mxDOUBLE_CLASS) && (mxIsComplex(prhs[nrhs-1]) || (mxGetNumberOfElements(prhs[nrhs-1]) != 1))))
    mexErrMsgTxt("Unsupported metadata's value or the number of elements is greater than 1.");

  btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]);
  btk::MetaData::Iterator it;
  btk::MetaData::Pointer parent = btkMXExtractMetaDataIterator(&it, nrhs-3, prhs, acq->GetMetaData());

  if (!(*it)->HasInfo())
    mexErrMsgTxt("No metadata's info.");

  size_t index = static_cast<size_t>(mxGetScalar(prhs[nrhs-2])) - 1;
  if (index >= (*it)->GetInfo()->GetValues().size())
    mexErrMsgTxt("Invalid index to extract one metadata's value.");

  const mxArray* data = 0;
  if (mxIsCell(prhs[nrhs-1]))
  {
    data = mxGetCell(prhs[nrhs-1], 0);
    if (!data || !mxIsChar(data))
      mexErrMsgTxt("Error in the value's format: only a string are accepted in cell.");
  }
  else
    data = prhs[nrhs-1];

  if (mxIsChar(data))
  {
    size_t strlen_ = (mxGetM(data) * mxGetN(data) * sizeof(mxChar)) + 1;
    char* d = (char*)mxMalloc(strlen_);
    mxGetString(data, d, strlen_);
    (*it)->GetInfo()->SetValue(static_cast<int>(index), d);
    mxFree(d);
  }
  else
    (*it)->GetInfo()->SetValue(static_cast<int>(index), mxGetScalar(data));

  if (nlhs > 0)
    plhs[0] = btkMXCreateMetaDataStructure(acq->GetMetaData());
};

<commit_msg>[FIX] Wrong checks in the data type / number of elements for the value to set in a metadata.<commit_after>/*
 * The Biomechanical ToolKit
 * Copyright (c) 2009-2013, Arnaud Barré
 * 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(s) of the copyright holders nor the names
 *       of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written
 *       permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "btkMEXObjectHandle.h"
#include "btkMXMetaData.h"

#include <btkAcquisition.h>

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(nrhs < 3)
    mexErrMsgTxt("Minimum of three inputs required.");
  if (nlhs > 1)
    mexErrMsgTxt("Too many output arguments.");

  for (int i = 1 ; i < nrhs-2 ; ++i)
  {
    if (mxIsEmpty(prhs[i]) || (!mxIsChar(prhs[i]) && ((mxGetClassID(prhs[i]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[i]) || (mxGetNumberOfElements(prhs[i]) != 1))))
      mexErrMsgTxt("Metadata's label or index must be set by a non-empty string or an integer respectively.");
  }
  if ((mxGetClassID(prhs[nrhs-2]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[nrhs-2]) || (mxGetNumberOfElements(prhs[nrhs-2]) != 1))
    mexErrMsgTxt("The index for the metadata's value must be set by a single integer");
  bool invalidData = false;
  if (mxIsCell(prhs[nrhs-1]))
  {
    if (mxGetNumberOfElements(prhs[nrhs-1]) != 1)
      invalidData = true;
  }
  else if (mxIsChar(prhs[nrhs-1]))
  {
    if (mxGetM(prhs[nrhs-1]) != 1)
      invalidData = true;
  }
  else if ((mxGetClassID(prhs[nrhs-1]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[nrhs-1]) || (mxGetNumberOfElements(prhs[nrhs-1]) != 1))
    invalidData = true;
  if (invalidData)
    mexErrMsgTxt("Unsupported metadata's value or the number of elements is greater than 1.");

  btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]);
  btk::MetaData::Iterator it;
  btk::MetaData::Pointer parent = btkMXExtractMetaDataIterator(&it, nrhs-3, prhs, acq->GetMetaData());

  if (!(*it)->HasInfo())
    mexErrMsgTxt("No metadata's info.");

  size_t index = static_cast<size_t>(mxGetScalar(prhs[nrhs-2])) - 1;
  if (index >= (*it)->GetInfo()->GetValues().size())
    mexErrMsgTxt("Invalid index to extract one metadata's value.");

  const mxArray* data = 0;
  if (mxIsCell(prhs[nrhs-1]))
  {
    data = mxGetCell(prhs[nrhs-1], 0);
    if (!data || !mxIsChar(data))
      mexErrMsgTxt("Error in the value's format: only a string is accepted in cell.");
  }
  else
    data = prhs[nrhs-1];

  if (mxIsChar(data))
  {
    size_t strlen_ = (mxGetM(data) * mxGetN(data) * sizeof(mxChar)) + 1;
    char* d = (char*)mxMalloc(strlen_);
    mxGetString(data, d, strlen_);
    (*it)->GetInfo()->SetValue(static_cast<int>(index), d);
    mxFree(d);
  }
  else
    (*it)->GetInfo()->SetValue(static_cast<int>(index), mxGetScalar(data));

  if (nlhs > 0)
    plhs[0] = btkMXCreateMetaDataStructure(acq->GetMetaData());
};

<|endoftext|>


<commit_before>
#ifndef STEAL_QUEUE_HPP
#define STEAL_QUEUE_HPP

#include <iostream>
#include <glog/logging.h>
#include <stdlib.h>

#define SS_NSTATES 1

struct workStealRequest_args;
struct workStealReply_args;

/// Type for Node ID.
#include <boost/cstdint.hpp>
typedef int16_t Node;

/// Forward declare for steal_locally
class Thread;

template <typename T>
class StealQueue {
    private:
        uint64_t stackSize;     /* total space avail (in number of elements) */
        uint64_t workAvail;     /* elements available for stealing */
        uint64_t sharedStart;   /* index of start of shared portion of stack */
        uint64_t local;         /* index of start of local portion */
        uint64_t top;           /* index of stack top */
        uint64_t maxStackDepth;                      /* stack stats */
        uint64_t nNodes, maxTreeDepth, nVisited, nLeaves;        /* tree stats: (num pushed, max depth, num popped, leaves)  */
        uint64_t nAcquire, nRelease, nSteal, nFail;  /* steal stats */
        uint64_t wakeups, falseWakeups, nNodes_last;
        double time[SS_NSTATES], timeLast;
        /* perf measurements */
        int entries[SS_NSTATES], curState;
        /* lock for manipulation of shared portion */
        T* stack;       /* addr of actual
                                  stack of nodes
                                  in local addr
                                  space */
        T* stack_g; /* addr of same
                              stack in global
                              addr space */

        static StealQueue<T>* staticQueueAddress;

        static void workStealReply_am( workStealReply_args * args,  size_t size, void * payload, size_t payload_size );
        static void workStealRequest_am( workStealRequest_args * args, size_t size, void * payload, size_t payload_size );

        std::ostream& dump ( std::ostream& o ) const {
            return o << "StealQueue[localDepth=" << localDepth()
                     << "; sharedDepth=" << sharedDepth()
                     << "; indices(top= " << top
                                   << " local=" << local
                                   << " sharedStart=" << sharedStart << ")"
                     << "; stackSize=" << stackSize << "]";
        }

    public:
        StealQueue( uint64_t numEle )
            : stackSize( numEle )
            , maxStackDepth( 0 )
            , nNodes( 0 ), maxTreeDepth( 0 ), nVisited( 0 ), nLeaves( 0 )
            , nAcquire( 0 ), nRelease( 0 ), nSteal( 0 ), nFail( 0 )
            , wakeups( 0 ), falseWakeups( 0 ), nNodes_last( 0 ) {

                uint64_t nbytes = numEle * sizeof(T);

                // allocate stack in shared addr space with affinity to calling thread
                // and record local addr for efficient access in sequel
                stack_g = static_cast<T*>( malloc( nbytes ) );
                stack = stack_g;

                CHECK( stack!= NULL ) << "Request for " << nbytes << " bytes for stealStack failed";

                mkEmpty();
            }

        void mkEmpty();
        void push( T c);
        T peek( );
        void pop( );
        uint64_t topPosn( ) const;
        uint64_t localDepth( ) const;
        uint64_t sharedDepth( ) const;
        void release( int k );
        int acquire( int k );
        int steal_locally( Node victim, int chunkSize, Thread * current );
        void setState( int state );

        uint64_t get_nNodes( ) {
            return nNodes;
        }

        /// register local address of remote steal queues
        static void registerAddress( StealQueue<T> * addr );

        template< typename U >
        friend std::ostream& operator<<( std::ostream& o, const StealQueue<U>& sq );
};

static int maxint(int x, int y) { return (x>y)?x:y; }

/// Push onto top of local stack
template <typename T>
inline void StealQueue<T>::push( T c ) {
  CHECK( top < stackSize ) << "push: overflow (top:" << top << " stackSize:" << stackSize << ")";

  stack[top] = c;
  top++;
  nNodes++;
  maxStackDepth = maxint(top, maxStackDepth);
  //s->maxTreeDepth = maxint(s->maxTreeDepth, c->height); //XXX dont want to deref c here (expensive for just a bookkeeping operation
}

/// get top element
template <typename T>
inline T StealQueue<T>::peek( ) {
    CHECK(top > local) << "peek: empty local stack";
    return stack[top-1];
}

/// local pop
template <typename T>
inline void StealQueue<T>::pop( ) {
  CHECK(top > local) << "pop: empty local stack";

  // 0 out the popped element (to detect errors)
  memset( &stack[top-1], 0, sizeof(T) );

  top--;
  nVisited++;
}

/// local depth
template <typename T>
inline uint64_t StealQueue<T>::localDepth() const {
  return (top - local);
}

template <typename T>
void StealQueue<T>::setState( int state ) { return; }

/// Initialize the dedicated queue for T
template <typename T>
StealQueue<T>* StealQueue<T>::staticQueueAddress = NULL;

template <typename T>
void StealQueue<T>::registerAddress( StealQueue<T> * addr ) {
    staticQueueAddress = addr;
}

/// set queue to empty
template <typename T>
void StealQueue<T>::mkEmpty( ) {
    sharedStart = 0;
    local  = 0;
    top    = 0;
    workAvail = 0;
}

/// local top position:  stack index of top element
template <typename T>
uint64_t StealQueue<T>::topPosn() const
{
  CHECK ( top > local ) << "ss_topPosn: empty local stack";
  return top - 1;
}

/// release k values from bottom of local stack
template <typename T>
void StealQueue<T>::release( int k ) {
  CHECK(top - local >= k) << "ss_release:  do not have k vals to release";

  // the above check is not time-of-check-to-use bug, because top/local guarenteed
  // not to change. We just need to update them
  VLOG(4) << "(before)release: k=" << k << " local size=" << top-local << " sharedSize=" << workAvail;
  local += k;
  workAvail += k;
  VLOG(4) << "(after)release: k=" << k << " local size=" << top-local << " sharedSize=" << workAvail;
  nRelease++;

}

/// move k values from top of shared stack into local stack
/// return false if k vals are not avail on shared stack
template <typename T>
int StealQueue<T>::acquire( int k ) {
  int avail;
  avail = local - sharedStart;
  VLOG(4) << "(before)acquire: k=" << k << " avail=" << avail << " acquire?=" << (avail>=k);
  if (avail >= k) {
    local -= k;
    workAvail -= k;
    VLOG(4) << "(after)acquire: local" << local << " workAvail=" << workAvail;
    nAcquire++;
  }
  return (avail >= k);
}

template <typename T>
uint64_t StealQueue<T>::sharedDepth( ) const {
    return local - sharedStart;
}

//////////////////////////////////////////////////
// Work stealing
/////////////////////////////////////////////////

//#include "../SoftXMT.hpp"
#include <Aggregator.hpp>
void SoftXMT_suspend();
void SoftXMT_wake( Thread * );
Node SoftXMT_mynode();

struct workStealRequest_args {
    int k;
    Node from;
};

struct workStealReply_args {
    int k;
};

static int local_steal_amount;
static Thread * steal_waiter = NULL;

template <typename T>
void StealQueue<T>::workStealReply_am( workStealReply_args * args,  size_t size, void * payload, size_t payload_size ) {
    CHECK ( local_steal_amount == -1 ) << "local_steal_amount=" << local_steal_amount << " when steal reply arrives";

    T * stolen_work = static_cast<T*>( payload );
    int k = args->k;

    StealQueue<T>* thiefStack = StealQueue<T>::staticQueueAddress;

    if (k > 0) {
        memcpy(&thiefStack->stack[thiefStack->top], stolen_work, payload_size);
        local_steal_amount = k;

        thiefStack->top += local_steal_amount;
        thiefStack->nSteal++;
    } else {
        local_steal_amount = 0;

        thiefStack->nFail++;
    }

    if ( steal_waiter != NULL ) {
        SoftXMT_wake( steal_waiter );
        steal_waiter = NULL;
    }
}

template <typename T>
void StealQueue<T>::workStealRequest_am(workStealRequest_args * args, size_t size, void * payload, size_t payload_size) {
    int k = args->k;

    StealQueue<T>* victimStack = StealQueue<T>::staticQueueAddress;

    int victimLocal = victimStack->local;
    int victimShared = victimStack->sharedStart;
    int victimWorkAvail = victimStack->workAvail;

    CHECK( victimLocal - victimShared == victimWorkAvail ) << "handle steal request: stealStack invariant violated";

    int ok = victimWorkAvail >= k;
    VLOG(4) << "Victim (Node " << SoftXMT_mynode() << ") victimWorkAvail=" << victimWorkAvail << " k=" << k;
    if (ok) {
        /* reserve a chunk */
        victimStack->sharedStart =  victimShared + k;
        victimStack->workAvail = victimWorkAvail - k;
    }

    /* if k elts reserved, move them to local portion of our stack */
    if (ok) {
        T* victimStackBase = victimStack->stack;
        T* victimSharedStart = victimStackBase + victimShared;

        workStealReply_args reply_args = { k };
        SoftXMT_call_on( args->from, &StealQueue<T>::workStealReply_am,
                         &reply_args, sizeof(workStealReply_args),
                         victimSharedStart, k*sizeof( T ));

        // 0 out the stolen stuff (to detect errors)
        memset( victimSharedStart, 0, k*sizeof( T ) );
    } else {
        workStealReply_args reply_args = { 0 };
        SoftXMT_call_on( args->from, &StealQueue<T>::workStealReply_am, &reply_args );
    }

}

template <typename T>
int StealQueue<T>::steal_locally( Node victim, int k, Thread * current ) {

    local_steal_amount = -1;

    workStealRequest_args req_args = { k, SoftXMT_mynode() };
    SoftXMT_call_on( victim, &StealQueue<T>::workStealRequest_am, &req_args );

    // steal is blocking
    // TODO: use suspend-wake mechanism
    while ( local_steal_amount == -1 ) {
        steal_waiter = current;
        SoftXMT_suspend();
    }

    return local_steal_amount;
}
/////////////////////////////////////////////////////////

template <typename T>
std::ostream& operator<<( std::ostream& o, const StealQueue<T>& sq ) {
    return sq.dump( o );
}

#endif
<commit_msg>steal "success" and "victim" events (in the AM handlers)<commit_after>
#ifndef STEAL_QUEUE_HPP
#define STEAL_QUEUE_HPP

#include <iostream>
#include <glog/logging.h>
#include <stdlib.h>

// profiling/tracing
#include <TAU.h>

#define SS_NSTATES 1

struct workStealRequest_args;
struct workStealReply_args;

/// Type for Node ID.
#include <boost/cstdint.hpp>
typedef int16_t Node;

/// Forward declare for steal_locally
class Thread;

template <typename T>
class StealQueue {
    private:
        uint64_t stackSize;     /* total space avail (in number of elements) */
        uint64_t workAvail;     /* elements available for stealing */
        uint64_t sharedStart;   /* index of start of shared portion of stack */
        uint64_t local;         /* index of start of local portion */
        uint64_t top;           /* index of stack top */
        uint64_t maxStackDepth;                      /* stack stats */
        uint64_t nNodes, maxTreeDepth, nVisited, nLeaves;        /* tree stats: (num pushed, max depth, num popped, leaves)  */
        uint64_t nAcquire, nRelease, nSteal, nFail;  /* steal stats */
        uint64_t wakeups, falseWakeups, nNodes_last;
        double time[SS_NSTATES], timeLast;
        /* perf measurements */
        int entries[SS_NSTATES], curState;
        /* lock for manipulation of shared portion */
        T* stack;       /* addr of actual
                                  stack of nodes
                                  in local addr
                                  space */
        T* stack_g; /* addr of same
                              stack in global
                              addr space */

        static StealQueue<T>* staticQueueAddress;

        static void workStealReply_am( workStealReply_args * args,  size_t size, void * payload, size_t payload_size );
        static void workStealRequest_am( workStealRequest_args * args, size_t size, void * payload, size_t payload_size );

        std::ostream& dump ( std::ostream& o ) const {
            return o << "StealQueue[localDepth=" << localDepth()
                     << "; sharedDepth=" << sharedDepth()
                     << "; indices(top= " << top
                                   << " local=" << local
                                   << " sharedStart=" << sharedStart << ")"
                     << "; stackSize=" << stackSize << "]";
        }

    public:
        StealQueue( uint64_t numEle )
            : stackSize( numEle )
            , maxStackDepth( 0 )
            , nNodes( 0 ), maxTreeDepth( 0 ), nVisited( 0 ), nLeaves( 0 )
            , nAcquire( 0 ), nRelease( 0 ), nSteal( 0 ), nFail( 0 )
            , wakeups( 0 ), falseWakeups( 0 ), nNodes_last( 0 ) {

                uint64_t nbytes = numEle * sizeof(T);

                // allocate stack in shared addr space with affinity to calling thread
                // and record local addr for efficient access in sequel
                stack_g = static_cast<T*>( malloc( nbytes ) );
                stack = stack_g;

                CHECK( stack!= NULL ) << "Request for " << nbytes << " bytes for stealStack failed";

                mkEmpty();
            }

        void mkEmpty();
        void push( T c);
        T peek( );
        void pop( );
        uint64_t topPosn( ) const;
        uint64_t localDepth( ) const;
        uint64_t sharedDepth( ) const;
        void release( int k );
        int acquire( int k );
        int steal_locally( Node victim, int chunkSize, Thread * current );
        void setState( int state );

        uint64_t get_nNodes( ) {
            return nNodes;
        }

        /// register local address of remote steal queues
        static void registerAddress( StealQueue<T> * addr );

        template< typename U >
        friend std::ostream& operator<<( std::ostream& o, const StealQueue<U>& sq );
};

static int maxint(int x, int y) { return (x>y)?x:y; }

/// Push onto top of local stack
template <typename T>
inline void StealQueue<T>::push( T c ) {
  CHECK( top < stackSize ) << "push: overflow (top:" << top << " stackSize:" << stackSize << ")";

  stack[top] = c;
  top++;
  nNodes++;
  maxStackDepth = maxint(top, maxStackDepth);
  //s->maxTreeDepth = maxint(s->maxTreeDepth, c->height); //XXX dont want to deref c here (expensive for just a bookkeeping operation
}

/// get top element
template <typename T>
inline T StealQueue<T>::peek( ) {
    CHECK(top > local) << "peek: empty local stack";
    return stack[top-1];
}

/// local pop
template <typename T>
inline void StealQueue<T>::pop( ) {
  CHECK(top > local) << "pop: empty local stack";

  // 0 out the popped element (to detect errors)
  memset( &stack[top-1], 0, sizeof(T) );

  top--;
  nVisited++;
}

/// local depth
template <typename T>
inline uint64_t StealQueue<T>::localDepth() const {
  return (top - local);
}

template <typename T>
void StealQueue<T>::setState( int state ) { return; }

/// Initialize the dedicated queue for T
template <typename T>
StealQueue<T>* StealQueue<T>::staticQueueAddress = NULL;

template <typename T>
void StealQueue<T>::registerAddress( StealQueue<T> * addr ) {
    staticQueueAddress = addr;
}

/// set queue to empty
template <typename T>
void StealQueue<T>::mkEmpty( ) {
    sharedStart = 0;
    local  = 0;
    top    = 0;
    workAvail = 0;
}

/// local top position:  stack index of top element
template <typename T>
uint64_t StealQueue<T>::topPosn() const
{
  CHECK ( top > local ) << "ss_topPosn: empty local stack";
  return top - 1;
}

/// release k values from bottom of local stack
template <typename T>
void StealQueue<T>::release( int k ) {
  CHECK(top - local >= k) << "ss_release:  do not have k vals to release";

  // the above check is not time-of-check-to-use bug, because top/local guarenteed
  // not to change. We just need to update them
  VLOG(4) << "(before)release: k=" << k << " local size=" << top-local << " sharedSize=" << workAvail;
  local += k;
  workAvail += k;
  VLOG(4) << "(after)release: k=" << k << " local size=" << top-local << " sharedSize=" << workAvail;
  nRelease++;

}

/// move k values from top of shared stack into local stack
/// return false if k vals are not avail on shared stack
template <typename T>
int StealQueue<T>::acquire( int k ) {
  int avail;
  avail = local - sharedStart;
  VLOG(4) << "(before)acquire: k=" << k << " avail=" << avail << " acquire?=" << (avail>=k);
  if (avail >= k) {
    local -= k;
    workAvail -= k;
    VLOG(4) << "(after)acquire: local" << local << " workAvail=" << workAvail;
    nAcquire++;
  }
  return (avail >= k);
}

template <typename T>
uint64_t StealQueue<T>::sharedDepth( ) const {
    return local - sharedStart;
}

//////////////////////////////////////////////////
// Work stealing
/////////////////////////////////////////////////

//#include "../SoftXMT.hpp"
#include <Aggregator.hpp>
void SoftXMT_suspend();
void SoftXMT_wake( Thread * );
Node SoftXMT_mynode();

struct workStealRequest_args {
    int k;
    Node from;
};

struct workStealReply_args {
    int k;
};

static int local_steal_amount;
static Thread * steal_waiter = NULL;

template <typename T>
void StealQueue<T>::workStealReply_am( workStealReply_args * args,  size_t size, void * payload, size_t payload_size ) {
    CHECK ( local_steal_amount == -1 ) << "local_steal_amount=" << local_steal_amount << " when steal reply arrives";

    T * stolen_work = static_cast<T*>( payload );
    int k = args->k;

    StealQueue<T>* thiefStack = StealQueue<T>::staticQueueAddress;

    if (k > 0) {
        TAU_REGISTER_EVENT(steal_success_ev, "Steal success");
        TAU_EVENT(steal_success_ev, k);

        memcpy(&thiefStack->stack[thiefStack->top], stolen_work, payload_size);
        local_steal_amount = k;

        thiefStack->top += local_steal_amount;
        thiefStack->nSteal++;
    } else {
        local_steal_amount = 0;

        thiefStack->nFail++;
    }

    if ( steal_waiter != NULL ) {
        SoftXMT_wake( steal_waiter );
        steal_waiter = NULL;
    }
}

template <typename T>
void StealQueue<T>::workStealRequest_am(workStealRequest_args * args, size_t size, void * payload, size_t payload_size) {
    int k = args->k;

    StealQueue<T>* victimStack = StealQueue<T>::staticQueueAddress;

    int victimLocal = victimStack->local;
    int victimShared = victimStack->sharedStart;
    int victimWorkAvail = victimStack->workAvail;

    CHECK( victimLocal - victimShared == victimWorkAvail ) << "handle steal request: stealStack invariant violated";

    int ok = victimWorkAvail >= k;
    VLOG(4) << "Victim (Node " << SoftXMT_mynode() << ") victimWorkAvail=" << victimWorkAvail << " k=" << k;
    if (ok) {
        /* reserve a chunk */
        victimStack->sharedStart =  victimShared + k;
        victimStack->workAvail = victimWorkAvail - k;
    }

    /* if k elts reserved, move them to local portion of our stack */
    if (ok) {
        TAU_REGISTER_EVENT(steal_victim_ev, "Steal victim");
        TAU_EVENT(steal_victim_ev, k);

        T* victimStackBase = victimStack->stack;
        T* victimSharedStart = victimStackBase + victimShared;

        workStealReply_args reply_args = { k };
        SoftXMT_call_on( args->from, &StealQueue<T>::workStealReply_am,
                         &reply_args, sizeof(workStealReply_args),
                         victimSharedStart, k*sizeof( T ));

        // 0 out the stolen stuff (to detect errors)
        memset( victimSharedStart, 0, k*sizeof( T ) );
    } else {
        workStealReply_args reply_args = { 0 };
        SoftXMT_call_on( args->from, &StealQueue<T>::workStealReply_am, &reply_args );
    }

}

template <typename T>
int StealQueue<T>::steal_locally( Node victim, int k, Thread * current ) {

    local_steal_amount = -1;

    workStealRequest_args req_args = { k, SoftXMT_mynode() };
    SoftXMT_call_on( victim, &StealQueue<T>::workStealRequest_am, &req_args );

    // steal is blocking
    // TODO: use suspend-wake mechanism
    while ( local_steal_amount == -1 ) {
        steal_waiter = current;
        SoftXMT_suspend();
    }

    return local_steal_amount;
}
/////////////////////////////////////////////////////////

template <typename T>
std::ostream& operator<<( std::ostream& o, const StealQueue<T>& sq ) {
    return sq.dump( o );
}

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <fstream>
#include <iomanip>
#include <string.h>
#include <math.h>
#include "SuMo.h"

using namespace std;

int SuMo::read_CC(bool SHOW_CC_STATUS, bool SHOW_AC_STATUS, int device, int triggerMode) {

    bool print = false; // verbose
    int samples;        // no. of words in usb packet
    int samples_device_0, samples_device_1;

    if (device == 0)
        for (int i = 0; i < 4; i++) {
            EVENT_FLAG[i] = false;
            DIGITIZING_START_FLAG[i] = false;
        }
    else if (device == 1)
        for (int i = 4; i < numFrontBoards; i++) {
            EVENT_FLAG[i] = false;
            DIGITIZING_START_FLAG[i] = false;
        }
    else if (device == 100) {  //device = 100 for all boards in system
        for (int i = 0; i < numFrontBoards; i++) {
            EVENT_FLAG[i] = false;
            DIGITIZING_START_FLAG[i] = false;
        }
        if (print) cout << "using device = 100, ALL devices " << endl;
    } else return -3; // device assignment error

    /* device = 1 for slave device */
    if (device > 1 && mode != USB2x) return -2;

    /* set usb read mode for numFrontBoards+1 (central card readout-only) */
    if (device == 0) set_usb_read_mode(5);
    else if (device == 1) set_usb_read_mode_slaveDevice(5);
    else if (device == 100) {
        if (SHOW_CC_STATUS) cout << "master CC connected." << endl;
        if (mode == USB2x) {
            set_usb_read_mode_slaveDevice(5);
            if (SHOW_CC_STATUS) cout << "slave CC connected." << endl;
        }
        set_usb_read_mode(5);
    } else return -3;

    int ram_events = 0;
    int num_devices = 1;
    int device_tmp = device;
    if (device == 100) {
        num_devices = 2;
        device_tmp = 0;
    } else {
        num_devices = 1;
        device_tmp = device;
    }

    for (int loop_cc = device_tmp; loop_cc < device_tmp + num_devices; loop_cc++) {

        if (print) cout << "device in central card address loop : " << loop_cc << endl;

        unsigned short buffer[cc_buffersize];
        memset(buffer, 0x0, cc_buffersize * sizeof(unsigned short));
        /* try readout */
        try {
            if (loop_cc == 0) {
                usb.readData(buffer, cc_buffersize + 2, &samples);
                samples_device_0 = samples;
            } else if (loop_cc == 1) {
                usb2.readData(buffer, cc_buffersize + 2, &samples);
                samples_device_1 = samples;
            }

            if (samples < 2 && device != 100) {
                if (print) cout << "error: no data in buffer on device #" << device << endl;
                return -1;
            }

            int cc_header_found = -1;
            int cc_start_found = -1;

            for (int i = 0; i < 5; i++) {
                if (buffer[i] == 0x1234) {
                    cc_header_found = i;
                    if (print) cout << "cc header @ " << i << endl;
                }
                if (buffer[i] == 0xDEAD) {
                    cc_start_found = i;
                    if (print) cout << "cc start @ " << i << endl;
                }
            }
            if (loop_cc == 0) {
                CC_EVENT_COUNT_FROMCC0 = buffer[5];
                if (SHOW_CC_STATUS) cout << "master event = " << buffer[5] << endl;
            }
            if (loop_cc == 1) {
                CC_EVENT_COUNT_FROMCC1 = buffer[5];
                if (SHOW_CC_STATUS) cout << "slave event = " << buffer[5] << endl;
            }

            for (int i = 0; i < cc_buffersize; i++) {
                CC_INFO[i] = buffer[i];
                if (print) cout << i << ":" << buffer[i] << " ";
            }
            if (print) cout << "samples received: " << samples << " on device #" << device << endl;
        }
        catch (...) {
            fprintf(stderr, "Please connect the board. [DEFAULT exception] \n");
            return 1;
        }

        if (SHOW_CC_STATUS) {
            cout << endl;
            if (device > 0) cout << "AC/DC connection status :: Slave Device: \n";
            else cout << "AC/DC connection status: \n";
        }

        int slave_index = loop_cc * boardsPerCC;
        /* look for ACDC boards, set global variable DC_ACTIVE[numFrontBoards] */
        // add second handle for DC_ACTIVE
        if ((buffer[2] & 0x1) && (buffer[2] & 0x11)) {
            DC_ACTIVE[0 + slave_index] = true;
            if (SHOW_CC_STATUS) cout << "* DC 0 detected!! \n";
        }
        if ((buffer[2] & 0x2) && (buffer[2] & 0x22)) {
            DC_ACTIVE[1 + slave_index] = true;
            if (SHOW_CC_STATUS) cout << "* DC 1 detected!! \n";
        }
        if ((buffer[2] & 0x4) && (buffer[2] & 0x44)) {
            DC_ACTIVE[2 + slave_index] = true;
            if (SHOW_CC_STATUS) cout << "* DC 2 detected!! \n";
        }
        if ((buffer[2] & 0x8) && (buffer[2] & 0x88)) {
            DC_ACTIVE[3 + slave_index] = true;
            if (SHOW_CC_STATUS) cout << "* DC 3 detected!! \n";
        }

        //check for events in CC RAM
        if (buffer[4] & 0x1) EVENT_FLAG[0 + slave_index] = true;
        if (buffer[4] & 0x2) EVENT_FLAG[1 + slave_index] = true;
        if (buffer[4] & 0x4) EVENT_FLAG[2 + slave_index] = true;
        if (buffer[4] & 0x8) EVENT_FLAG[3 + slave_index] = true;

        ram_events += EVENT_FLAG[0 + slave_index] +
                EVENT_FLAG[1 + slave_index] +
                EVENT_FLAG[2 + slave_index] +
                EVENT_FLAG[3 + slave_index];

        if (buffer[4] >> 4 & 0x1) DIGITIZING_START_FLAG[0 + slave_index] = true;
        if (buffer[4] >> 4 & 0x2) DIGITIZING_START_FLAG[1 + slave_index] = true;
        if (buffer[4] >> 4 & 0x4) DIGITIZING_START_FLAG[2 + slave_index] = true;
        if (buffer[4] >> 4 & 0x8) DIGITIZING_START_FLAG[3 + slave_index] = true;

    }  //end loop over central cards
//probe ac/dc cards if specified
    if (SHOW_AC_STATUS) {
        bool tmp_active[numFrontBoards];
        for (int ii = 0; ii < numFrontBoards; ii++) tmp_active[ii] = false; //mask off master or slave board for printing info

        if (device == 1) {     //slave device
            for (int board = boardsPerCC; board < numFrontBoards; board++) tmp_active[board] = DC_ACTIVE[board];

            read_AC(triggerMode, tmp_active, false);
            for (int board = boardsPerCC; board < numFrontBoards; board++)
                if (DC_ACTIVE[board]) {
                    cout << endl << "AC/DC #" << board << ":";
                    get_AC_info(true, board);
                }
            //manage_cc_fifo_slaveDevice(1);
        } else if (device == 0) {          //master device
            for (int board = 0; board < boardsPerCC; board++) tmp_active[board] = DC_ACTIVE[board];

            read_AC(triggerMode, tmp_active, false);
            for (int board = 0; board < boardsPerCC; board++)
                if (DC_ACTIVE[board]) {
                    cout << endl << "AC/DC #" << board << ":";
                    get_AC_info(true, board);
                }
            //manage_cc_fifo(1);
        } else if (device == 100) {          //all devices

            read_AC(triggerMode, DC_ACTIVE, false, true);
            for (int board = 0; board < numFrontBoards; board++)
                if (DC_ACTIVE[board]) {
                    cout << endl << "AC/DC #" << board << ":";
                    get_AC_info(true, board);
                }
            //manage_cc_fifo(1);
            //if(mode == USB2x) manage_cc_fifo_slaveDevice(1);
        }
        sys_wait(5000);
        manage_cc_fifo(1);
        if (mode == USB2x) manage_cc_fifo_slaveDevice(1);
    }

    if (SHOW_CC_STATUS) cout << "\n**********************\n";

    //if(device)  usb2.freeHandles();
    //else        usb.freeHandles();

    if (print) cout << "retval, if success is ram_events = " << ram_events << endl;
    return ram_events;
}
<commit_msg>fixed issue where active DC was not initialized causing fake detection<commit_after>#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <fstream>
#include <iomanip>
#include <string.h>
#include <math.h>
#include "SuMo.h"

using namespace std;

int SuMo::read_CC(bool SHOW_CC_STATUS, bool SHOW_AC_STATUS, int device, int triggerMode) {

    bool print = false; // verbose
    int samples;        // no. of words in usb packet
    int samples_device_0, samples_device_1;

    if (device == 0)
        for (int i = 0; i < 4; i++) {
            EVENT_FLAG[i] = false;
            DIGITIZING_START_FLAG[i] = false;
        }
    else if (device == 1)
        for (int i = 4; i < numFrontBoards; i++) {
            EVENT_FLAG[i] = false;
            DIGITIZING_START_FLAG[i] = false;
        }
    else if (device == 100) {  //device = 100 for all boards in system
        for (int i = 0; i < numFrontBoards; i++) {
            EVENT_FLAG[i] = false;
            DIGITIZING_START_FLAG[i] = false;
        }
        if (print) cout << "using device = 100, ALL devices " << endl;
    } else return -3; // device assignment error

    /* device = 1 for slave device */
    if (device > 1 && mode != USB2x) return -2;

    /* set usb read mode for numFrontBoards+1 (central card readout-only) */
    if (device == 0) set_usb_read_mode(5);
    else if (device == 1) set_usb_read_mode_slaveDevice(5);
    else if (device == 100) {
        if (SHOW_CC_STATUS) cout << "master CC connected." << endl;
        if (mode == USB2x) {
            set_usb_read_mode_slaveDevice(5);
            if (SHOW_CC_STATUS) cout << "slave CC connected." << endl;
        }
        set_usb_read_mode(5);
    } else return -3;

    int ram_events = 0;
    int num_devices = 1;
    int device_tmp = device;
    if (device == 100) {
        num_devices = 2;
        device_tmp = 0;
    } else {
        num_devices = 1;
        device_tmp = device;
    }

    for (int loop_cc = device_tmp; loop_cc < device_tmp + num_devices; loop_cc++) {

        if (print) cout << "device in central card address loop : " << loop_cc << endl;

        unsigned short buffer[cc_buffersize];
        memset(buffer, 0x0, cc_buffersize * sizeof(unsigned short));
        /* try readout */
        try {
            if (loop_cc == 0) {
                usb.readData(buffer, cc_buffersize + 2, &samples);
                samples_device_0 = samples;
            } else if (loop_cc == 1) {
                usb2.readData(buffer, cc_buffersize + 2, &samples);
                samples_device_1 = samples;
            }

            if (samples < 2 && device != 100) {
                if (print) cout << "error: no data in buffer on device #" << device << endl;
                return -1;
            }

            int cc_header_found = -1;
            int cc_start_found = -1;

            for (int i = 0; i < 5; i++) {
                if (buffer[i] == 0x1234) {
                    cc_header_found = i;
                    if (print) cout << "cc header @ " << i << endl;
                }
                if (buffer[i] == 0xDEAD) {
                    cc_start_found = i;
                    if (print) cout << "cc start @ " << i << endl;
                }
            }
            if (loop_cc == 0) {
                CC_EVENT_COUNT_FROMCC0 = buffer[5];
                if (SHOW_CC_STATUS) cout << "master event = " << buffer[5] << endl;
            }
            if (loop_cc == 1) {
                CC_EVENT_COUNT_FROMCC1 = buffer[5];
                if (SHOW_CC_STATUS) cout << "slave event = " << buffer[5] << endl;
            }

            for (int i = 0; i < cc_buffersize; i++) {
                CC_INFO[i] = buffer[i];
                if (print) cout << i << ":" << buffer[i] << " ";
            }
            if (print) cout << "samples received: " << samples << " on device #" << device << endl;
        }
        catch (...) {
            fprintf(stderr, "Please connect the board. [DEFAULT exception] \n");
            return 1;
        }

        if (SHOW_CC_STATUS) {
            cout << endl;
            if (device > 0) cout << "AC/DC connection status :: Slave Device: \n";
            else cout << "AC/DC connection status: \n";
        }

        // Initialize DC_ACTIVE to false
        for (int ac = 0; ac < numFrontBoards; ac++) {
            DC_ACTIVE[ac] = false;
        }

        int slave_index = loop_cc * boardsPerCC;
        /* look for ACDC boards, set global variable DC_ACTIVE[numFrontBoards] */
        // add second handle for DC_ACTIVE
        if ((buffer[2] & 0x1) && (buffer[2] & 0x11)) {
            DC_ACTIVE[0 + slave_index] = true;
            if (SHOW_CC_STATUS) cout << "* DC 0 detected!! \n";
        }
        if ((buffer[2] & 0x2) && (buffer[2] & 0x22)) {
            DC_ACTIVE[1 + slave_index] = true;
            if (SHOW_CC_STATUS) cout << "* DC 1 detected!! \n";
        }
        if ((buffer[2] & 0x4) && (buffer[2] & 0x44)) {
            DC_ACTIVE[2 + slave_index] = true;
            if (SHOW_CC_STATUS) cout << "* DC 2 detected!! \n";
        }
        if ((buffer[2] & 0x8) && (buffer[2] & 0x88)) {
            DC_ACTIVE[3 + slave_index] = true;
            if (SHOW_CC_STATUS) cout << "* DC 3 detected!! \n";
        }

        // TODO the above will have to be extended when switching to ACC

        //check for events in CC RAM
        if (buffer[4] & 0x1) EVENT_FLAG[0 + slave_index] = true;
        if (buffer[4] & 0x2) EVENT_FLAG[1 + slave_index] = true;
        if (buffer[4] & 0x4) EVENT_FLAG[2 + slave_index] = true;
        if (buffer[4] & 0x8) EVENT_FLAG[3 + slave_index] = true;

        ram_events += EVENT_FLAG[0 + slave_index] +
                EVENT_FLAG[1 + slave_index] +
                EVENT_FLAG[2 + slave_index] +
                EVENT_FLAG[3 + slave_index];

        if (buffer[4] >> 4 & 0x1) DIGITIZING_START_FLAG[0 + slave_index] = true;
        if (buffer[4] >> 4 & 0x2) DIGITIZING_START_FLAG[1 + slave_index] = true;
        if (buffer[4] >> 4 & 0x4) DIGITIZING_START_FLAG[2 + slave_index] = true;
        if (buffer[4] >> 4 & 0x8) DIGITIZING_START_FLAG[3 + slave_index] = true;

    }  //end loop over central cards
//probe ac/dc cards if specified
    if (SHOW_AC_STATUS) {
        bool tmp_active[numFrontBoards];
        for (int ii = 0; ii < numFrontBoards; ii++) tmp_active[ii] = false; //mask off master or slave board for printing info

        if (device == 1) {     //slave device
            for (int board = boardsPerCC; board < numFrontBoards; board++) tmp_active[board] = DC_ACTIVE[board];

            read_AC(triggerMode, tmp_active, false);
            for (int board = boardsPerCC; board < numFrontBoards; board++)
                if (DC_ACTIVE[board]) {
                    cout << endl << "AC/DC #" << board << ":";
                    get_AC_info(true, board);
                }
            //manage_cc_fifo_slaveDevice(1);
        } else if (device == 0) {          //master device
            for (int board = 0; board < boardsPerCC; board++) tmp_active[board] = DC_ACTIVE[board];

            read_AC(triggerMode, tmp_active, false);
            for (int board = 0; board < boardsPerCC; board++) {
                if (DC_ACTIVE[board]) {
                    cout << endl << "AC/DC #" << board << ":";
                    get_AC_info(true, board);
                }
            }
            //manage_cc_fifo(1);
        } else if (device == 100) {          //all devices

            read_AC(triggerMode, DC_ACTIVE, false, true);
            for (int board = 0; board < numFrontBoards; board++)
                if (DC_ACTIVE[board]) {
                    cout << endl << "AC/DC #" << board << ":";
                    get_AC_info(true, board);
                }
            //manage_cc_fifo(1);
            //if(mode == USB2x) manage_cc_fifo_slaveDevice(1);
        }
        sys_wait(5000);
        manage_cc_fifo(1);
        if (mode == USB2x) manage_cc_fifo_slaveDevice(1);
    }

    if (SHOW_CC_STATUS) cout << "\n**********************\n";

    //if(device)  usb2.freeHandles();
    //else        usb.freeHandles();

    if (print) cout << "retval, if success is ram_events = " << ram_events << endl;
    return ram_events;
}
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "distributor_bucket_space.h"
#include "bucketownership.h"
#include <vespa/storage/bucketdb/btree_bucket_database.h>
#include <vespa/vdslib/state/clusterstate.h>
#include <vespa/vdslib/distribution/distribution.h>
#include <vespa/vespalib/stllike/hash_map.hpp>

namespace storage::distributor {

namespace {

const char *up_states = "uri";
const char *nonretired_up_states = "ui";
const char *nonretired_or_maintenance_up_states = "uim";

}

DistributorBucketSpace::DistributorBucketSpace()
    : DistributorBucketSpace(0u)
{
}

DistributorBucketSpace::DistributorBucketSpace(uint16_t node_index)
    : _bucketDatabase(std::make_unique<BTreeBucketDatabase>()),
      _clusterState(),
      _distribution(),
      _node_index(node_index),
      _distribution_bits(1u),
      _pending_cluster_state(),
      _available_nodes(),
      _ownerships(),
      _ideal_nodes()
{
}

DistributorBucketSpace::~DistributorBucketSpace() = default;

void
DistributorBucketSpace::clear()
{
    _ownerships.clear();
    _ideal_nodes.clear();
}

void
DistributorBucketSpace::enumerate_available_nodes()
{
    _distribution_bits = _clusterState->getDistributionBitCount();
    auto node_count = _clusterState->getNodeCount(lib::NodeType::STORAGE);
    if (_pending_cluster_state) {
        _distribution_bits = std::min(_distribution_bits, _pending_cluster_state->getDistributionBitCount());
        node_count = std::min(node_count, _pending_cluster_state->getNodeCount(lib::NodeType::STORAGE));
    }
    std::vector<bool> nodes(node_count);
    for (uint32_t i = 0; i < node_count; ++i) {
        lib::Node node_key(lib::NodeType::STORAGE, i);
        const lib::NodeState& ns(_clusterState->getNodeState(node_key));
        if (ns.getState().oneOf(up_states)) {
            if (!_pending_cluster_state || _pending_cluster_state->getNodeState(node_key).getState().oneOf(up_states)) {
                nodes[i] = true;
            }
        }
    }
    _available_nodes = std::move(nodes);
}

void
DistributorBucketSpace::setClusterState(std::shared_ptr<const lib::ClusterState> clusterState)
{
    _clusterState = std::move(clusterState);
    clear();
    enumerate_available_nodes();
}

void
DistributorBucketSpace::setDistribution(std::shared_ptr<const lib::Distribution> distribution) {
    _distribution = std::move(distribution);
    clear();
}

void
DistributorBucketSpace::set_pending_cluster_state(std::shared_ptr<const lib::ClusterState> pending_cluster_state)
{
    _pending_cluster_state = std::move(pending_cluster_state);
    clear();
    enumerate_available_nodes();
}

bool
DistributorBucketSpace::owns_bucket_in_state(
        const lib::Distribution& distribution,
        const lib::ClusterState& cluster_state,
        document::BucketId bucket) const
{
    try {
        uint16_t distributor = distribution.getIdealDistributorNode(cluster_state, bucket);

        return (_node_index == distributor);
    } catch (lib::TooFewBucketBitsInUseException& e) {
        return false;
    } catch (lib::NoDistributorsAvailableException& e) {
        return false;
    }
}

bool
DistributorBucketSpace::owns_bucket_in_state(
        const lib::ClusterState& clusterState,
        document::BucketId bucket) const
{
    return owns_bucket_in_state(*_distribution, clusterState, bucket);
}

const IdealServiceLayerNodesBundle&
DistributorBucketSpace::get_ideal_service_layer_nodes_bundle(document::BucketId bucket) const
{
    assert(bucket.getUsedBits() >= _distribution_bits);
    document::BucketId lookup_bucket((bucket.getUsedBits() > 33) ? bucket.getUsedBits() : _distribution_bits, bucket.getId());
    auto itr = _ideal_nodes.find(lookup_bucket);
    if (itr != _ideal_nodes.end()) {
        return itr->second;
    }
    IdealServiceLayerNodesBundle ideal_nodes_bundle;
    ideal_nodes_bundle.set_available_nodes(_distribution->getIdealStorageNodes(*_clusterState, bucket, up_states));
    ideal_nodes_bundle.set_available_nonretired_nodes(_distribution->getIdealStorageNodes(*_clusterState, bucket, nonretired_up_states));
    ideal_nodes_bundle.set_available_nonretired_or_maintenance_nodes(_distribution->getIdealStorageNodes(*_clusterState, bucket, nonretired_or_maintenance_up_states));
    auto insres = _ideal_nodes.insert(std::make_pair(lookup_bucket, std::move(ideal_nodes_bundle)));
    assert(insres.second);
    return insres.first->second;
}

BucketOwnershipFlags
DistributorBucketSpace::get_bucket_ownership_flags(document::BucketId bucket) const
{
    if (bucket.getUsedBits() < _distribution_bits) {
        BucketOwnershipFlags flags;
        if (!_pending_cluster_state) {
            flags.set_owned_in_pending_state();
        }
        return flags;
    }
    document::BucketId super_bucket(_distribution_bits, bucket.getId());
    auto itr = _ownerships.find(super_bucket);
    if (itr != _ownerships.end()) {
        return itr->second;
    }
    BucketOwnershipFlags flags;
    if (!_pending_cluster_state || owns_bucket_in_state(*_distribution, *_pending_cluster_state, super_bucket)) {
        flags.set_owned_in_pending_state();
    }
    if (owns_bucket_in_state(*_distribution, *_clusterState, super_bucket)) {
        flags.set_owned_in_current_state();
    }
    auto insres = _ownerships.insert(std::make_pair(super_bucket, flags));
    assert(insres.second);
    return insres.first->second;
}

BucketOwnership
DistributorBucketSpace::check_ownership_in_pending_and_current_state(document::BucketId bucket) const
{
    auto flags = get_bucket_ownership_flags(bucket);
    if (!flags.owned_in_pending_state()) {
        assert(_pending_cluster_state);
        return BucketOwnership::createNotOwnedInState(*_pending_cluster_state);
    }
    if (flags.owned_in_current_state()) {
        return BucketOwnership::createOwned();
    } else {
        return BucketOwnership::createNotOwnedInState(*_clusterState);
    }
}

}
<commit_msg>Don't store variants of ideal service layer nodes in hash if bucket used bits > 33.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "distributor_bucket_space.h"
#include "bucketownership.h"
#include <vespa/storage/bucketdb/btree_bucket_database.h>
#include <vespa/vdslib/state/clusterstate.h>
#include <vespa/vdslib/distribution/distribution.h>
#include <vespa/vespalib/stllike/hash_map.hpp>

namespace storage::distributor {

namespace {

const char *up_states = "uri";
const char *nonretired_up_states = "ui";
const char *nonretired_or_maintenance_up_states = "uim";

}

DistributorBucketSpace::DistributorBucketSpace()
    : DistributorBucketSpace(0u)
{
}

DistributorBucketSpace::DistributorBucketSpace(uint16_t node_index)
    : _bucketDatabase(std::make_unique<BTreeBucketDatabase>()),
      _clusterState(),
      _distribution(),
      _node_index(node_index),
      _distribution_bits(1u),
      _pending_cluster_state(),
      _available_nodes(),
      _ownerships(),
      _ideal_nodes()
{
}

DistributorBucketSpace::~DistributorBucketSpace() = default;

void
DistributorBucketSpace::clear()
{
    _ownerships.clear();
    _ideal_nodes.clear();
}

void
DistributorBucketSpace::enumerate_available_nodes()
{
    _distribution_bits = _clusterState->getDistributionBitCount();
    auto node_count = _clusterState->getNodeCount(lib::NodeType::STORAGE);
    if (_pending_cluster_state) {
        _distribution_bits = std::min(_distribution_bits, _pending_cluster_state->getDistributionBitCount());
        node_count = std::min(node_count, _pending_cluster_state->getNodeCount(lib::NodeType::STORAGE));
    }
    std::vector<bool> nodes(node_count);
    for (uint32_t i = 0; i < node_count; ++i) {
        lib::Node node_key(lib::NodeType::STORAGE, i);
        const lib::NodeState& ns(_clusterState->getNodeState(node_key));
        if (ns.getState().oneOf(up_states)) {
            if (!_pending_cluster_state || _pending_cluster_state->getNodeState(node_key).getState().oneOf(up_states)) {
                nodes[i] = true;
            }
        }
    }
    _available_nodes = std::move(nodes);
}

void
DistributorBucketSpace::setClusterState(std::shared_ptr<const lib::ClusterState> clusterState)
{
    _clusterState = std::move(clusterState);
    clear();
    enumerate_available_nodes();
}

void
DistributorBucketSpace::setDistribution(std::shared_ptr<const lib::Distribution> distribution) {
    _distribution = std::move(distribution);
    clear();
}

void
DistributorBucketSpace::set_pending_cluster_state(std::shared_ptr<const lib::ClusterState> pending_cluster_state)
{
    _pending_cluster_state = std::move(pending_cluster_state);
    clear();
    enumerate_available_nodes();
}

bool
DistributorBucketSpace::owns_bucket_in_state(
        const lib::Distribution& distribution,
        const lib::ClusterState& cluster_state,
        document::BucketId bucket) const
{
    try {
        uint16_t distributor = distribution.getIdealDistributorNode(cluster_state, bucket);

        return (_node_index == distributor);
    } catch (lib::TooFewBucketBitsInUseException& e) {
        return false;
    } catch (lib::NoDistributorsAvailableException& e) {
        return false;
    }
}

bool
DistributorBucketSpace::owns_bucket_in_state(
        const lib::ClusterState& clusterState,
        document::BucketId bucket) const
{
    return owns_bucket_in_state(*_distribution, clusterState, bucket);
}

namespace {

void
setup_ideal_nodes_bundle(IdealServiceLayerNodesBundle& ideal_nodes_bundle,
                         const lib::Distribution& distribution,
                         const lib::ClusterState& cluster_state,
                         document::BucketId bucket)
{
    ideal_nodes_bundle.set_available_nodes(distribution.getIdealStorageNodes(cluster_state, bucket, up_states));
    ideal_nodes_bundle.set_available_nonretired_nodes(distribution.getIdealStorageNodes(cluster_state, bucket, nonretired_up_states));
    ideal_nodes_bundle.set_available_nonretired_or_maintenance_nodes(distribution.getIdealStorageNodes(cluster_state, bucket, nonretired_or_maintenance_up_states));
}

// Ideal service layer nodes bundle used when bucket id used bits > 33.
thread_local IdealServiceLayerNodesBundle fallback_ideal_nodes_bundle;

}

const IdealServiceLayerNodesBundle&
DistributorBucketSpace::get_ideal_service_layer_nodes_bundle(document::BucketId bucket) const
{
    assert(bucket.getUsedBits() >= _distribution_bits);
    if (bucket.getUsedBits() > 33) {
        IdealServiceLayerNodesBundle &ideal_nodes_bundle = fallback_ideal_nodes_bundle;
        setup_ideal_nodes_bundle(ideal_nodes_bundle, *_distribution, *_clusterState, bucket);
        return ideal_nodes_bundle;
    }
    document::BucketId lookup_bucket((bucket.getUsedBits() > 33) ? bucket.getUsedBits() : _distribution_bits, bucket.getId());
    auto itr = _ideal_nodes.find(lookup_bucket);
    if (itr != _ideal_nodes.end()) {
        return itr->second;
    }
    IdealServiceLayerNodesBundle ideal_nodes_bundle;
    setup_ideal_nodes_bundle(ideal_nodes_bundle, *_distribution, *_clusterState, lookup_bucket);
    auto insres = _ideal_nodes.insert(std::make_pair(lookup_bucket, std::move(ideal_nodes_bundle)));
    assert(insres.second);
    return insres.first->second;
}

BucketOwnershipFlags
DistributorBucketSpace::get_bucket_ownership_flags(document::BucketId bucket) const
{
    if (bucket.getUsedBits() < _distribution_bits) {
        BucketOwnershipFlags flags;
        if (!_pending_cluster_state) {
            flags.set_owned_in_pending_state();
        }
        return flags;
    }
    document::BucketId super_bucket(_distribution_bits, bucket.getId());
    auto itr = _ownerships.find(super_bucket);
    if (itr != _ownerships.end()) {
        return itr->second;
    }
    BucketOwnershipFlags flags;
    if (!_pending_cluster_state || owns_bucket_in_state(*_distribution, *_pending_cluster_state, super_bucket)) {
        flags.set_owned_in_pending_state();
    }
    if (owns_bucket_in_state(*_distribution, *_clusterState, super_bucket)) {
        flags.set_owned_in_current_state();
    }
    auto insres = _ownerships.insert(std::make_pair(super_bucket, flags));
    assert(insres.second);
    return insres.first->second;
}

BucketOwnership
DistributorBucketSpace::check_ownership_in_pending_and_current_state(document::BucketId bucket) const
{
    auto flags = get_bucket_ownership_flags(bucket);
    if (!flags.owned_in_pending_state()) {
        assert(_pending_cluster_state);
        return BucketOwnership::createNotOwnedInState(*_pending_cluster_state);
    }
    if (flags.owned_in_current_state()) {
        return BucketOwnership::createOwned();
    } else {
        return BucketOwnership::createNotOwnedInState(*_clusterState);
    }
}

}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include "exp.h"

int main( int argc , char **argv )
{
    testing :: InitGoogleTest( &argc , argv ) ;
    return RUN_ALL_TESTS( ) ;
}
<commit_msg>Delete mainExp.cpp<commit_after><|endoftext|>


<commit_before>// @(#)root/utils:$Id$
// Author: Philippe Canal 27/08/2003

/*************************************************************************
 * Copyright (C) 1995-2003, Rene Brun, Fons Rademakers, and al.          *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS              *
 *************************************************************************/

#include "RConfigure.h"
#include "RConfig.h"

#include "RStl.h"
#include "TClassEdit.h"
#include "TMetaUtils.h"
using namespace TClassEdit;

#include <stdio.h>

#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"

#include "Scanner.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"

#include "clang/Sema/Sema.h"
#include "clang/Sema/Template.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/AST/DeclTemplate.h"

#ifndef ROOT_Varargs
#include "Varargs.h"
#endif

//
// ROOT::Internal::RStl is the rootcint STL handling class.
//

static int fgCount = 0;

ROOT::Internal::RStl& ROOT::Internal::RStl::Instance()
{
   // Return the singleton ROOT::Internal::RStl.

   static ROOT::Internal::RStl instance;
   return instance;

}

void ROOT::Internal::RStl::GenerateTClassFor(const clang::QualType &type, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
{
   // Force the generation of the TClass for the given class.

   clang::QualType thisType = type;

   auto typePtr = thisType.getTypePtr();
   const clang::CXXRecordDecl *stlclass = typePtr->getAsCXXRecordDecl();
   if (!stlclass) {
      return;
   }

   // Transform the type to the corresponding one for IO
   auto typeForIO = ROOT::TMetaUtils::GetTypeForIO(thisType, interp, normCtxt);
   if (typeForIO.getTypePtr() != typePtr)
      stlclass = typeForIO->getAsCXXRecordDecl();
   if (!stlclass) {
      return;
   }
   thisType = typeForIO;

   const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);

   if (!templateCl) {
      ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
            ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
   }

   if ( TClassEdit::STLKind( stlclass->getName().str().c_str() )  == ROOT::kSTLvector ) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
         if (decl) {
            // NOTE: we should just compare the decl to the bool builtin!
            llvm::StringRef argname = decl->getName();
            if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
               ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
            }
         }
      }
   }

   fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,
                                                       thisType.getTypePtr(),
                                                       stlclass,
                                                       "",
                                                       false /* for backward compatibility rather than 'true' .. neither really make a difference */,
                                                       false,
                                                       false,
                                                       false,
                                                       -1,
                                                       interp,
                                                       normCtxt) );

   // fprintf(stderr,"Registered the STL class %s as needing a dictionary\n",R__GetQualifiedName(*stlclass).c_str());

   for(unsigned int i=0; i <  templateCl->getTemplateArgs().size(); ++i) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();

         if (decl && TClassEdit::STLKind( decl->getName().str().c_str() ) != 0 )
            {
               const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
               if (clxx) {
                  if (!clxx->isCompleteDefinition()) {
                     /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation(), arg.getAsType());
                  }
                  // Do we need to strip the qualifier?
                  GenerateTClassFor(arg.getAsType(),interp,normCtxt);
               }
            }
      }
   }
}

void ROOT::Internal::RStl::GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlclass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
{
   // Force the generation of the TClass for the given class.
   const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);

   if (templateCl == 0) {
      ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
            ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
   }

   if ( TClassEdit::STLKind( stlclass->getName().str().c_str() )  == ROOT::kSTLvector ) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
         if (decl) {
            // NOTE: we should just compare the decl to the bool builtin!
            llvm::StringRef argname = decl->getName();
            if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
               ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
            }
         }
      }
   }

   fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,stlclass,requestedName,true,false,false,false,-1, interp,normCtxt) );

   TClassEdit::TSplitType splitType( requestedName, (TClassEdit::EModType)(TClassEdit::kLong64 | TClassEdit::kDropStd) );
   for(unsigned int i=0; i <  templateCl->getTemplateArgs().size(); ++i) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();

         if (decl && TClassEdit::STLKind( decl->getName().str().c_str() ) != 0 )
            {
               const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
               if (clxx) {
                  if (!clxx->isCompleteDefinition()) {
                     /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation (), arg.getAsType());
                     clxx = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
                  }
                  if (!splitType.fElements.empty()) {
                     GenerateTClassFor( splitType.fElements[i+1].c_str(), clxx, interp, normCtxt);
                  } else {
                     GenerateTClassFor( "", clxx, interp, normCtxt );
                  }
               }
            }
      }
   }

}

void ROOT::Internal::RStl::Print()
{
   // Print the content of the object
   fprintf(stderr,"ROOT::Internal::RStl singleton\n");
   list_t::iterator iter;
   for(iter = fList.begin(); iter != fList.end(); ++iter) {
      fprintf(stderr, "need TClass for %s\n", ROOT::TMetaUtils::GetQualifiedName(*(*iter)).c_str());
   }
}

void ROOT::Internal::RStl::WriteClassInit(std::ostream &ostr,
                                const cling::Interpreter &interp,
                                const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt,
                                const ROOT::TMetaUtils::RConstructorTypes& ctorTypes,
                                bool &needCollectionProxy,
                                void (*emitStreamerInfo)(const char*) )
{
   // This function writes the TGeneraticClassInfo initialiser
   // and the auxiliary functions (new and delete wrappers) for
   // each of the STL containers that have been registered

   list_t::iterator iter;
   for(iter = fList.begin(); iter != fList.end(); ++iter) {
      const clang::CXXRecordDecl* result;

      if (!iter->GetRecordDecl()->getDefinition()) {

         // We do not have a complete definition, we need to force the instantiation
         // and findScope can do that.
         const cling::LookupHelper& lh = interp.getLookupHelper();
         result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(iter->GetNormalizedName(),
                                                                            cling::LookupHelper::NoDiagnostics,
                                                                            0)
                                                               );

         if (!result || !iter->GetRecordDecl()->getDefinition()) {
            fprintf(stderr,"Error: incomplete definition for %s\n",iter->GetNormalizedName());
            continue;
         }
      }
      else
      {
         result = llvm::dyn_cast<clang::CXXRecordDecl>(iter->GetRecordDecl());
      }

      ROOT::TMetaUtils::WriteClassInit(ostr, *iter, result, interp, normCtxt, ctorTypes, needCollectionProxy);
      ROOT::TMetaUtils::WriteAuxFunctions(ostr, *iter, result, interp, ctorTypes, normCtxt);

      if (emitStreamerInfo) emitStreamerInfo(iter->GetNormalizedName());
   }
}
<commit_msg>Remove unnecessary include, breaking (invisible) laying.<commit_after>// @(#)root/utils:$Id$
// Author: Philippe Canal 27/08/2003

/*************************************************************************
 * Copyright (C) 1995-2003, Rene Brun, Fons Rademakers, and al.          *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS              *
 *************************************************************************/

#include "RConfigure.h"
#include "RConfig.h"

#include "RStl.h"
#include "TClassEdit.h"
#include "TMetaUtils.h"
using namespace TClassEdit;

#include <stdio.h>

#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"

#include "clang/Sema/Sema.h"
#include "clang/Sema/Template.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/AST/DeclTemplate.h"

#ifndef ROOT_Varargs
#include "Varargs.h"
#endif

//
// ROOT::Internal::RStl is the rootcint STL handling class.
//

static int fgCount = 0;

ROOT::Internal::RStl& ROOT::Internal::RStl::Instance()
{
   // Return the singleton ROOT::Internal::RStl.

   static ROOT::Internal::RStl instance;
   return instance;

}

void ROOT::Internal::RStl::GenerateTClassFor(const clang::QualType &type, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
{
   // Force the generation of the TClass for the given class.

   clang::QualType thisType = type;

   auto typePtr = thisType.getTypePtr();
   const clang::CXXRecordDecl *stlclass = typePtr->getAsCXXRecordDecl();
   if (!stlclass) {
      return;
   }

   // Transform the type to the corresponding one for IO
   auto typeForIO = ROOT::TMetaUtils::GetTypeForIO(thisType, interp, normCtxt);
   if (typeForIO.getTypePtr() != typePtr)
      stlclass = typeForIO->getAsCXXRecordDecl();
   if (!stlclass) {
      return;
   }
   thisType = typeForIO;

   const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);

   if (!templateCl) {
      ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
            ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
   }

   if ( TClassEdit::STLKind( stlclass->getName().str().c_str() )  == ROOT::kSTLvector ) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
         if (decl) {
            // NOTE: we should just compare the decl to the bool builtin!
            llvm::StringRef argname = decl->getName();
            if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
               ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
            }
         }
      }
   }

   fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,
                                                       thisType.getTypePtr(),
                                                       stlclass,
                                                       "",
                                                       false /* for backward compatibility rather than 'true' .. neither really make a difference */,
                                                       false,
                                                       false,
                                                       false,
                                                       -1,
                                                       interp,
                                                       normCtxt) );

   // fprintf(stderr,"Registered the STL class %s as needing a dictionary\n",R__GetQualifiedName(*stlclass).c_str());

   for(unsigned int i=0; i <  templateCl->getTemplateArgs().size(); ++i) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();

         if (decl && TClassEdit::STLKind( decl->getName().str().c_str() ) != 0 )
            {
               const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
               if (clxx) {
                  if (!clxx->isCompleteDefinition()) {
                     /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation(), arg.getAsType());
                  }
                  // Do we need to strip the qualifier?
                  GenerateTClassFor(arg.getAsType(),interp,normCtxt);
               }
            }
      }
   }
}

void ROOT::Internal::RStl::GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlclass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
{
   // Force the generation of the TClass for the given class.
   const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);

   if (templateCl == 0) {
      ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
            ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
   }

   if ( TClassEdit::STLKind( stlclass->getName().str().c_str() )  == ROOT::kSTLvector ) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
         if (decl) {
            // NOTE: we should just compare the decl to the bool builtin!
            llvm::StringRef argname = decl->getName();
            if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
               ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
            }
         }
      }
   }

   fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,stlclass,requestedName,true,false,false,false,-1, interp,normCtxt) );

   TClassEdit::TSplitType splitType( requestedName, (TClassEdit::EModType)(TClassEdit::kLong64 | TClassEdit::kDropStd) );
   for(unsigned int i=0; i <  templateCl->getTemplateArgs().size(); ++i) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();

         if (decl && TClassEdit::STLKind( decl->getName().str().c_str() ) != 0 )
            {
               const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
               if (clxx) {
                  if (!clxx->isCompleteDefinition()) {
                     /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation (), arg.getAsType());
                     clxx = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
                  }
                  if (!splitType.fElements.empty()) {
                     GenerateTClassFor( splitType.fElements[i+1].c_str(), clxx, interp, normCtxt);
                  } else {
                     GenerateTClassFor( "", clxx, interp, normCtxt );
                  }
               }
            }
      }
   }

}

void ROOT::Internal::RStl::Print()
{
   // Print the content of the object
   fprintf(stderr,"ROOT::Internal::RStl singleton\n");
   list_t::iterator iter;
   for(iter = fList.begin(); iter != fList.end(); ++iter) {
      fprintf(stderr, "need TClass for %s\n", ROOT::TMetaUtils::GetQualifiedName(*(*iter)).c_str());
   }
}

void ROOT::Internal::RStl::WriteClassInit(std::ostream &ostr,
                                const cling::Interpreter &interp,
                                const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt,
                                const ROOT::TMetaUtils::RConstructorTypes& ctorTypes,
                                bool &needCollectionProxy,
                                void (*emitStreamerInfo)(const char*) )
{
   // This function writes the TGeneraticClassInfo initialiser
   // and the auxiliary functions (new and delete wrappers) for
   // each of the STL containers that have been registered

   list_t::iterator iter;
   for(iter = fList.begin(); iter != fList.end(); ++iter) {
      const clang::CXXRecordDecl* result;

      if (!iter->GetRecordDecl()->getDefinition()) {

         // We do not have a complete definition, we need to force the instantiation
         // and findScope can do that.
         const cling::LookupHelper& lh = interp.getLookupHelper();
         result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(iter->GetNormalizedName(),
                                                                            cling::LookupHelper::NoDiagnostics,
                                                                            0)
                                                               );

         if (!result || !iter->GetRecordDecl()->getDefinition()) {
            fprintf(stderr,"Error: incomplete definition for %s\n",iter->GetNormalizedName());
            continue;
         }
      }
      else
      {
         result = llvm::dyn_cast<clang::CXXRecordDecl>(iter->GetRecordDecl());
      }

      ROOT::TMetaUtils::WriteClassInit(ostr, *iter, result, interp, normCtxt, ctorTypes, needCollectionProxy);
      ROOT::TMetaUtils::WriteAuxFunctions(ostr, *iter, result, interp, ctorTypes, normCtxt);

      if (emitStreamerInfo) emitStreamerInfo(iter->GetNormalizedName());
   }
}
<|endoftext|>