<commit_before>/*******************************************************************************
 * ALMA - Atacama Large Millimeter Array
 * Copyright (c) ESO - European Southern Observatory, 2011
 * (in the framework of the ALMA collaboration).
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *******************************************************************************/
/*************************************************************************
* E.S.O. - VLT project
*
* "@(#) $Id: acscomponentImpl.cpp,v 1.40 2012/05/02 09:48:14 bjeram Exp $"
*
* who       when        what
* --------  --------    --------------------------------------------------
* rcirami   2003-08-28  created
*/

#include "acscomponentImpl.h"
#include "loggingLogger.h"
#include "acsErrTypeComponent.h"
#include <string>

using namespace maci;
using namespace acscomponent;

//
// ACSComponent Constructor
//
ACSComponentImpl::ACSComponentImpl(
    const ACE_CString& name,
    maci::ContainerServices *containerServices) :
    Logging::Loggable(containerServices->getLogger()),
    m_name(name),
    m_containerServices_p(containerServices)
{
  ACS_TRACE("acscomponent::ACSComponentImpl::ACSComponentImpl");

  // Check if the ContainerServices is NULL
  // Now the ContainerServices is very important and does a lof things
  // and the component
  if (containerServices==NULL)
  {
    acsErrTypeComponent::InvalidContainerServicesExImpl ex(__FILE__,__LINE__,"acscomponent::ACSComponentImpl::ACSComponentImpl");
    throw ex;
  }
}

//
// ACSComponent Destructor
//
ACSComponentImpl::~ACSComponentImpl()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::~ACSComponentImpl");
}

/*********************** IDL interface **********************/

char *
ACSComponentImpl::name ()
{
  return CORBA::string_dup(m_name.c_str());
}

ACS::ComponentStates
ACSComponentImpl::componentState ()
{
  if (m_containerServices_p==NULL)
  {
    return ACS::COMPSTATE_UNKNOWN;
  }
  else if (m_containerServices_p->getComponentStateManager()==NULL)
  {
    return ACS::COMPSTATE_UNKNOWN;
  }
  else return m_containerServices_p->getComponentStateManager()->getCurrentState();
}

/********************** LifeCycle methods ***********************/

void ACSComponentImpl::initialize()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::initialize");
}

void ACSComponentImpl::execute()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::execute");
}

void ACSComponentImpl::cleanUp()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::cleanUp");
}

void ACSComponentImpl::aboutToAbort()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::cleanUp");
}

void ACSComponentImpl::__initialize()
{
   ACS_TRACE("acscomponent::ACSComponentImpl::__initialize");
    try
    {
        initialize();
    }
    catch (ACSErr::ACSbaseExImpl &ex)
    {
        throw acsErrTypeLifeCycle::LifeCycleExImpl(ex, __FILE__,__LINE__,"ACSComponentImpl::__initialize");
    }catch(const std::exception &stdex){
    	ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	ex.setWhat(stdex.what());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: initialize can throw just ACS based exceptions. Please check your code.");
    	throw lex;

    }catch( CORBA::SystemException &_ex )
    {
    	ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setMinor(_ex.minor());
    	corbaProblemEx.setCompletionStatus(_ex.completed());
    	corbaProblemEx.setInfo(_ex._info().c_str());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(corbaProblemEx, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: initialize can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch( CORBA::UserException &_ex )
    {
    	ACSErrTypeCommon::CORBAUserExceptionExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setInfo(_ex._info());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(__FILE__,__LINE__, __FUNCTION__);

    	lex.addData("WARNING:", "component lifecylce method: initialize can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch(...){

    	ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: initialize can throw just ACS based exceptions. Please check your code.");
        throw lex;
    }

}

void ACSComponentImpl::__execute()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::__execute");
/*
startAllThreads is not there but it might be goot to put there
so that all threads are just created in suspend mode and than startAllThreads would resume them
  if (getContainerServices()->getThreadManager()->startAllThreads() == false)
      {
      throw acsErrTypeLifeCycle::LifeCycleExImpl(ex,__FILE__,__LINE__,"ACSComponentImpl::__execute(): startAllThreads failed");
      }
*/
    try
    {
        execute();
    }
    catch (ACSErr::ACSbaseExImpl &ex)
    {
        throw acsErrTypeLifeCycle::LifeCycleExImpl(ex,__FILE__,__LINE__,"ACSComponentImpl::__execute");
    }catch(const std::exception &stdex){
    	ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	ex.setWhat(stdex.what());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: execute can throw just ACS based exceptions. Please check your code.");
    	throw lex;

    }catch( CORBA::SystemException &_ex )
    {
    	ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setMinor(_ex.minor());
    	corbaProblemEx.setCompletionStatus(_ex.completed());
    	corbaProblemEx.setInfo(_ex._info().c_str());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(corbaProblemEx, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: execute can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch( CORBA::UserException &_ex )
    {
    	ACSErrTypeCommon::CORBAUserExceptionExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setInfo(_ex._info());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(__FILE__,__LINE__, __FUNCTION__);

    	lex.addData("WARNING:", "component lifecylce method: execute can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch(...){

    	ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: execute can throw just ACS based exceptions. Please check your code.");
        throw lex;
    }

}

void ACSComponentImpl::__aboutToAbort()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::__aboutToAbort");
  if (getContainerServices()->getThreadManager()->stopAll() == false)
      {
      throw acsErrTypeLifeCycle::StoppingThreadsFailureExImpl(__FILE__,__LINE__,"ACSComponentImpl::__aboutToAbort");
      }

    try
    {
        aboutToAbort();
    }
    catch (ACSErr::ACSbaseExImpl &ex)
    {
        throw acsErrTypeLifeCycle::LifeCycleExImpl(ex,__FILE__,__LINE__,"ACSComponentImpl::__aboutToAbort");
    }catch(const std::exception &stdex){
    	ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	ex.setWhat(stdex.what());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: aboutToAbort can throw just ACS based exceptions. Please check your code.");
    	throw lex;

    }catch( CORBA::SystemException &_ex )
    {
    	ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setMinor(_ex.minor());
    	corbaProblemEx.setCompletionStatus(_ex.completed());
    	corbaProblemEx.setInfo(_ex._info().c_str());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(corbaProblemEx, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: aboutToAbort can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch( CORBA::UserException &_ex )
    {
    	ACSErrTypeCommon::CORBAUserExceptionExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setInfo(_ex._info());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(__FILE__,__LINE__, __FUNCTION__);

    	lex.addData("WARNING:", "component lifecylce method: aboutToAbort can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch(...){

    	ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: aboutToAbort can throw just ACS based exceptions. Please check your code.");
        throw lex;
    }

}

void ACSComponentImpl::__cleanUp()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::__cleanUp");

  try
      {
      cleanUp();
      }
  catch(ACSErr::ACSbaseExImpl &ex)
  {
	  throw acsErrTypeLifeCycle::LifeCycleExImpl(ex, __FILE__,__LINE__,"ACSComponentImpl::__cleanUp");
  }catch(const std::exception &stdex){
	  ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);
	  ex.setWhat(stdex.what());
	  acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
	  lex.addData("WARNING:", "component lifecylce method: cleanUp can throw just ACS based exceptions. Please check your code.");
	  throw lex;

  }catch( CORBA::SystemException &_ex )
  {
	  ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
	  corbaProblemEx.setMinor(_ex.minor());
	  corbaProblemEx.setCompletionStatus(_ex.completed());
	  corbaProblemEx.setInfo(_ex._info().c_str());
	  acsErrTypeLifeCycle::LifeCycleExImpl lex(corbaProblemEx, __FILE__,__LINE__, __FUNCTION__);
	  lex.addData("WARNING:", "component lifecylce method: cleanUp can throw just ACS based exceptions. Please check your code.");
	  throw lex;
  }catch( CORBA::UserException &_ex )
  {
	  ACSErrTypeCommon::CORBAUserExceptionExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
	  corbaProblemEx.setInfo(_ex._info());
	  acsErrTypeLifeCycle::LifeCycleExImpl lex(__FILE__,__LINE__, __FUNCTION__);

	  lex.addData("WARNING:", "component lifecylce method: cleanUp can throw just ACS based exceptions. Please check your code.");
	  throw lex;
  }catch(...){

	  ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);
	  acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
	  lex.addData("WARNING:", "component lifecylce method: cleanUp can throw just ACS based exceptions. Please check your code.");
	  throw lex;
  }

  // just in case if a user does not stop the threads we stop them here
  if (getContainerServices()->getThreadManager()->stopAll() == false)
      {
      throw acsErrTypeLifeCycle::StoppingThreadsFailureExImpl(__FILE__,__LINE__,"ACSComponentImpl::__cleanUp");
      }
}

/*******************************  protected methods *******************************/

maci::ContainerServices*
ACSComponentImpl::getContainerServices()
{
  return GetImpl(m_containerServices_p);
}

<commit_msg>name() builds the CORBA::string by getting the name of the component with componentName().<commit_after>/*******************************************************************************
 * ALMA - Atacama Large Millimeter Array
 * Copyright (c) ESO - European Southern Observatory, 2011
 * (in the framework of the ALMA collaboration).
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *******************************************************************************/
/*************************************************************************
* E.S.O. - VLT project
*
* "@(#) $Id: acscomponentImpl.cpp,v 1.41 2013/01/16 16:22:16 acaproni Exp $"
*
* who       when        what
* --------  --------    --------------------------------------------------
* rcirami   2003-08-28  created
*/

#include "acscomponentImpl.h"
#include "loggingLogger.h"
#include "acsErrTypeComponent.h"
#include <string>

using namespace maci;
using namespace acscomponent;

//
// ACSComponent Constructor
//
ACSComponentImpl::ACSComponentImpl(
    const ACE_CString& name,
    maci::ContainerServices *containerServices) :
    Logging::Loggable(containerServices->getLogger()),
    m_name(name),
    m_containerServices_p(containerServices)
{
  ACS_TRACE("acscomponent::ACSComponentImpl::ACSComponentImpl");

  // Check if the ContainerServices is NULL
  // Now the ContainerServices is very important and does a lof things
  // and the component
  if (containerServices==NULL)
  {
    acsErrTypeComponent::InvalidContainerServicesExImpl ex(__FILE__,__LINE__,"acscomponent::ACSComponentImpl::ACSComponentImpl");
    throw ex;
  }
}

//
// ACSComponent Destructor
//
ACSComponentImpl::~ACSComponentImpl()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::~ACSComponentImpl");
}

/*********************** IDL interface **********************/

char *
ACSComponentImpl::name ()
{
  return CORBA::string_dup(componentName());
}

ACS::ComponentStates
ACSComponentImpl::componentState ()
{
  if (m_containerServices_p==NULL)
  {
    return ACS::COMPSTATE_UNKNOWN;
  }
  else if (m_containerServices_p->getComponentStateManager()==NULL)
  {
    return ACS::COMPSTATE_UNKNOWN;
  }
  else return m_containerServices_p->getComponentStateManager()->getCurrentState();
}

/********************** LifeCycle methods ***********************/

void ACSComponentImpl::initialize()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::initialize");
}

void ACSComponentImpl::execute()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::execute");
}

void ACSComponentImpl::cleanUp()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::cleanUp");
}

void ACSComponentImpl::aboutToAbort()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::cleanUp");
}

void ACSComponentImpl::__initialize()
{
   ACS_TRACE("acscomponent::ACSComponentImpl::__initialize");
    try
    {
        initialize();
    }
    catch (ACSErr::ACSbaseExImpl &ex)
    {
        throw acsErrTypeLifeCycle::LifeCycleExImpl(ex, __FILE__,__LINE__,"ACSComponentImpl::__initialize");
    }catch(const std::exception &stdex){
    	ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	ex.setWhat(stdex.what());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: initialize can throw just ACS based exceptions. Please check your code.");
    	throw lex;

    }catch( CORBA::SystemException &_ex )
    {
    	ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setMinor(_ex.minor());
    	corbaProblemEx.setCompletionStatus(_ex.completed());
    	corbaProblemEx.setInfo(_ex._info().c_str());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(corbaProblemEx, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: initialize can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch( CORBA::UserException &_ex )
    {
    	ACSErrTypeCommon::CORBAUserExceptionExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setInfo(_ex._info());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(__FILE__,__LINE__, __FUNCTION__);

    	lex.addData("WARNING:", "component lifecylce method: initialize can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch(...){

    	ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: initialize can throw just ACS based exceptions. Please check your code.");
        throw lex;
    }

}

void ACSComponentImpl::__execute()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::__execute");
/*
startAllThreads is not there but it might be goot to put there
so that all threads are just created in suspend mode and than startAllThreads would resume them
  if (getContainerServices()->getThreadManager()->startAllThreads() == false)
      {
      throw acsErrTypeLifeCycle::LifeCycleExImpl(ex,__FILE__,__LINE__,"ACSComponentImpl::__execute(): startAllThreads failed");
      }
*/
    try
    {
        execute();
    }
    catch (ACSErr::ACSbaseExImpl &ex)
    {
        throw acsErrTypeLifeCycle::LifeCycleExImpl(ex,__FILE__,__LINE__,"ACSComponentImpl::__execute");
    }catch(const std::exception &stdex){
    	ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	ex.setWhat(stdex.what());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: execute can throw just ACS based exceptions. Please check your code.");
    	throw lex;

    }catch( CORBA::SystemException &_ex )
    {
    	ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setMinor(_ex.minor());
    	corbaProblemEx.setCompletionStatus(_ex.completed());
    	corbaProblemEx.setInfo(_ex._info().c_str());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(corbaProblemEx, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: execute can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch( CORBA::UserException &_ex )
    {
    	ACSErrTypeCommon::CORBAUserExceptionExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setInfo(_ex._info());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(__FILE__,__LINE__, __FUNCTION__);

    	lex.addData("WARNING:", "component lifecylce method: execute can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch(...){

    	ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: execute can throw just ACS based exceptions. Please check your code.");
        throw lex;
    }

}

void ACSComponentImpl::__aboutToAbort()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::__aboutToAbort");
  if (getContainerServices()->getThreadManager()->stopAll() == false)
      {
      throw acsErrTypeLifeCycle::StoppingThreadsFailureExImpl(__FILE__,__LINE__,"ACSComponentImpl::__aboutToAbort");
      }

    try
    {
        aboutToAbort();
    }
    catch (ACSErr::ACSbaseExImpl &ex)
    {
        throw acsErrTypeLifeCycle::LifeCycleExImpl(ex,__FILE__,__LINE__,"ACSComponentImpl::__aboutToAbort");
    }catch(const std::exception &stdex){
    	ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	ex.setWhat(stdex.what());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: aboutToAbort can throw just ACS based exceptions. Please check your code.");
    	throw lex;

    }catch( CORBA::SystemException &_ex )
    {
    	ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setMinor(_ex.minor());
    	corbaProblemEx.setCompletionStatus(_ex.completed());
    	corbaProblemEx.setInfo(_ex._info().c_str());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(corbaProblemEx, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: aboutToAbort can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch( CORBA::UserException &_ex )
    {
    	ACSErrTypeCommon::CORBAUserExceptionExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
    	corbaProblemEx.setInfo(_ex._info());
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(__FILE__,__LINE__, __FUNCTION__);

    	lex.addData("WARNING:", "component lifecylce method: aboutToAbort can throw just ACS based exceptions. Please check your code.");
    	throw lex;
    }catch(...){

    	ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);
    	acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
    	lex.addData("WARNING:", "component lifecylce method: aboutToAbort can throw just ACS based exceptions. Please check your code.");
        throw lex;
    }

}

void ACSComponentImpl::__cleanUp()
{
  ACS_TRACE("acscomponent::ACSComponentImpl::__cleanUp");

  try
      {
      cleanUp();
      }
  catch(ACSErr::ACSbaseExImpl &ex)
  {
	  throw acsErrTypeLifeCycle::LifeCycleExImpl(ex, __FILE__,__LINE__,"ACSComponentImpl::__cleanUp");
  }catch(const std::exception &stdex){
	  ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);
	  ex.setWhat(stdex.what());
	  acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
	  lex.addData("WARNING:", "component lifecylce method: cleanUp can throw just ACS based exceptions. Please check your code.");
	  throw lex;

  }catch( CORBA::SystemException &_ex )
  {
	  ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
	  corbaProblemEx.setMinor(_ex.minor());
	  corbaProblemEx.setCompletionStatus(_ex.completed());
	  corbaProblemEx.setInfo(_ex._info().c_str());
	  acsErrTypeLifeCycle::LifeCycleExImpl lex(corbaProblemEx, __FILE__,__LINE__, __FUNCTION__);
	  lex.addData("WARNING:", "component lifecylce method: cleanUp can throw just ACS based exceptions. Please check your code.");
	  throw lex;
  }catch( CORBA::UserException &_ex )
  {
	  ACSErrTypeCommon::CORBAUserExceptionExImpl corbaProblemEx(__FILE__, __LINE__, __FUNCTION__);
	  corbaProblemEx.setInfo(_ex._info());
	  acsErrTypeLifeCycle::LifeCycleExImpl lex(__FILE__,__LINE__, __FUNCTION__);

	  lex.addData("WARNING:", "component lifecylce method: cleanUp can throw just ACS based exceptions. Please check your code.");
	  throw lex;
  }catch(...){

	  ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);
	  acsErrTypeLifeCycle::LifeCycleExImpl lex(ex, __FILE__,__LINE__, __FUNCTION__);
	  lex.addData("WARNING:", "component lifecylce method: cleanUp can throw just ACS based exceptions. Please check your code.");
	  throw lex;
  }

  // just in case if a user does not stop the threads we stop them here
  if (getContainerServices()->getThreadManager()->stopAll() == false)
      {
      throw acsErrTypeLifeCycle::StoppingThreadsFailureExImpl(__FILE__,__LINE__,"ACSComponentImpl::__cleanUp");
      }
}

/*******************************  protected methods *******************************/

maci::ContainerServices*
ACSComponentImpl::getContainerServices()
{
  return GetImpl(m_containerServices_p);
}

<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software 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 "Gaffer/CompoundPlug.h"
#include "Gaffer/PlugIterator.h"

#include "GafferUI/ArrayNodule.h"
#include "GafferUI/LinearContainer.h"

#include "boost/bind.hpp"
#include "boost/bind/placeholders.hpp"

using namespace GafferUI;
using namespace Imath;
using namespace std;

IE_CORE_DEFINERUNTIMETYPED( ArrayNodule );

ArrayNodule::ArrayNodule( Gaffer::CompoundPlugPtr plug )
	:	Nodule( plug )
{
	m_row = new LinearContainer( "row", LinearContainer::X, LinearContainer::Centre, 0.0f );
	addChild( m_row );

	plug->childAddedSignal().connect( boost::bind( &ArrayNodule::childAdded, this, ::_1,  ::_2 ) );
	plug->childRemovedSignal().connect( boost::bind( &ArrayNodule::childRemoved, this, ::_1,  ::_2 ) );

	Gaffer::PlugIterator it = Gaffer::PlugIterator( plug->children().begin(), plug->children().end() );
	Gaffer::PlugIterator end = Gaffer::PlugIterator( plug->children().end(), plug->children().end() );
	for( ; it!=end; it++ )
	{
		NodulePtr nodule = Nodule::create( *it );
		if( nodule )
		{
			m_row->addChild( nodule );
		}
	}

	m_row->renderRequestSignal().connect( boost::bind( &ArrayNodule::childRenderRequest, this, ::_1 ) );
}

ArrayNodule::~ArrayNodule()
{
}

Imath::Box3f ArrayNodule::bound() const
{
	return m_row->bound();
}

void ArrayNodule::doRender( IECore::RendererPtr renderer ) const
{
	m_row->render( renderer );
}

bool ArrayNodule::acceptsChild( Gaffer::ConstGraphComponentPtr potentialChild ) const
{
	return children().size()==0;
}

NodulePtr ArrayNodule::nodule( Gaffer::ConstPlugPtr plug )
{
	ChildNoduleIterator it = ChildNoduleIterator( m_row->children().begin(), m_row->children().end() );
	ChildNoduleIterator end = ChildNoduleIterator( m_row->children().end(), m_row->children().end() );
	for( ; it!=end; it++ )
	{
		if( (*it)->plug() == plug )
		{
			return *it;
		}
	}
	return 0;
}

ConstNodulePtr ArrayNodule::nodule( Gaffer::ConstPlugPtr plug ) const
{
	// preferring the nasty casts over mainaining two nearly identical implementations
	return const_cast<ArrayNodule *>( this )->nodule( plug );
}

void ArrayNodule::childAdded( Gaffer::GraphComponentPtr parent, Gaffer::GraphComponentPtr child )
{
	Gaffer::PlugPtr plug = IECore::runTimeCast<Gaffer::Plug>( child );
	if( !plug )
	{
		return;
	}

	NodulePtr nodule = Nodule::create( plug );
	if( nodule )
	{
		m_row->addChild( nodule );
	}
}

void ArrayNodule::childRemoved( Gaffer::GraphComponentPtr parent, Gaffer::GraphComponentPtr child )
{
	Gaffer::PlugPtr plug = IECore::runTimeCast<Gaffer::Plug>( child );
	if( !plug )
	{
		return;
	}

	ChildNoduleIterator it = ChildNoduleIterator( m_row->children().begin(), m_row->children().end() );
	ChildNoduleIterator end = ChildNoduleIterator( m_row->children().end(), m_row->children().end() );
	for( ; it!=end; it++ )
	{
		if( (*it)->plug() == plug )
		{
			m_row->removeChild( *it );
			break;
		}
	}
}

void ArrayNodule::childRenderRequest( Gadget *child )
{
	renderRequestSignal()( this );
}
<commit_msg>Removing whitespace.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software 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 "Gaffer/CompoundPlug.h"
#include "Gaffer/PlugIterator.h"

#include "GafferUI/ArrayNodule.h"
#include "GafferUI/LinearContainer.h"

#include "boost/bind.hpp"
#include "boost/bind/placeholders.hpp"

using namespace GafferUI;
using namespace Imath;
using namespace std;

IE_CORE_DEFINERUNTIMETYPED( ArrayNodule );

ArrayNodule::ArrayNodule( Gaffer::CompoundPlugPtr plug )
	:	Nodule( plug )
{
	m_row = new LinearContainer( "row", LinearContainer::X, LinearContainer::Centre, 0.0f );
	addChild( m_row );

	plug->childAddedSignal().connect( boost::bind( &ArrayNodule::childAdded, this, ::_1,  ::_2 ) );
	plug->childRemovedSignal().connect( boost::bind( &ArrayNodule::childRemoved, this, ::_1,  ::_2 ) );

	Gaffer::PlugIterator it = Gaffer::PlugIterator( plug->children().begin(), plug->children().end() );
	Gaffer::PlugIterator end = Gaffer::PlugIterator( plug->children().end(), plug->children().end() );
	for( ; it!=end; it++ )
	{
		NodulePtr nodule = Nodule::create( *it );
		if( nodule )
		{
			m_row->addChild( nodule );
		}
	}

	m_row->renderRequestSignal().connect( boost::bind( &ArrayNodule::childRenderRequest, this, ::_1 ) );
}

ArrayNodule::~ArrayNodule()
{
}

Imath::Box3f ArrayNodule::bound() const
{
	return m_row->bound();
}

void ArrayNodule::doRender( IECore::RendererPtr renderer ) const
{
	m_row->render( renderer );
}

bool ArrayNodule::acceptsChild( Gaffer::ConstGraphComponentPtr potentialChild ) const
{
	return children().size()==0;
}

NodulePtr ArrayNodule::nodule( Gaffer::ConstPlugPtr plug )
{
	ChildNoduleIterator it = ChildNoduleIterator( m_row->children().begin(), m_row->children().end() );
	ChildNoduleIterator end = ChildNoduleIterator( m_row->children().end(), m_row->children().end() );
	for( ; it!=end; it++ )
	{
		if( (*it)->plug() == plug )
		{
			return *it;
		}
	}
	return 0;
}

ConstNodulePtr ArrayNodule::nodule( Gaffer::ConstPlugPtr plug ) const
{
	// preferring the nasty casts over mainaining two nearly identical implementations
	return const_cast<ArrayNodule *>( this )->nodule( plug );
}

void ArrayNodule::childAdded( Gaffer::GraphComponentPtr parent, Gaffer::GraphComponentPtr child )
{
	Gaffer::PlugPtr plug = IECore::runTimeCast<Gaffer::Plug>( child );
	if( !plug )
	{
		return;
	}

	NodulePtr nodule = Nodule::create( plug );
	if( nodule )
	{
		m_row->addChild( nodule );
	}
}

void ArrayNodule::childRemoved( Gaffer::GraphComponentPtr parent, Gaffer::GraphComponentPtr child )
{
	Gaffer::PlugPtr plug = IECore::runTimeCast<Gaffer::Plug>( child );
	if( !plug )
	{
		return;
	}

	ChildNoduleIterator it = ChildNoduleIterator( m_row->children().begin(), m_row->children().end() );
	ChildNoduleIterator end = ChildNoduleIterator( m_row->children().end(), m_row->children().end() );
	for( ; it!=end; it++ )
	{
		if( (*it)->plug() == plug )
		{
			m_row->removeChild( *it );
			break;
		}
	}
}

void ArrayNodule::childRenderRequest( Gadget *child )
{
	renderRequestSignal()( this );
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AreaChartType.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 18:43:44 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "AreaChartType.hxx"
#include "macros.hxx"
#include "servicenames_charttypes.hxx"

using namespace ::com::sun::star;

namespace chart
{

AreaChartType::AreaChartType(
    const uno::Reference< uno::XComponentContext > & xContext ) :
        ChartType( xContext )
{}

AreaChartType::AreaChartType( const AreaChartType & rOther ) :
        ChartType( rOther )
{}

AreaChartType::~AreaChartType()
{}

// ____ XCloneable ____
uno::Reference< util::XCloneable > SAL_CALL AreaChartType::createClone()
    throw (uno::RuntimeException)
{
    return uno::Reference< util::XCloneable >( new AreaChartType( *this ));
}

// ____ XChartType ____
::rtl::OUString SAL_CALL AreaChartType::getChartType()
    throw (uno::RuntimeException)
{
    return CHART2_SERVICE_NAME_CHARTTYPE_AREA;
}

uno::Sequence< ::rtl::OUString > AreaChartType::getSupportedServiceNames_Static()
{
    uno::Sequence< ::rtl::OUString > aServices( 2 );
    aServices[ 0 ] = CHART2_SERVICE_NAME_CHARTTYPE_AREA;
    aServices[ 1 ] = C2U( "com.sun.star.chart2.ChartType" );
    return aServices;
}

// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL( AreaChartType,
                             C2U( "com.sun.star.comp.chart.AreaChartType" ));

} //  namespace chart
<commit_msg>INTEGRATION: CWS changefileheader (1.5.126); FILE MERGED 2008/03/28 16:44:10 rt 1.5.126.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: AreaChartType.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "AreaChartType.hxx"
#include "macros.hxx"
#include "servicenames_charttypes.hxx"

using namespace ::com::sun::star;

namespace chart
{

AreaChartType::AreaChartType(
    const uno::Reference< uno::XComponentContext > & xContext ) :
        ChartType( xContext )
{}

AreaChartType::AreaChartType( const AreaChartType & rOther ) :
        ChartType( rOther )
{}

AreaChartType::~AreaChartType()
{}

// ____ XCloneable ____
uno::Reference< util::XCloneable > SAL_CALL AreaChartType::createClone()
    throw (uno::RuntimeException)
{
    return uno::Reference< util::XCloneable >( new AreaChartType( *this ));
}

// ____ XChartType ____
::rtl::OUString SAL_CALL AreaChartType::getChartType()
    throw (uno::RuntimeException)
{
    return CHART2_SERVICE_NAME_CHARTTYPE_AREA;
}

uno::Sequence< ::rtl::OUString > AreaChartType::getSupportedServiceNames_Static()
{
    uno::Sequence< ::rtl::OUString > aServices( 2 );
    aServices[ 0 ] = CHART2_SERVICE_NAME_CHARTTYPE_AREA;
    aServices[ 1 ] = C2U( "com.sun.star.chart2.ChartType" );
    return aServices;
}

// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL( AreaChartType,
                             C2U( "com.sun.star.comp.chart.AreaChartType" ));

} //  namespace chart
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#ifndef _Stroika_Foundation_Memory_BlockAllocator_inl_
#define _Stroika_Foundation_Memory_BlockAllocator_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include <algorithm>
#include <mutex>
#include <vector>

#include "../Debug/Assertions.h"
#include "../Debug/Valgrind.h"
#include "../Execution/Common.h"
#include "../Execution/SpinLock.h"

#include "Common.h"

/**
 *  \brief qStroika_Foundation_Memory_BlockAllocator_UseLockFree_ provides a lock-free implementation of BlockAllocator (which should be faster)
 *
 *  STILL EXPERIMENTAL< but appears to be working well so leave on by default
 */
//#define qStroika_Foundation_Memory_BlockAllocator_UseLockFree_   0
#if !defined(qStroika_Foundation_Memory_BlockAllocator_UseLockFree_)
#define qStroika_Foundation_Memory_BlockAllocator_UseLockFree_ 1
#endif

/*
 *  qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_ is currently experimental as
 *  a test to see if its faster than calling operator new (for blocks of RAM).
 *
 *  operator new[] does very little for us, and could in principle have call overhead and
 *  overhead to track the number of entries in the array (which would be pointless).
 */
#if !defined(qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_)
#define qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_ 1
#endif

#if qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_
#include "../Execution/Exceptions.h"
#include <cstdlib>
#endif

namespace Stroika::Foundation::Memory {

    namespace Private_ {

        /*
         *  kUseSpinLock_ is probaly best true (empirical tests with the
         *  performance regression test indicated that this helped considerably).
         *
         *  It should be generally pretty safe because the locks are very narrow (so threads shoudln't spend much time
         *  spinning. And we could reduce this further during mallocs of new blocks.
         */
        constexpr bool kUseSpinLock_ = !qStroika_Foundation_Memory_BlockAllocator_UseLockFree_ and Execution::kSpinLock_IsFasterThan_mutex;

#if qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
        /**
         *  Basic idea is to use a sentinal value to indicate LOCKED - and use atomic exchange, with
         *  the head of list pointer.
         *
         *  If we exchange and get the sentinal, we didnt get the lock so retry.
         *
         *  If don't get the sentinal, we have the lock (and stored the sentinal so nobody else will get the lock)
         *  so go ahead and complete the operation.
         *
         *  \note   I tried to make kLockedSentinal_ constexpr, but this generates errors, apparently because:
         *          http://en.cppreference.com/w/cpp/language/constant_expression
         *
         *          Address constant expression is a prvalue core constant expression (after conversions required by context)
         *          of type nullptr_t or of a pointer type, which points to an object with static storage duration, one past
         *          the end of an array with static storage duration, to a function, or is a null pointer
         *
         *          @todo COULD use UNION to workaround this...
         */
        static void* const kLockedSentinal_ = (void*)1; // any invalid pointer
#else
        struct BlockAllocator_ModuleInit_ {
            BlockAllocator_ModuleInit_ ();
            ~BlockAllocator_ModuleInit_ ();
        };

        using LockType_ = conditional_t<kUseSpinLock_, Execution::SpinLock, mutex>;
        extern LockType_* sLock_;

        inline LockType_& GetLock_ ()
        {
            AssertNotNull (sLock_); // automatically initailized by BlockAllocated::Private_::ActualModuleInit
            return *sLock_;
        }

        void DoDeleteHandlingLocksExceptionsEtc_ (void* p, void** staticNextLinkP) noexcept;
#endif
    }

    namespace Private_ {

        /*
         * Picked particular kTargetMallocSize since with malloc overhead likely to turn out to be
         * a chunk which memory allocator can do a good job on.
         */
        constexpr size_t kTargetMallocSize_ = 16360; // 16384 = 16K - leave a few bytes sluff...

        inline constexpr size_t BlockAllocation_Private_ComputeChunks_ (size_t poolElementSize)
        {
            return max (static_cast<size_t> (kTargetMallocSize_ / poolElementSize), static_cast<size_t> (10));
        }

        // This must be included here to keep genclass happy, since the .cc file will not be included
        // in the genclassed .cc file....
        inline void** GetMem_Util_ (size_t sz)
        {
            Require (sz >= sizeof (void*));

            const size_t kChunks = BlockAllocation_Private_ComputeChunks_ (sz);
            Assert (kChunks >= 1);

            /*
             * Please note that the following line is NOT a memory leak. @see BlockAllocator<>
             */
#if qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_
            void** newLinks = (void**)::malloc (kChunks * sz);
            Execution::ThrowIfNull (newLinks);
#else
            void** newLinks = (void**)new char[kChunks * sz];
#endif
            AssertNotNull (newLinks);
            void** curLink = newLinks;
            for (size_t i = 1; i < kChunks; i++) {
                *curLink = &(((char*)newLinks)[i * sz]);
                curLink  = (void**)*curLink;
            }
            *curLink = nullptr; // nullptr-terminate the link list
            return newLinks;
        }

        /*
         *  BlockAllocationPool_ implements the core  logic for allocation/deallocation of a particular pool. These are organized
         *  by size rather than type to reduce fragmentation.
         */
        template <size_t SIZE>
        class BlockAllocationPool_ {
        public:
            static void* Allocate (size_t n);
            static void  Deallocate (void* p) noexcept;
            static void  Compact ();

        private:
            static inline conditional_t<qStroika_Foundation_Memory_BlockAllocator_UseLockFree_, atomic<void*>, void*> sHeadLink_{nullptr};
        };
    }

    /*
     ********************************************************************************
     ***************** Private_::BlockAllocationPool_<SIZE> *************************
     ********************************************************************************
     */
    template <size_t SIZE>
    inline void* Private_::BlockAllocationPool_<SIZE>::Allocate ([[maybe_unused]] size_t n)
    {
        static_assert (SIZE >= sizeof (void*), "SIZE >= sizeof (void*)");
        Require (n <= SIZE);

#if qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
    /*
     *  Note - once we have stored Private_::kLockedSentinal_ in the sHeadLink_ and gotten back something other than that, we
     *  effectively have a lock for the scope below (because nobody else can get other than Private_::kLockedSentinal_ from exchange).
     */
    again:
        void* p = sHeadLink_.exchange (Private_::kLockedSentinal_, memory_order_acq_rel);
        if (p == Private_::kLockedSentinal_) {
            // we stored and retrieved a sentinal. So no lock. Try again!
            this_thread::yield (); // nb: until Stroika v2.0a209, this called Execution::Yield (), making this a cancelation point.
            goto again;
        }
        // if we got here, p contains the real head, and have a pseudo lock
        if (p == nullptr) {
            p = GetMem_Util_ (SIZE);
        }
        void* result = p;
        AssertNotNull (result);
        /*
         *  Treat this as a linked list, and make head point to next member.
         *
         *  Use atomic_load to guarantee the value not loaded from cache line not shared across threads.
         */
        static_assert (sizeof (void*) == sizeof (atomic<void*>), "atomic doesn't change size");
        void* next = reinterpret_cast<const atomic<void*>*> (p)->load (memory_order_acquire);
        Verify (sHeadLink_.exchange (next, memory_order_acq_rel) == Private_::kLockedSentinal_); // must return Private_::kLockedSentinal_ cuz we owned lock, so Private_::kLockedSentinal_ must be there
        return result;
#else
        [[maybe_unused]] auto&& critSec = lock_guard{Private_::GetLock_ ()};
        /*
         * To implement linked list of BlockAllocated(T)'s before they are
         * actually alloced, re-use the begining of this as a link pointer.
         */
        if (sHeadLink_ == nullptr) {
            sHeadLink_ = GetMem_Util_ (SIZE);
        }
        void* result = sHeadLink_;
        AssertNotNull (result);
        /*
         * treat this as a linked list, and make head point to next member
         */
        sHeadLink_ = (*(void**)sHeadLink_);
        return result;
#endif
    }
    template <size_t SIZE>
    inline void Private_::BlockAllocationPool_<SIZE>::Deallocate (void* p) noexcept
    {
        static_assert (SIZE >= sizeof (void*), "SIZE >= sizeof (void*)");
        RequireNotNull (p);
#if qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
        /*
         *  Note - once we have stored Private_::kLockedSentinal_ in the sHeadLink_ and gotten back something other than that, we
         *  effectively have a lock for the scope below (because nobody else can get other than Private_::kLockedSentinal_ from exchange).
         */
    again:
        void* prevHead = sHeadLink_.exchange (Private_::kLockedSentinal_, memory_order_acq_rel);
        if (prevHead == Private_::kLockedSentinal_) {
            // we stored and retrieved a sentinal. So no lock. Try again!
            this_thread::yield (); // nb: until Stroika v2.0a209, this called Execution::Yield (), making this a cancelation point.
            goto again;
        }
        /*
         *  Push p onto the head of linked free list.
         *
         *  Use atomic to guarantee the value not pushed to RAM so shared across threads.
         */
        static_assert (sizeof (void*) == sizeof (atomic<void*>), "atomic doesn't change size");
        void* newHead = p;
        reinterpret_cast<atomic<void*>*> (newHead)->store (prevHead, memory_order_release);
        Verify (sHeadLink_.exchange (newHead, memory_order_acq_rel) == Private_::kLockedSentinal_); // must return Private_::kLockedSentinal_ cuz we owned lock, so Private_::kLockedSentinal_ must be there
#else
        Private_::DoDeleteHandlingLocksExceptionsEtc_ (p, &sHeadLink_);
#endif
#if qStroika_FeatureSupported_Valgrind
        VALGRIND_HG_CLEAN_MEMORY (p, SIZE);
#endif
    }
    template <size_t SIZE>
    void Private_::BlockAllocationPool_<SIZE>::Compact ()
    {
#if qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
// cannot compact lock-free - no biggie
#else
        [[maybe_unused]] auto&& critSec = lock_guard{Private_::GetLock_ ()};

        // step one: put all the links into a single, sorted vector
        const size_t kChunks = BlockAllocation_Private_ComputeChunks_ (SIZE);
        Assert (kChunks >= 1);
        vector<void*> links;
        try {
            links.reserve (kChunks * 2);
            void* link = sHeadLink_;
            while (link != nullptr) {
                // probably should use Containers::ReserveSpeedTweekAddN - but want to avoid embrace of dependencies
                if (links.size () == links.capacity ()) {
                    links.reserve (links.size () * 2);
                }
                links.push_back (link);
                link = *(void**)link;
            }
        }
        catch (...) {
            return;
        }

        sort (links.begin (), links.end ());

        // now look for unused memory blocks. Since the vector is sorted by pointer value, the first pointer encountered is potentially the start of a block.
        // Look at the next N vector elements, where N is the amount of elements that would have been alloced (the chunk size). If they are all there, then the
        // block is unused can can be freed. Otherwise do the same thing to the first element found outside of the block.
        size_t originalSize = links.size ();
        size_t index        = 0;
        while (index < links.size ()) {
            Byte*  deleteCandidate = (Byte*)links[index];
            bool   canDelete       = true;
            size_t i               = 1;
            for (; i < kChunks; ++i) {
                if ((index + i) >= links.size ())
                    break;
                Byte* next = (Byte*)links[index + i];
                Byte* prev = (Byte*)links[index + i - 1];
                if (canDelete and ((next - prev) != SIZE)) {
                    canDelete = false; // don't break here, as have to find end up this block, which could be further on
                }
                if (static_cast<size_t> (abs (next - deleteCandidate) / SIZE) >= kChunks) {
                    Assert (not canDelete);
                    break;
                }
            }
            if (canDelete) {
                links.erase (links.begin () + index, links.begin () + index + kChunks);
#if qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_
                ::free ((void*)deleteCandidate);
#else
                delete static_cast<Byte*> ((void*)deleteCandidate);
#endif
            }
            else {
                index += i;
            }
        }

        // finally, clean up the pool. The head link is probably wrong, and the elements are no longer linked up correctly
        sHeadLink_ = (links.size () == 0) ? nullptr : links[0];
        if (links.size () != originalSize and links.size () > 0) {
            // we delete some, which means that the next pointers are bad
            void** curLink = (void**)sHeadLink_;
            for (size_t i = 1; i < links.size (); i++) {
                *curLink = links[i];
                curLink  = (void**)*curLink;
            }
            *curLink = nullptr;
        }
#endif
    }

    /*
     ********************************************************************************
     ******************************** BlockAllocator<T> *****************************
     ********************************************************************************
     */
    template <typename T>
    inline void* BlockAllocator<T>::Allocate ([[maybe_unused]] size_t n)
    {
        using Private_::BlockAllocationPool_;
        Require (n == sizeof (T));
#if qAllowBlockAllocation
        void* result = BlockAllocationPool_<AdjustSizeForPool_ ()>::Allocate (n);
#else
        void* result = ::operator new (n);
#endif
        EnsureNotNull (result);
        Ensure (reinterpret_cast<ptrdiff_t> (result) % alignof (T) == 0); // see https://stroika.atlassian.net/browse/STK-511 - assure aligned
        return result;
    }
    template <typename T>
    inline void BlockAllocator<T>::Deallocate (void* p) noexcept
    {
        using Private_::BlockAllocationPool_;
#if qAllowBlockAllocation
        if (p != nullptr) {
            BlockAllocationPool_<AdjustSizeForPool_ ()>::Deallocate (p);
        }
#else
        ::               operator delete (p);
#endif
    }
    template <typename T>
    void BlockAllocator<T>::Compact ()
    {
        using Private_::BlockAllocationPool_;
#if qAllowBlockAllocation
        BlockAllocationPool_<AdjustSizeForPool_ ()>::Compact ();
#endif
    }
    template <typename T>
    // not quite right - too much of a PITA to support both constexpr and non- just wait til all our compilers support constexpr and then fix!
    constexpr size_t BlockAllocator<T>::AdjustSizeForPool_ ()
    {
        size_t n = sizeof (T);
        // when we really fix constexpr usage, we can use the below!
        //return  Math::RoundUpTo (sizeof(T), sizeof (void*));
        return (((n + sizeof (void*) - 1u) / sizeof (void*)) * sizeof (void*));
    }

}
#if !qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
namespace {
    Stroika::Foundation::Execution::ModuleInitializer<Stroika::Foundation::Memory::Private_::BlockAllocator_ModuleInit_> _Stroika_Foundation_Memory_BlockAllocator_ModuleInit_; // this object constructed for the CTOR/DTOR per-module side-effects
}
#endif
#endif /*_Stroika_Foundation_Memory_BlockAllocator_inl_*/
<commit_msg>more cleanups of BlockAllocator<T>::AdjustSizeForPool_ ()<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#ifndef _Stroika_Foundation_Memory_BlockAllocator_inl_
#define _Stroika_Foundation_Memory_BlockAllocator_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include <algorithm>
#include <mutex>
#include <vector>

#include "../Debug/Assertions.h"
#include "../Debug/Valgrind.h"
#include "../Execution/Common.h"
#include "../Execution/SpinLock.h"
#include "../Math/Common.h"

#include "Common.h"

/**
 *  \brief qStroika_Foundation_Memory_BlockAllocator_UseLockFree_ provides a lock-free implementation of BlockAllocator (which should be faster)
 *
 *  STILL EXPERIMENTAL< but appears to be working well so leave on by default
 */
//#define qStroika_Foundation_Memory_BlockAllocator_UseLockFree_   0
#if !defined(qStroika_Foundation_Memory_BlockAllocator_UseLockFree_)
#define qStroika_Foundation_Memory_BlockAllocator_UseLockFree_ 1
#endif

/*
 *  qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_ is currently experimental as
 *  a test to see if its faster than calling operator new (for blocks of RAM).
 *
 *  operator new[] does very little for us, and could in principle have call overhead and
 *  overhead to track the number of entries in the array (which would be pointless).
 */
#if !defined(qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_)
#define qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_ 1
#endif

#if qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_
#include "../Execution/Exceptions.h"
#include <cstdlib>
#endif

namespace Stroika::Foundation::Memory {

    namespace Private_ {

        /*
         *  kUseSpinLock_ is probaly best true (empirical tests with the
         *  performance regression test indicated that this helped considerably).
         *
         *  It should be generally pretty safe because the locks are very narrow (so threads shoudln't spend much time
         *  spinning. And we could reduce this further during mallocs of new blocks.
         */
        constexpr bool kUseSpinLock_ = !qStroika_Foundation_Memory_BlockAllocator_UseLockFree_ and Execution::kSpinLock_IsFasterThan_mutex;

#if qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
        /**
         *  Basic idea is to use a sentinal value to indicate LOCKED - and use atomic exchange, with
         *  the head of list pointer.
         *
         *  If we exchange and get the sentinal, we didnt get the lock so retry.
         *
         *  If don't get the sentinal, we have the lock (and stored the sentinal so nobody else will get the lock)
         *  so go ahead and complete the operation.
         *
         *  \note   I tried to make kLockedSentinal_ constexpr, but this generates errors, apparently because:
         *          http://en.cppreference.com/w/cpp/language/constant_expression
         *
         *          Address constant expression is a prvalue core constant expression (after conversions required by context)
         *          of type nullptr_t or of a pointer type, which points to an object with static storage duration, one past
         *          the end of an array with static storage duration, to a function, or is a null pointer
         *
         *          @todo COULD use UNION to workaround this...
         */
        static void* const kLockedSentinal_ = (void*)1; // any invalid pointer
#else
        struct BlockAllocator_ModuleInit_ {
            BlockAllocator_ModuleInit_ ();
            ~BlockAllocator_ModuleInit_ ();
        };

        using LockType_ = conditional_t<kUseSpinLock_, Execution::SpinLock, mutex>;
        extern LockType_* sLock_;

        inline LockType_& GetLock_ ()
        {
            AssertNotNull (sLock_); // automatically initailized by BlockAllocated::Private_::ActualModuleInit
            return *sLock_;
        }

        void DoDeleteHandlingLocksExceptionsEtc_ (void* p, void** staticNextLinkP) noexcept;
#endif
    }

    namespace Private_ {

        /*
         * Picked particular kTargetMallocSize since with malloc overhead likely to turn out to be
         * a chunk which memory allocator can do a good job on.
         */
        constexpr size_t kTargetMallocSize_ = 16360; // 16384 = 16K - leave a few bytes sluff...

        inline constexpr size_t BlockAllocation_Private_ComputeChunks_ (size_t poolElementSize)
        {
            return max (static_cast<size_t> (kTargetMallocSize_ / poolElementSize), static_cast<size_t> (10));
        }

        // This must be included here to keep genclass happy, since the .cc file will not be included
        // in the genclassed .cc file....
        inline void** GetMem_Util_ (size_t sz)
        {
            Require (sz >= sizeof (void*));

            const size_t kChunks = BlockAllocation_Private_ComputeChunks_ (sz);
            Assert (kChunks >= 1);

            /*
             * Please note that the following line is NOT a memory leak. @see BlockAllocator<>
             */
#if qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_
            void** newLinks = (void**)::malloc (kChunks * sz);
            Execution::ThrowIfNull (newLinks);
#else
            void** newLinks = (void**)new char[kChunks * sz];
#endif
            AssertNotNull (newLinks);
            void** curLink = newLinks;
            for (size_t i = 1; i < kChunks; i++) {
                *curLink = &(((char*)newLinks)[i * sz]);
                curLink  = (void**)*curLink;
            }
            *curLink = nullptr; // nullptr-terminate the link list
            return newLinks;
        }

        /*
         *  BlockAllocationPool_ implements the core  logic for allocation/deallocation of a particular pool. These are organized
         *  by size rather than type to reduce fragmentation.
         */
        template <size_t SIZE>
        class BlockAllocationPool_ {
        public:
            // never returns nullptr - throws if memory exhausted
            static void* Allocate (size_t n);
            // require p != nullptr
            static void Deallocate (void* p) noexcept;
            static void Compact ();

        private:
            static inline conditional_t<qStroika_Foundation_Memory_BlockAllocator_UseLockFree_, atomic<void*>, void*> sHeadLink_{nullptr};
        };
    }

    /*
     ********************************************************************************
     ***************** Private_::BlockAllocationPool_<SIZE> *************************
     ********************************************************************************
     */
    template <size_t SIZE>
    inline void* Private_::BlockAllocationPool_<SIZE>::Allocate ([[maybe_unused]] size_t n)
    {
        static_assert (SIZE >= sizeof (void*), "SIZE >= sizeof (void*)");
        Require (n <= SIZE);

#if qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
    /*
     *  Note - once we have stored Private_::kLockedSentinal_ in the sHeadLink_ and gotten back something other than that, we
     *  effectively have a lock for the scope below (because nobody else can get other than Private_::kLockedSentinal_ from exchange).
     */
    again:
        void* p = sHeadLink_.exchange (Private_::kLockedSentinal_, memory_order_acq_rel);
        if (p == Private_::kLockedSentinal_) {
            // we stored and retrieved a sentinal. So no lock. Try again!
            this_thread::yield (); // nb: until Stroika v2.0a209, this called Execution::Yield (), making this a cancelation point.
            goto again;
        }
        // if we got here, p contains the real head, and have a pseudo lock
        if (p == nullptr) {
            p = GetMem_Util_ (SIZE);
        }
        void* result = p;
        AssertNotNull (result);
        /*
         *  Treat this as a linked list, and make head point to next member.
         *
         *  Use atomic_load to guarantee the value not loaded from cache line not shared across threads.
         */
        static_assert (sizeof (void*) == sizeof (atomic<void*>), "atomic doesn't change size");
        void* next = reinterpret_cast<const atomic<void*>*> (p)->load (memory_order_acquire);
        Verify (sHeadLink_.exchange (next, memory_order_acq_rel) == Private_::kLockedSentinal_); // must return Private_::kLockedSentinal_ cuz we owned lock, so Private_::kLockedSentinal_ must be there
        return result;
#else
        [[maybe_unused]] auto&& critSec = lock_guard{Private_::GetLock_ ()};
        /*
         * To implement linked list of BlockAllocated(T)'s before they are
         * actually alloced, re-use the begining of this as a link pointer.
         */
        if (sHeadLink_ == nullptr) {
            sHeadLink_ = GetMem_Util_ (SIZE);
        }
        void* result = sHeadLink_;
        AssertNotNull (result);
        /*
         * treat this as a linked list, and make head point to next member
         */
        sHeadLink_ = (*(void**)sHeadLink_);
        return result;
#endif
    }
    template <size_t SIZE>
    inline void Private_::BlockAllocationPool_<SIZE>::Deallocate (void* p) noexcept
    {
        static_assert (SIZE >= sizeof (void*), "SIZE >= sizeof (void*)");
        RequireNotNull (p);
#if qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
        /*
         *  Note - once we have stored Private_::kLockedSentinal_ in the sHeadLink_ and gotten back something other than that, we
         *  effectively have a lock for the scope below (because nobody else can get other than Private_::kLockedSentinal_ from exchange).
         */
    again:
        void* prevHead = sHeadLink_.exchange (Private_::kLockedSentinal_, memory_order_acq_rel);
        if (prevHead == Private_::kLockedSentinal_) {
            // we stored and retrieved a sentinal. So no lock. Try again!
            this_thread::yield (); // nb: until Stroika v2.0a209, this called Execution::Yield (), making this a cancelation point.
            goto again;
        }
        /*
         *  Push p onto the head of linked free list.
         *
         *  Use atomic to guarantee the value not pushed to RAM so shared across threads.
         */
        static_assert (sizeof (void*) == sizeof (atomic<void*>), "atomic doesn't change size");
        void* newHead = p;
        reinterpret_cast<atomic<void*>*> (newHead)->store (prevHead, memory_order_release);
        Verify (sHeadLink_.exchange (newHead, memory_order_acq_rel) == Private_::kLockedSentinal_); // must return Private_::kLockedSentinal_ cuz we owned lock, so Private_::kLockedSentinal_ must be there
#else
        Private_::DoDeleteHandlingLocksExceptionsEtc_ (p, &sHeadLink_);
#endif
#if qStroika_FeatureSupported_Valgrind
        VALGRIND_HG_CLEAN_MEMORY (p, SIZE);
#endif
    }
    template <size_t SIZE>
    void Private_::BlockAllocationPool_<SIZE>::Compact ()
    {
#if qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
// cannot compact lock-free - no biggie
#else
        [[maybe_unused]] auto&& critSec = lock_guard{Private_::GetLock_ ()};

        // step one: put all the links into a single, sorted vector
        const size_t kChunks = BlockAllocation_Private_ComputeChunks_ (SIZE);
        Assert (kChunks >= 1);
        vector<void*> links;
        try {
            links.reserve (kChunks * 2);
            void* link = sHeadLink_;
            while (link != nullptr) {
                // probably should use Containers::ReserveSpeedTweekAddN - but want to avoid embrace of dependencies
                if (links.size () == links.capacity ()) {
                    links.reserve (links.size () * 2);
                }
                links.push_back (link);
                link = *(void**)link;
            }
        }
        catch (...) {
            return;
        }

        sort (links.begin (), links.end ());

        // now look for unused memory blocks. Since the vector is sorted by pointer value, the first pointer encountered is potentially the start of a block.
        // Look at the next N vector elements, where N is the amount of elements that would have been alloced (the chunk size). If they are all there, then the
        // block is unused can can be freed. Otherwise do the same thing to the first element found outside of the block.
        size_t originalSize = links.size ();
        size_t index        = 0;
        while (index < links.size ()) {
            Byte*  deleteCandidate = (Byte*)links[index];
            bool   canDelete       = true;
            size_t i               = 1;
            for (; i < kChunks; ++i) {
                if ((index + i) >= links.size ())
                    break;
                Byte* next = (Byte*)links[index + i];
                Byte* prev = (Byte*)links[index + i - 1];
                if (canDelete and ((next - prev) != SIZE)) {
                    canDelete = false; // don't break here, as have to find end up this block, which could be further on
                }
                if (static_cast<size_t> (abs (next - deleteCandidate) / SIZE) >= kChunks) {
                    Assert (not canDelete);
                    break;
                }
            }
            if (canDelete) {
                links.erase (links.begin () + index, links.begin () + index + kChunks);
#if qStroika_Foundation_Memory_BlockAllocator_UseMallocDirectly_
                ::free ((void*)deleteCandidate);
#else
                delete static_cast<Byte*> ((void*)deleteCandidate);
#endif
            }
            else {
                index += i;
            }
        }

        // finally, clean up the pool. The head link is probably wrong, and the elements are no longer linked up correctly
        sHeadLink_ = (links.size () == 0) ? nullptr : links[0];
        if (links.size () != originalSize and links.size () > 0) {
            // we delete some, which means that the next pointers are bad
            void** curLink = (void**)sHeadLink_;
            for (size_t i = 1; i < links.size (); i++) {
                *curLink = links[i];
                curLink  = (void**)*curLink;
            }
            *curLink = nullptr;
        }
#endif
    }

    /*
     ********************************************************************************
     ******************************** BlockAllocator<T> *****************************
     ********************************************************************************
     */
    template <typename T>
    inline void* BlockAllocator<T>::Allocate ([[maybe_unused]] size_t n)
    {
        using Private_::BlockAllocationPool_;
        Require (n == sizeof (T));
#if qAllowBlockAllocation
        void* result = BlockAllocationPool_<AdjustSizeForPool_ ()>::Allocate (sizeof (T));
#else
        void* result = ::operator new (sizeof (T));
#endif
        EnsureNotNull (result);
        Ensure (reinterpret_cast<ptrdiff_t> (result) % alignof (T) == 0); // see https://stroika.atlassian.net/browse/STK-511 - assure aligned
        return result;
    }
    template <typename T>
    inline void BlockAllocator<T>::Deallocate (void* p) noexcept
    {
        using Private_::BlockAllocationPool_;
#if qAllowBlockAllocation
        if (p != nullptr) {
            BlockAllocationPool_<AdjustSizeForPool_ ()>::Deallocate (p);
        }
#else
        ::               operator delete (p);
#endif
    }
    template <typename T>
    void BlockAllocator<T>::Compact ()
    {
        using Private_::BlockAllocationPool_;
#if qAllowBlockAllocation
        BlockAllocationPool_<AdjustSizeForPool_ ()>::Compact ();
#endif
    }
    template <typename T>
    // not quite right - too much of a PITA to support both constexpr and non- just wait til all our compilers support constexpr and then fix!
    constexpr size_t BlockAllocator<T>::AdjustSizeForPool_ ()
    {
        return Math::RoundUpTo (sizeof (T), sizeof (void*));
    }

}
#if !qStroika_Foundation_Memory_BlockAllocator_UseLockFree_
namespace {
    Stroika::Foundation::Execution::ModuleInitializer<Stroika::Foundation::Memory::Private_::BlockAllocator_ModuleInit_> _Stroika_Foundation_Memory_BlockAllocator_ModuleInit_; // this object constructed for the CTOR/DTOR per-module side-effects
}
#endif
#endif /*_Stroika_Foundation_Memory_BlockAllocator_inl_*/
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////
//
//  Python wrappers
//
// ----------------------------------------------------------------
//
//  AUTHOR: Miguel Ramos Pernas
//  e-mail: miguel.ramos.pernas@cern.ch
//
//  Last update: 20/09/2017
//
// ----------------------------------------------------------------
///////////////////////////////////////////////////////////////////

#include "GlobalWrappers.h"
#include "NumpyUtils.h"
#include "TreeWrapper.h"

#include <Python.h>
#include <boost/python/dict.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/iterator.hpp>
#include <boost/python/list.hpp>
#include <boost/python/object.hpp>
#include <boost/python/object_operators.hpp>
#include <boost/python/tuple.hpp>

#include "BufferVariable.h"
#include "Definitions.h"
#include "Messenger.h"
#include "RootUtils.h"
#include "TreeBuffer.h"
#include "TreeManagement.h"
#include "Utils.h"

#include "TBranch.h"
#include "TDirectory.h"
#include "TEventList.h"
#include "TFile.h"
#include "TObject.h"
#include "TPython.h"
#include "TTree.h"

#include <iostream>
#include <map>
#include <string>
#include <vector>

//_______________________________________________________________

namespace iboost {

  //_______________________________________________________________
  //
  np::ndarray treeToNumpyArray( std::string fpath,
				std::string tpath,
				py::object &vars,
				std::string cuts,
				bool use_regex ) {

    // Open the Root file and access the tree
    TFile *ifile = TFile::Open(fpath.c_str());
    TTree *itree = static_cast<TTree*>(isis::getSafeObject(ifile, tpath));

    // Extracts the list of events to be used
    itree->Draw(">>evtlist", cuts.c_str());
    TEventList *evtlist = (TEventList*) gDirectory->Get("evtlist");

    // Get the branch names to be used
    itree->SetBranchStatus("*", 0);

    isis::Strings brnames;
    const py::ssize_t nvars = py::len(vars);
    for ( py::ssize_t i = 0; i < nvars; ++i ) {

      auto var = extractFromIndex<std::string>(vars, i);

      bool s = true;
      if ( use_regex )
	s = isis::getBranchNames(brnames, itree, var);
      else {
	if ( itree->GetBranch(var.c_str()) )
	    brnames.push_back(var);
	else
	  s = false;
      }

      if ( !s )
	IWarning << "No variables have been found following expression < "
		 << var << " >" << IEndMsg;
    }

    // Do not swap these two lines, since the path must be set after the
    // variable is enabled
    isis::TreeBuffer buffer(itree);
    for ( const auto br : brnames ) {

      itree->SetBranchStatus(br.c_str(), 1);

      buffer.loadVariable(br);
    }

    // Make the output array
    auto output = void_ndarray(evtlist->GetN(), buffer);

    // Build the writers
    std::vector<BuffVarWriter*> outvec;
    size_t n = brnames.size();
    outvec.reserve(n);
    for ( const auto el: buffer.getMap() ) {

      np::ndarray a = py::extract<np::ndarray>(output[el.first]);

      outvec.push_back(new BuffVarWriter(el.second, a));
    }

    // Calling to < append > is faster than assigning by index
    for ( int i = 0; i < evtlist->GetN(); ++i ) {

      Long64_t ievt = evtlist->GetEntry(i);
      itree->GetEntry(ievt);

      for ( auto &el : outvec )
	el->appendToArray(i, n);
    }

    // The branches are enabled again
    itree->SetBranchStatus("*", 1);
    ifile->Close();

    // Delete allocated memory
    for ( auto &v : outvec )
      delete v;

    return output;
  }

  //_______________________________________________________________
  //
  py::object numpyArrayToTree( py::tuple args, py::dict kwargs ) {

    checkArgs(args, 1);
    checkKwargs(kwargs, {"name", "tree", "variables", "use_regex"});

    np::ndarray vartup = extractFromIndex<np::ndarray>(args, 0);
    py::list varkeys   = struct_array_keys(vartup);

    // Get the tree name or the given tree
    TTree *tree = 0;
    if ( kwargs.has_key(py::object("tree")) ) {

      py::object el = kwargs["tree"];

      TObject *treeproxy =
	(TObject*) TPython::ObjectProxy_AsVoidPtr(el.ptr());

      tree = dynamic_cast<TTree*>(treeproxy);
    }

    std::string tname;
    if ( kwargs.has_key("name") )
      tname = py::extract<std::string>(kwargs["name"]);

    // Get the list of variables to work with
    py::list variables;
    if ( kwargs.has_key("variables") ) {
      variables = py::extract<py::list>(kwargs["variables"]);
      if ( !py::len(variables) )
	variables = varkeys;
    }
    else
      variables = varkeys;

    // Determine whether regex will be used or not
    bool use_regex = false;
    if ( kwargs.has_key("use_regex") )
      use_regex = py::extract<bool>(kwargs["use_regex"]);

    // Warning message if both the tree and tree name are provided
    if ( !tree ) {
      tree = new TTree(tname.c_str(), tname.c_str(), 0);
      tree->AutoSave();
    }
    else if ( !tname.empty() )
      IWarning << "The given tree name is not being used" << IEndMsg;

    // Prepare the variables to iterate with. The vector keeps
    // track of the types for each variable.
    isis::TreeBuffer buffer(tree);

    auto vars = boostListToStdCont<std::vector, std::string>(variables);
    auto vec_keys = boostListToStdCont<std::vector, std::string>(varkeys);

    // Get the variables from the given expressions
    isis::Strings brnames;
    for ( const auto &exp : vars ) {

      if ( use_regex )
	isis::stringVectorFilter(brnames, vec_keys, exp);
      else
	brnames.push_back(exp);
    }

    std::vector<BuffVarWriter*> varvec;
    varvec.reserve(brnames.size());
    for ( const auto &br : brnames )
      varvec.push_back(new BuffVarWriter( buffer, br,
					  py::extract<np::ndarray>(vartup[br]))
		       );

    // Loop over all the events in the dictionary
    py::ssize_t nvals = py::len(vartup);
    for ( py::ssize_t ievt = 0; ievt < nvals; ++ievt ) {

      // Loop over all the variables in the dictionary
      const size_t n = varvec.size();
      for ( auto &v : varvec )
	v->appendToVar(ievt, n);

      tree->Fill();
    }
    tree->AutoSave();

    // Delete the allocated memory
    for ( auto &v : varvec )
      delete v;

    // Returns "None"
    return py::object();
  }

}
<commit_msg>Fix issue in TreeWrapper.cpp, when writting data to root<commit_after>///////////////////////////////////////////////////////////////////
//
//  Python wrappers
//
// ----------------------------------------------------------------
//
//  AUTHOR: Miguel Ramos Pernas
//  e-mail: miguel.ramos.pernas@cern.ch
//
//  Last update: 21/09/2017
//
// ----------------------------------------------------------------
///////////////////////////////////////////////////////////////////

#include "GlobalWrappers.h"
#include "NumpyUtils.h"
#include "TreeWrapper.h"

#include <Python.h>
#include <boost/python/dict.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/iterator.hpp>
#include <boost/python/list.hpp>
#include <boost/python/object.hpp>
#include <boost/python/object_operators.hpp>
#include <boost/python/tuple.hpp>

#include "BufferVariable.h"
#include "Definitions.h"
#include "Messenger.h"
#include "RootUtils.h"
#include "TreeBuffer.h"
#include "TreeManagement.h"
#include "Utils.h"

#include "TBranch.h"
#include "TDirectory.h"
#include "TEventList.h"
#include "TFile.h"
#include "TObject.h"
#include "TPython.h"
#include "TTree.h"

#include <iostream>
#include <map>
#include <string>
#include <vector>

//_______________________________________________________________

namespace iboost {

  //_______________________________________________________________
  //
  np::ndarray treeToNumpyArray( std::string fpath,
				std::string tpath,
				py::object &vars,
				std::string cuts,
				bool use_regex ) {

    // Open the Root file and access the tree
    TFile *ifile = TFile::Open(fpath.c_str());
    TTree *itree = static_cast<TTree*>(isis::getSafeObject(ifile, tpath));

    // Extracts the list of events to be used
    itree->Draw(">>evtlist", cuts.c_str());
    TEventList *evtlist = (TEventList*) gDirectory->Get("evtlist");

    // Get the branch names to be used
    itree->SetBranchStatus("*", 0);

    isis::Strings brnames;
    const py::ssize_t nvars = py::len(vars);
    for ( py::ssize_t i = 0; i < nvars; ++i ) {

      auto var = extractFromIndex<std::string>(vars, i);

      bool s = true;
      if ( use_regex )
	s = isis::getBranchNames(brnames, itree, var);
      else {
	if ( itree->GetBranch(var.c_str()) )
	    brnames.push_back(var);
	else
	  s = false;
      }

      if ( !s )
	IWarning << "No variables have been found following expression < "
		 << var << " >" << IEndMsg;
    }

    // Do not swap these two lines, since the path must be set after the
    // variable is enabled
    isis::TreeBuffer buffer(itree);
    for ( const auto br : brnames ) {

      itree->SetBranchStatus(br.c_str(), 1);

      buffer.loadVariable(br);
    }

    // Make the output array
    auto output = void_ndarray(evtlist->GetN(), buffer);

    // Build the writers
    std::vector<BuffVarWriter*> outvec;
    const size_t n = brnames.size();
    outvec.reserve(n);
    for ( const auto el: buffer.getMap() ) {

      np::ndarray a = py::extract<np::ndarray>(output[el.first]);

      outvec.push_back(new BuffVarWriter(el.second, a));
    }

    // Calling to < append > is faster than assigning by index
    for ( int i = 0; i < evtlist->GetN(); ++i ) {

      Long64_t ievt = evtlist->GetEntry(i);
      itree->GetEntry(ievt);

      for ( auto &el : outvec )
	el->appendToArray(i, n);
    }

    // The branches are enabled again
    itree->SetBranchStatus("*", 1);
    ifile->Close();

    // Delete allocated memory
    for ( auto &v : outvec )
      delete v;

    return output;
  }

  //_______________________________________________________________
  //
  py::object numpyArrayToTree( py::tuple args, py::dict kwargs ) {

    checkArgs(args, 1);
    checkKwargs(kwargs, {"name", "tree", "variables", "use_regex"});

    np::ndarray vartup = extractFromIndex<np::ndarray>(args, 0);
    py::list varkeys   = struct_array_keys(vartup);

    // Get the tree name or the given tree
    TTree *tree = 0;
    if ( kwargs.has_key(py::object("tree")) ) {

      py::object el = kwargs["tree"];

      TObject *treeproxy =
	(TObject*) TPython::ObjectProxy_AsVoidPtr(el.ptr());

      tree = dynamic_cast<TTree*>(treeproxy);
    }

    std::string tname;
    if ( kwargs.has_key("name") )
      tname = py::extract<std::string>(kwargs["name"]);

    // Get the list of variables to work with
    py::list variables;
    if ( kwargs.has_key("variables") ) {
      variables = py::extract<py::list>(kwargs["variables"]);
      if ( !py::len(variables) )
	variables = varkeys;
    }
    else
      variables = varkeys;

    // Determine whether regex will be used or not
    bool use_regex = false;
    if ( kwargs.has_key("use_regex") )
      use_regex = py::extract<bool>(kwargs["use_regex"]);

    // Warning message if both the tree and tree name are provided
    if ( !tree ) {
      tree = new TTree(tname.c_str(), tname.c_str(), 0);
      tree->AutoSave();
    }
    else if ( !tname.empty() )
      IWarning << "The given tree name is not being used" << IEndMsg;

    // Prepare the variables to iterate with. The vector keeps
    // track of the types for each variable.
    isis::TreeBuffer buffer(tree);

    auto vars = boostListToStdCont<std::vector, std::string>(variables);
    auto vec_keys = boostListToStdCont<std::vector, std::string>(varkeys);

    // Get the variables from the given expressions
    isis::Strings brnames;
    for ( const auto &exp : vars ) {

      if ( use_regex )
	isis::stringVectorFilter(brnames, vec_keys, exp);
      else
	brnames.push_back(exp);
    }

    std::vector<BuffVarWriter*> varvec;
    const size_t n = brnames.size();
    varvec.reserve(n);
    for ( const auto &br : brnames )
      varvec.push_back(new BuffVarWriter( buffer, br,
					  py::extract<np::ndarray>(vartup[br]))
		       );

    // Loop over all the events in the array, the whole number of variables
    // in the input array must be used to access correctly to the data
    py::ssize_t nvals = py::len(vartup);
    py::ssize_t nkeys = py::len(varkeys);
    for ( py::ssize_t ievt = 0; ievt < nvals; ++ievt ) {

      // Loop over all the variables in the array
      for ( auto &v : varvec )
	v->appendToVar(ievt, nkeys);

      tree->Fill();
    }
    tree->AutoSave();

    // Delete the allocated memory
    for ( auto &v : varvec )
      delete v;

    // Returns "None"
    return py::object();
  }

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: CustomAnimationPanel.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-18 17:00:55 $
 *
 *  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 SD_TOOLPANEL_CONTROLS_CUSTOM_ANIMATION_PANEL_HXX
#define SD_TOOLPANEL_CONTROLS_CUSTOM_ANIMATION_PANEL_HXX

#include "taskpane/SubToolPanel.hxx"

namespace sd {
class ViewShellBase;
}

namespace sd { namespace toolpanel {
class TreeNode;
class ControlFactory;
} }

namespace sd { namespace toolpanel { namespace controls {

class CustomAnimationPanel
    : public SubToolPanel
{
public:
    CustomAnimationPanel (
        TreeNode* pParent,
        ViewShellBase& rBase);
    virtual ~CustomAnimationPanel (void);

    static std::auto_ptr<ControlFactory> CreateControlFactory (ViewShellBase& rBase);

    virtual Size GetPreferredSize (void);
    virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeigh);
    virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
    virtual ::Window* GetWindow (void);
    virtual bool IsResizable (void);
    virtual bool IsExpandable (void) const;

private:
    Size maPreferredSize;
    ::Window* mpWrappedControl;
};

} } } // end of namespace ::sd::toolpanel::controls

#endif
<commit_msg>INTEGRATION: CWS impress51 (1.3.46); FILE MERGED 2005/05/20 09:02:53 af 1.3.46.1: #i48247# Added CreateAccessibleObject() method.<commit_after>/*************************************************************************
 *
 *  $RCSfile: CustomAnimationPanel.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2005-07-14 10:24:59 $
 *
 *  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 SD_TOOLPANEL_CONTROLS_CUSTOM_ANIMATION_PANEL_HXX
#define SD_TOOLPANEL_CONTROLS_CUSTOM_ANIMATION_PANEL_HXX

#include "taskpane/SubToolPanel.hxx"

namespace sd {
class ViewShellBase;
}

namespace sd { namespace toolpanel {
class TreeNode;
class ControlFactory;
} }

namespace sd { namespace toolpanel { namespace controls {

class CustomAnimationPanel
    : public SubToolPanel
{
public:
    CustomAnimationPanel (
        TreeNode* pParent,
        ViewShellBase& rBase);
    virtual ~CustomAnimationPanel (void);

    static std::auto_ptr<ControlFactory> CreateControlFactory (ViewShellBase& rBase);

    virtual Size GetPreferredSize (void);
    virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeigh);
    virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
    virtual ::Window* GetWindow (void);
    virtual bool IsResizable (void);
    virtual bool IsExpandable (void) const;

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible > CreateAccessibleObject (
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::accessibility::XAccessible>& rxParent);

private:
    Size maPreferredSize;
    ::Window* mpWrappedControl;
};

} } } // end of namespace ::sd::toolpanel::controls

#endif
<|endoftext|>


<commit_before>// Copyright 2011 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <vector>

#include <utils.hpp>
#include <Exceptions.hpp>

#ifndef INITIALIZE_OPENCL_HPP
#define INITIALIZE_OPENCL_HPP

namespace isa {
namespace OpenCL {

void initializeOpenCL(unsigned int platform, unsigned int nrQueues, std::vector< cl::Platform > * platforms, cl::Context * context, std::vector< cl::Device > * devices, std::vector< std::vector< cl::CommandQueue > > * queues) throw (isa::OpenCL::OpenCLError) {
	try {
		unsigned int nrDevices = 0;

		cl::Platform::get(platforms);
		cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms->at(platform))(), 0};
		*context = cl::Context(CL_DEVICE_TYPE_ALL, properties);

		*devices = context->getInfo<CL_CONTEXT_DEVICES>();
		nrDevices = devices->size();
		for ( unsigned int device = 0; device < nrDevices; device++ ) {
			queues->push_back(std::vector< cl::CommandQueue >());
			for ( unsigned int queue = 0; queue < nrQueues; queue++ ) {
				(queues->at(device)).push_back(cl::CommandQueue(*context, devices->at(device)));;
			}
		}
	}	catch ( cl::Error &e ) {
		throw isa::OpenCL::OpenCLError("Impossible to initialize OpenCL: " + isa::utils::toString(e.err()) + ".");
	}
}

} // OpenCL
} // isa

#endif // INITIALIZE_OPENCL_HPP

<commit_msg>Allocating the context in initializeOpenCL().<commit_after>// Copyright 2011 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <vector>

#include <utils.hpp>
#include <Exceptions.hpp>

#ifndef INITIALIZE_OPENCL_HPP
#define INITIALIZE_OPENCL_HPP

namespace isa {
namespace OpenCL {

void initializeOpenCL(unsigned int platform, unsigned int nrQueues, std::vector< cl::Platform > * platforms, cl::Context * context, std::vector< cl::Device > * devices, std::vector< std::vector< cl::CommandQueue > > * queues) throw (isa::OpenCL::OpenCLError) {
	try {
		unsigned int nrDevices = 0;

		cl::Platform::get(platforms);
		cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms->at(platform))(), 0};
    context = new cl::Context();
		*context = cl::Context(CL_DEVICE_TYPE_ALL, properties);

		*devices = context->getInfo<CL_CONTEXT_DEVICES>();
		nrDevices = devices->size();
		for ( unsigned int device = 0; device < nrDevices; device++ ) {
			queues->push_back(std::vector< cl::CommandQueue >());
			for ( unsigned int queue = 0; queue < nrQueues; queue++ ) {
				(queues->at(device)).push_back(cl::CommandQueue(*context, devices->at(device)));;
			}
		}
	}	catch ( cl::Error &e ) {
		throw isa::OpenCL::OpenCLError("Impossible to initialize OpenCL: " + isa::utils::toString(e.err()) + ".");
	}
}

} // OpenCL
} // isa

#endif // INITIALIZE_OPENCL_HPP

<|endoftext|>