<commit_before>/*** tws_util.cpp -- common utils
 *
 * Copyright (C) 2010, 2011 Ruediger Meier
 *
 * Author:  Ruediger Meier <sweet_f_a@gmx.de>
 *
 * This file is part of twstools.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the author nor the names of any contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 REGENTS 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 "tws_util.h"
#include "debug.h"

// from global installed twsapi
#include "twsapi/EWrapper.h" //IB::TickType
#include "twsapi/Execution.h"
#include "twsapi/Contract.h"

#include <sys/time.h>

int64_t nowInMsecs()
{
	timeval tv;
	int err = gettimeofday( &tv, NULL );
	assert( err == 0 );

	const uint64_t now_ms = tv.tv_sec*1000 + tv.tv_usec/1000;
	return now_ms;
}

std::string msecs_to_string( int64_t msecs )
{
	const time_t s = msecs / 1000;
	const uint ms = msecs % 1000;
	char buf[ 19 + 4 + 1 ]; // "yyyy-mm-dd hh:mm:ss.zzz"
	const struct tm *tmp_tm = localtime( &s );
	size_t tmp_sz;

	tmp_sz = strftime(buf, 19+1 , "%F %T", tmp_tm);
	assert( tmp_sz == 19);
	tmp_sz = snprintf( buf+19, 4+1, ".%03u", ms );
	assert( tmp_sz == 4);

	return std::string(buf);
}

std::string ibToString( int tickType) {
	switch ( tickType) {
		case IB::BID_SIZE:                    return "bidSize";
		case IB::BID:                         return "bidPrice";
		case IB::ASK:                         return "askPrice";
		case IB::ASK_SIZE:                    return "askSize";
		case IB::LAST:                        return "lastPrice";
		case IB::LAST_SIZE:                   return "lastSize";
		case IB::HIGH:                        return "high";
		case IB::LOW:                         return "low";
		case IB::VOLUME:                      return "volume";
		case IB::CLOSE:                       return "close";
		case IB::BID_OPTION_COMPUTATION:      return "bidOptComp";
		case IB::ASK_OPTION_COMPUTATION:      return "askOptComp";
		case IB::LAST_OPTION_COMPUTATION:     return "lastOptComp";
		case IB::MODEL_OPTION:                return "modelOptComp";
		case IB::OPEN:                        return "open";
		case IB::LOW_13_WEEK:                 return "13WeekLow";
		case IB::HIGH_13_WEEK:                return "13WeekHigh";
		case IB::LOW_26_WEEK:                 return "26WeekLow";
		case IB::HIGH_26_WEEK:                return "26WeekHigh";
		case IB::LOW_52_WEEK:                 return "52WeekLow";
		case IB::HIGH_52_WEEK:                return "52WeekHigh";
		case IB::AVG_VOLUME:                  return "AvgVolume";
		case IB::OPEN_INTEREST:               return "OpenInterest";
		case IB::OPTION_HISTORICAL_VOL:       return "OptionHistoricalVolatility";
		case IB::OPTION_IMPLIED_VOL:          return "OptionImpliedVolatility";
		case IB::OPTION_BID_EXCH:             return "OptionBidExchStr";
		case IB::OPTION_ASK_EXCH:             return "OptionAskExchStr";
		case IB::OPTION_CALL_OPEN_INTEREST:   return "OptionCallOpenInterest";
		case IB::OPTION_PUT_OPEN_INTEREST:    return "OptionPutOpenInterest";
		case IB::OPTION_CALL_VOLUME:          return "OptionCallVolume";
		case IB::OPTION_PUT_VOLUME:           return "OptionPutVolume";
		case IB::INDEX_FUTURE_PREMIUM:        return "IndexFuturePremium";
		case IB::BID_EXCH:                    return "bidExch";
		case IB::ASK_EXCH:                    return "askExch";
		case IB::AUCTION_VOLUME:              return "auctionVolume";
		case IB::AUCTION_PRICE:               return "auctionPrice";
		case IB::AUCTION_IMBALANCE:           return "auctionImbalance";
		case IB::MARK_PRICE:                  return "markPrice";
		case IB::BID_EFP_COMPUTATION:         return "bidEFP";
		case IB::ASK_EFP_COMPUTATION:         return "askEFP";
		case IB::LAST_EFP_COMPUTATION:        return "lastEFP";
		case IB::OPEN_EFP_COMPUTATION:        return "openEFP";
		case IB::HIGH_EFP_COMPUTATION:        return "highEFP";
		case IB::LOW_EFP_COMPUTATION:         return "lowEFP";
		case IB::CLOSE_EFP_COMPUTATION:       return "closeEFP";
		case IB::LAST_TIMESTAMP:              return "lastTimestamp";
		case IB::SHORTABLE:                   return "shortable";
		case IB::FUNDAMENTAL_RATIOS:          return "fundamentals";
		case IB::RT_VOLUME:                   return "rtVolume";
		case IB::HALTED:                      return "halted";
		default:                          return "unknown";
	}
}

std::string ibToString( const IB::Execution& ex )
{
	char buf[1024];
	snprintf( buf, sizeof(buf), "orderId:%ld: clientId:%ld, execId:%s, "
		"time:%s, acctNumber:%s, exchange:%s, side:%s, shares:%d, price:%g, "
		"permId:%d, liquidation:%d, cumQty:%d, avgPrice:%g",
		ex.orderId, ex.clientId, ex.execId.c_str(), ex.time.c_str(),
		ex.acctNumber.c_str(), ex.exchange.c_str(), ex.side.c_str(),
		ex.shares, ex.price, ex.permId, ex.liquidation, ex.cumQty, ex.avgPrice);
	return std::string(buf);
}

std::string ibToString( const IB::Contract &c, bool showFields )
{
	char buf[1024];
	const char *fmt;

	if( showFields ) {
		fmt = "conId:%ld, symbol:%s, secType:%s, expiry:%s, strike:%g, "
		"right:%s, multiplier:%s, exchange:%s, currency:%s, localSymbol:%s";
	} else {
		fmt = "%ld,%s,%s,%s,%g,%s,%s,%s,%s,%s";
	}
	snprintf( buf, sizeof(buf), fmt,
		c.conId, c.symbol.c_str(), c.secType.c_str(),
		c.expiry.c_str(), c.strike, c.right.c_str(),
		c.multiplier.c_str(), c.exchange.c_str(), c.currency.c_str(),
		c.localSymbol.c_str() );

	return std::string(buf);
}

<commit_msg>build fix, don't use uint<commit_after>/*** tws_util.cpp -- common utils
 *
 * Copyright (C) 2010, 2011 Ruediger Meier
 *
 * Author:  Ruediger Meier <sweet_f_a@gmx.de>
 *
 * This file is part of twstools.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the author nor the names of any contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 REGENTS 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 "tws_util.h"
#include "debug.h"

// from global installed twsapi
#include "twsapi/EWrapper.h" //IB::TickType
#include "twsapi/Execution.h"
#include "twsapi/Contract.h"

#include <sys/time.h>

int64_t nowInMsecs()
{
	timeval tv;
	int err = gettimeofday( &tv, NULL );
	assert( err == 0 );

	const uint64_t now_ms = tv.tv_sec*1000 + tv.tv_usec/1000;
	return now_ms;
}

std::string msecs_to_string( int64_t msecs )
{
	const time_t s = msecs / 1000;
	const unsigned int ms = msecs % 1000;
	char buf[ 19 + 4 + 1 ]; // "yyyy-mm-dd hh:mm:ss.zzz"
	const struct tm *tmp_tm = localtime( &s );
	size_t tmp_sz;

	tmp_sz = strftime(buf, 19+1 , "%F %T", tmp_tm);
	assert( tmp_sz == 19);
	tmp_sz = snprintf( buf+19, 4+1, ".%03u", ms );
	assert( tmp_sz == 4);

	return std::string(buf);
}

std::string ibToString( int tickType) {
	switch ( tickType) {
		case IB::BID_SIZE:                    return "bidSize";
		case IB::BID:                         return "bidPrice";
		case IB::ASK:                         return "askPrice";
		case IB::ASK_SIZE:                    return "askSize";
		case IB::LAST:                        return "lastPrice";
		case IB::LAST_SIZE:                   return "lastSize";
		case IB::HIGH:                        return "high";
		case IB::LOW:                         return "low";
		case IB::VOLUME:                      return "volume";
		case IB::CLOSE:                       return "close";
		case IB::BID_OPTION_COMPUTATION:      return "bidOptComp";
		case IB::ASK_OPTION_COMPUTATION:      return "askOptComp";
		case IB::LAST_OPTION_COMPUTATION:     return "lastOptComp";
		case IB::MODEL_OPTION:                return "modelOptComp";
		case IB::OPEN:                        return "open";
		case IB::LOW_13_WEEK:                 return "13WeekLow";
		case IB::HIGH_13_WEEK:                return "13WeekHigh";
		case IB::LOW_26_WEEK:                 return "26WeekLow";
		case IB::HIGH_26_WEEK:                return "26WeekHigh";
		case IB::LOW_52_WEEK:                 return "52WeekLow";
		case IB::HIGH_52_WEEK:                return "52WeekHigh";
		case IB::AVG_VOLUME:                  return "AvgVolume";
		case IB::OPEN_INTEREST:               return "OpenInterest";
		case IB::OPTION_HISTORICAL_VOL:       return "OptionHistoricalVolatility";
		case IB::OPTION_IMPLIED_VOL:          return "OptionImpliedVolatility";
		case IB::OPTION_BID_EXCH:             return "OptionBidExchStr";
		case IB::OPTION_ASK_EXCH:             return "OptionAskExchStr";
		case IB::OPTION_CALL_OPEN_INTEREST:   return "OptionCallOpenInterest";
		case IB::OPTION_PUT_OPEN_INTEREST:    return "OptionPutOpenInterest";
		case IB::OPTION_CALL_VOLUME:          return "OptionCallVolume";
		case IB::OPTION_PUT_VOLUME:           return "OptionPutVolume";
		case IB::INDEX_FUTURE_PREMIUM:        return "IndexFuturePremium";
		case IB::BID_EXCH:                    return "bidExch";
		case IB::ASK_EXCH:                    return "askExch";
		case IB::AUCTION_VOLUME:              return "auctionVolume";
		case IB::AUCTION_PRICE:               return "auctionPrice";
		case IB::AUCTION_IMBALANCE:           return "auctionImbalance";
		case IB::MARK_PRICE:                  return "markPrice";
		case IB::BID_EFP_COMPUTATION:         return "bidEFP";
		case IB::ASK_EFP_COMPUTATION:         return "askEFP";
		case IB::LAST_EFP_COMPUTATION:        return "lastEFP";
		case IB::OPEN_EFP_COMPUTATION:        return "openEFP";
		case IB::HIGH_EFP_COMPUTATION:        return "highEFP";
		case IB::LOW_EFP_COMPUTATION:         return "lowEFP";
		case IB::CLOSE_EFP_COMPUTATION:       return "closeEFP";
		case IB::LAST_TIMESTAMP:              return "lastTimestamp";
		case IB::SHORTABLE:                   return "shortable";
		case IB::FUNDAMENTAL_RATIOS:          return "fundamentals";
		case IB::RT_VOLUME:                   return "rtVolume";
		case IB::HALTED:                      return "halted";
		default:                          return "unknown";
	}
}

std::string ibToString( const IB::Execution& ex )
{
	char buf[1024];
	snprintf( buf, sizeof(buf), "orderId:%ld: clientId:%ld, execId:%s, "
		"time:%s, acctNumber:%s, exchange:%s, side:%s, shares:%d, price:%g, "
		"permId:%d, liquidation:%d, cumQty:%d, avgPrice:%g",
		ex.orderId, ex.clientId, ex.execId.c_str(), ex.time.c_str(),
		ex.acctNumber.c_str(), ex.exchange.c_str(), ex.side.c_str(),
		ex.shares, ex.price, ex.permId, ex.liquidation, ex.cumQty, ex.avgPrice);
	return std::string(buf);
}

std::string ibToString( const IB::Contract &c, bool showFields )
{
	char buf[1024];
	const char *fmt;

	if( showFields ) {
		fmt = "conId:%ld, symbol:%s, secType:%s, expiry:%s, strike:%g, "
		"right:%s, multiplier:%s, exchange:%s, currency:%s, localSymbol:%s";
	} else {
		fmt = "%ld,%s,%s,%s,%g,%s,%s,%s,%s,%s";
	}
	snprintf( buf, sizeof(buf), fmt,
		c.conId, c.symbol.c_str(), c.secType.c_str(),
		c.expiry.c_str(), c.strike, c.right.c_str(),
		c.multiplier.c_str(), c.exchange.c_str(), c.currency.c_str(),
		c.localSymbol.c_str() );

	return std::string(buf);
}

<|endoftext|>


<commit_before><commit_msg>Annotate further.<commit_after><|endoftext|>


<commit_before>#include "boost/program_options.hpp"

#include "itkRGBPixel.h"
#include "itkImage.h"
#include "itkImageSeriesReader.h"
#include "itkNumericSeriesFileNames.h"
#include "itkChangeInformationImageFilter.h"

#include "IOHelpers.hpp"
#include "Parameters.hpp"

namespace po = boost::program_options;
po::variables_map parse_arguments(int argc, char *argv[]);

int main( int argc, char ** argv )
{
  // set dataset, in order to use getSpacings

  // Parse command line arguments
  po::variables_map vm = parse_arguments(argc, argv);

  typedef itk::RGBPixel< unsigned char > PixelType;
  typedef itk::Image< PixelType, 3 > ImageType;
  typedef itk::ImageSeriesReader< ImageType > SeriesReaderType;
  typedef itk::NumericSeriesFileNames NameGeneratorType;

  SeriesReaderType::Pointer seriesReader = SeriesReaderType::New();
  NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();

  nameGenerator->SetStartIndex( 1 );
  nameGenerator->SetEndIndex( vm["numberOfSlices"].as<unsigned int>() );
  nameGenerator->SetIncrementIndex( 1 );
  nameGenerator->SetSeriesFormat( vm["inputSeriesFormat"].as<string>() );
  seriesReader->SetFileNames( nameGenerator->GetFileNames() );
  seriesReader->Update();

  ImageType::Pointer input = seriesReader->GetOutput();
  ImageType::SpacingType spacing = input->GetSpacing();
  spacing[2] = vm["zSpacing"].as<double>();

  typedef itk::ChangeInformationImageFilter< ImageType > ZScalerType;
  ZScalerType::Pointer zScaler = ZScalerType::New();
  zScaler->ChangeSpacingOn();
	zScaler->SetOutputSpacing(spacing);
  zScaler->SetInput(input);

  ImageType::Pointer output = zScaler->GetOutput();
  writeImage<ImageType>(output, vm["outputFile"].as<string>() );

  return EXIT_SUCCESS;
}

po::variables_map parse_arguments(int argc, char *argv[])
{
  // Declare the supported options.
  po::options_description opts("Options");
  opts.add_options()
      ("help,h", "produce help message")
      ("numberOfSlices,n", po::value<unsigned int>(), "number of input files")
      ("inputSeriesFormat", po::value<string>()->default_value("HiRes_%03d.mha"), "format of image series file names")
      ("outputFile", po::value<string>()->default_value("HiRes.mha"), "name of output volume")
      ("zSpacing", po::value<double>()->default_value(10.0), "spacing in microns between slices")
  ;

  po::positional_options_description p;
  p.add("numberOfSlices", 1)
   .add("inputSeriesFormat", 1)
   .add("outputFile", 1)
   .add("zSpacing", 1)
   ;

  // parse command line
  po::variables_map vm;
	try
	{
  po::store(po::command_line_parser(argc, argv)
            .options(opts)
            .positional(p)
            .run(),
            vm);
	}
	catch (std::exception& e)
	{
	  cerr << "caught command-line parsing error" << endl;
    std::cerr << e.what() << std::endl;
    exit(EXIT_FAILURE);
  }
  po::notify(vm);

  // if help is specified, or positional args aren't present,
  // or more than one loadX flag
  if( vm.count("help") || !vm.count("numberOfSlices") )
  {
    cerr << "Usage: "
      << argv[0]
      << " [--numberOfSlices=]100"
      << " [--inputSeriesFormat=]HiRes_%03d"
      << " [--outputFile=]HiRes.mha"
      << endl << endl;
    cerr << opts << "\n";
    exit(EXIT_FAILURE);
  }

  return vm;
}
<commit_msg>Compressed images by default<commit_after>#include "boost/program_options.hpp"

#include "itkRGBPixel.h"
#include "itkImage.h"
#include "itkImageSeriesReader.h"
#include "itkNumericSeriesFileNames.h"
#include "itkChangeInformationImageFilter.h"

#include "IOHelpers.hpp"
#include "Parameters.hpp"

namespace po = boost::program_options;
po::variables_map parse_arguments(int argc, char *argv[]);

int main( int argc, char ** argv )
{
  // Parse command line arguments
  po::variables_map vm = parse_arguments(argc, argv);

  typedef itk::RGBPixel< unsigned char > PixelType;
  typedef itk::Image< PixelType, 3 > ImageType;
  typedef itk::ImageSeriesReader< ImageType > SeriesReaderType;
  typedef itk::NumericSeriesFileNames NameGeneratorType;

  SeriesReaderType::Pointer seriesReader = SeriesReaderType::New();
  NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();

  nameGenerator->SetStartIndex( 1 );
  nameGenerator->SetEndIndex( vm["numberOfSlices"].as<unsigned int>() );
  nameGenerator->SetIncrementIndex( 1 );
  nameGenerator->SetSeriesFormat( vm["inputSeriesFormat"].as<string>() );
  seriesReader->SetFileNames( nameGenerator->GetFileNames() );
  seriesReader->Update();

  ImageType::Pointer input = seriesReader->GetOutput();
  ImageType::SpacingType spacing = input->GetSpacing();
  spacing[2] = vm["zSpacing"].as<double>();

  typedef itk::ChangeInformationImageFilter< ImageType > ZScalerType;
  ZScalerType::Pointer zScaler = ZScalerType::New();
  zScaler->ChangeSpacingOn();
	zScaler->SetOutputSpacing(spacing);
  zScaler->SetInput(input);

  ImageType::Pointer output = zScaler->GetOutput();
  writeImage<ImageType>(output, vm["outputFile"].as<string>() );

  return EXIT_SUCCESS;
}

po::variables_map parse_arguments(int argc, char *argv[])
{
  // Declare the supported options.
  po::options_description opts("Options");
  opts.add_options()
      ("help,h", "produce help message")
      ("numberOfSlices,n", po::value<unsigned int>(), "number of input files")
      ("inputSeriesFormat", po::value<string>()->default_value("HiRes_%03d.mhz"), "format of image series file names")
      ("outputFile", po::value<string>()->default_value("HiRes.mhz"), "name of output volume")
      ("zSpacing", po::value<double>()->default_value(10.0), "spacing in microns between slices")
  ;

  po::positional_options_description p;
  p.add("numberOfSlices", 1)
   .add("inputSeriesFormat", 1)
   .add("outputFile", 1)
   .add("zSpacing", 1)
   ;

  // parse command line
  po::variables_map vm;
	try
	{
  po::store(po::command_line_parser(argc, argv)
            .options(opts)
            .positional(p)
            .run(),
            vm);
	}
	catch (std::exception& e)
	{
	  cerr << "caught command-line parsing error" << endl;
    std::cerr << e.what() << std::endl;
    exit(EXIT_FAILURE);
  }
  po::notify(vm);

  // if help is specified, or positional args aren't present,
  // or more than one loadX flag
  if( vm.count("help") || !vm.count("numberOfSlices") )
  {
    cerr << "Usage: "
      << argv[0]
      << " [--numberOfSlices=]100"
      << " [--inputSeriesFormat=]HiRes_%03d"
      << " [--outputFile=]HiRes.mha"
      << endl << endl;
    cerr << opts << "\n";
    exit(EXIT_FAILURE);
  }

  return vm;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: soundplayer.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 15:20:54 $
 *
 *  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_slideshow.hxx"

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/lang/XComponent.hdl>

#include <tools/urlobj.hxx>

#include "soundplayer.hxx"

#include <algorithm>

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

// TODO(Q3): This breaks encapsulation. Either export
// these strings from avmedia, or provide an XManager
// factory there
#ifdef WNT
#   define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.media.Manager_DirectX"
#else
#   define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.media.Manager_Java"
#endif

namespace slideshow
{
    namespace internal
    {
        // TODO(Q3): Move the whole SoundPlayer class to avmedia.

        boost::shared_ptr<SoundPlayer> SoundPlayer::create(
            EventMultiplexer & rEventMultiplexer,
            const ::rtl::OUString& rSoundURL,
            const uno::Reference< uno::XComponentContext>&  rComponentContext )
        {
            boost::shared_ptr<SoundPlayer> pPlayer(
                new SoundPlayer( rEventMultiplexer,
                                 rSoundURL,
                                 rComponentContext ) );
            rEventMultiplexer.addPauseHandler( pPlayer );
            pPlayer->mThis = pPlayer;
            return pPlayer;
        }

        bool SoundPlayer::handlePause( bool bPauseShow )
        {
            return bPauseShow ? stopPlayback() : startPlayback();
        }

        void SoundPlayer::dispose()
        {
            if( mThis )
            {
                mrEventMultiplexer.removePauseHandler( mThis );
                mThis.reset();
            }

            if( mxPlayer.is() )
            {
                mxPlayer->stop();
                uno::Reference<lang::XComponent> xComponent(
                    mxPlayer, uno::UNO_QUERY );
                if( xComponent.is() )
                    xComponent->dispose();
                mxPlayer.clear();
            }
        }

        SoundPlayer::SoundPlayer(
            EventMultiplexer & rEventMultiplexer,
            const ::rtl::OUString& rSoundURL,
            const uno::Reference< uno::XComponentContext>&  rComponentContext )
            : mrEventMultiplexer(rEventMultiplexer),
              mThis(),
              mxPlayer()
        {
            ENSURE_AND_THROW( rComponentContext.is(),
                              "SoundPlayer::SoundPlayer(): Invalid component context" );

            try
            {
                uno::Reference<lang::XMultiComponentFactory> xFac(
                    rComponentContext->getServiceManager() );

                uno::Reference< ::com::sun::star::media::XManager > xManager(
                    xFac->createInstanceWithContext(
                        ::rtl::OUString::createFromAscii( AVMEDIA_MANAGER_SERVICE_NAME ),
                        rComponentContext ),
                    uno::UNO_QUERY_THROW );

                const INetURLObject aURL( rSoundURL );
                mxPlayer.set( xManager->createPlayer(
                                aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ),
                                uno::UNO_QUERY_THROW );
            }
            catch( uno::Exception& )
            {
                throw lang::NoSupportException(
                    rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                       "No sound support for ") ) + rSoundURL,
                    uno::Reference<uno::XInterface>() );
            }
        }

        SoundPlayer::~SoundPlayer()
        {
            try
            {
                dispose();
            }
            catch (uno::Exception &) {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
        }

        double SoundPlayer::getDuration() const
        {
            if( !mxPlayer.is() )
                return 0.0;

            const double nDuration( mxPlayer->getDuration() );
            if( mxPlayer->isPlaying() )
                return ::std::max( 0.0,
                                   nDuration - mxPlayer->getMediaTime() );
            else
                return nDuration;
        }

        bool SoundPlayer::startPlayback()
        {
            if( !mxPlayer.is() )
                return false;

            if( mxPlayer->isPlaying() )
                mxPlayer->stop();

            mxPlayer->start();
            return true;
        }

        bool SoundPlayer::stopPlayback()
        {
            if( mxPlayer.is() )
                mxPlayer->stop();

            return true;
        }

    }
}
<commit_msg>INTEGRATION: CWS impress122 (1.6.30); FILE MERGED 2007/06/14 09:58:24 cl 1.6.30.1: #i24969# enable to play sound over more than one slide and allow stop sound<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: soundplayer.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 15:50:15 $
 *
 *  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_slideshow.hxx"

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/lang/XComponent.hdl>

#include <tools/urlobj.hxx>

#include "soundplayer.hxx"

#include <algorithm>

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

// TODO(Q3): This breaks encapsulation. Either export
// these strings from avmedia, or provide an XManager
// factory there
#ifdef WNT
#   define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.media.Manager_DirectX"
#else
#   define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.media.Manager_Java"
#endif

namespace slideshow
{
    namespace internal
    {
        // TODO(Q3): Move the whole SoundPlayer class to avmedia.

        boost::shared_ptr<SoundPlayer> SoundPlayer::create(
            EventMultiplexer & rEventMultiplexer,
            const ::rtl::OUString& rSoundURL,
            const uno::Reference< uno::XComponentContext>&  rComponentContext )
        {
            boost::shared_ptr<SoundPlayer> pPlayer(
                new SoundPlayer( rEventMultiplexer,
                                 rSoundURL,
                                 rComponentContext ) );
            rEventMultiplexer.addPauseHandler( pPlayer );
            pPlayer->mThis = pPlayer;
            return pPlayer;
        }

        bool SoundPlayer::handlePause( bool bPauseShow )
        {
            return bPauseShow ? stopPlayback() : startPlayback();
        }

        void SoundPlayer::dispose()
        {
            if( mThis )
            {
                mrEventMultiplexer.removePauseHandler( mThis );
                mThis.reset();
            }

            if( mxPlayer.is() )
            {
                mxPlayer->stop();
                uno::Reference<lang::XComponent> xComponent(
                    mxPlayer, uno::UNO_QUERY );
                if( xComponent.is() )
                    xComponent->dispose();
                mxPlayer.clear();
            }
        }

        SoundPlayer::SoundPlayer(
            EventMultiplexer & rEventMultiplexer,
            const ::rtl::OUString& rSoundURL,
            const uno::Reference< uno::XComponentContext>&  rComponentContext )
            : mrEventMultiplexer(rEventMultiplexer),
              mThis(),
              mxPlayer()
        {
            ENSURE_AND_THROW( rComponentContext.is(),
                              "SoundPlayer::SoundPlayer(): Invalid component context" );

            try
            {
                uno::Reference<lang::XMultiComponentFactory> xFac(
                    rComponentContext->getServiceManager() );

                uno::Reference< ::com::sun::star::media::XManager > xManager(
                    xFac->createInstanceWithContext(
                        ::rtl::OUString::createFromAscii( AVMEDIA_MANAGER_SERVICE_NAME ),
                        rComponentContext ),
                    uno::UNO_QUERY_THROW );

                const INetURLObject aURL( rSoundURL );
                mxPlayer.set( xManager->createPlayer(
                                aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ),
                                uno::UNO_QUERY_THROW );
            }
            catch( uno::Exception& )
            {
                throw lang::NoSupportException(
                    rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                       "No sound support for ") ) + rSoundURL,
                    uno::Reference<uno::XInterface>() );
            }
        }

        SoundPlayer::~SoundPlayer()
        {
            try
            {
                dispose();
            }
            catch (uno::Exception &) {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
        }

        double SoundPlayer::getDuration() const
        {
            if( !mxPlayer.is() )
                return 0.0;

            const double nDuration( mxPlayer->getDuration() );
            if( mxPlayer->isPlaying() )
                return ::std::max( 0.0,
                                   nDuration - mxPlayer->getMediaTime() );
            else
                return nDuration;
        }

        bool SoundPlayer::startPlayback()
        {
            if( !mxPlayer.is() )
                return false;

            if( mxPlayer->isPlaying() )
                mxPlayer->stop();

            mxPlayer->start();
            return true;
        }

        bool SoundPlayer::stopPlayback()
        {
            if( mxPlayer.is() )
                mxPlayer->stop();

            return true;
        }

        void SoundPlayer::setPlaybackLoop( bool bLoop )
        {
            if( mxPlayer.is() )
                mxPlayer->setPlaybackLoop( bLoop );
        }
    }
}
<|endoftext|>


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

#include "hal/us_ticker_api.h"
#include "hal/lp_ticker_api.h"
#include "mbed_atomic.h"
#include "mbed_critical.h"
#include "mbed_assert.h"
#include "platform/mbed_power_mgmt.h"
#include "platform/CriticalSectionLock.h"
#include "platform/SysTimer.h"
extern "C" {
#if MBED_CONF_RTOS_PRESENT
#include "rtx_lib.h"
#endif
}

#if (defined(NO_SYSTICK))
/**
 * Return an IRQ number that can be used in the absence of SysTick
 *
 * @return Free IRQ number that can be used
 */
extern "C" IRQn_Type mbed_get_m0_tick_irqn(void);
#endif

#if defined(TARGET_CORTEX_A)
extern "C" IRQn_ID_t mbed_get_a9_tick_irqn(void);
#endif

namespace mbed {
namespace internal {

template<uint32_t US_IN_TICK, bool IRQ>
SysTimer<US_IN_TICK, IRQ>::SysTimer() :
#if DEVICE_LPTICKER
    TimerEvent(get_lp_ticker_data()),
#else
    TimerEvent(get_us_ticker_data()),
#endif
    _time_us(ticker_read_us(_ticker_data)),
    _tick(0),
    _unacknowledged_ticks(0),
    _wake_time_set(false),
    _wake_time_passed(false),
    _ticking(false),
    _deep_sleep_locked(false)
{
    if (!_ticker_data->interface->runs_in_deep_sleep) {
        sleep_manager_lock_deep_sleep();
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
SysTimer<US_IN_TICK, IRQ>::SysTimer(const ticker_data_t *data) :
    TimerEvent(data),
    _time_us(ticker_read_us(_ticker_data)),
    _tick(0),
    _unacknowledged_ticks(0),
    _wake_time_set(false),
    _wake_time_passed(false),
    _ticking(false),
    _deep_sleep_locked(false)
{
    if (!_ticker_data->interface->runs_in_deep_sleep) {
        sleep_manager_lock_deep_sleep();
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
SysTimer<US_IN_TICK, IRQ>::~SysTimer()
{
    cancel_tick();
    cancel_wake();
    if (!_ticker_data->interface->runs_in_deep_sleep) {
        sleep_manager_unlock_deep_sleep();
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::set_wake_time(uint64_t at)
{
    // SysTimer must not be active - we must be in suspend state
    MBED_ASSERT(!_ticking);

    // There is a potential race here, when called from outside
    // a critical section. See function documentation for notes on
    // handling it.
    if (core_util_atomic_load_bool(&_wake_time_set)) {
        return;
    }

    // Analyse the timers
    if (update_and_get_tick() >= at) {
        _wake_time_passed = true;
        return;
    }

    uint64_t ticks_to_sleep = at - _tick;
    uint64_t wake_time = at * US_IN_TICK;

    /* Set this first, before attaching the interrupt that can unset it */
    _wake_time_set = true;
    _wake_time_passed = false;

    /* If deep sleep is unlocked, and we have enough time, let's go for it */
    if (MBED_CONF_TARGET_DEEP_SLEEP_LATENCY > 0 &&
            ticks_to_sleep > MBED_CONF_TARGET_DEEP_SLEEP_LATENCY &&
            sleep_manager_can_deep_sleep()) {
        /* Schedule the wake up interrupt early, allowing for the deep sleep latency */
        _wake_early = true;
        insert_absolute(wake_time - MBED_CONF_TARGET_DEEP_SLEEP_LATENCY * US_IN_TICK);
    } else {
        /* Otherwise, we'll set up for shallow sleep at the precise time.
         * To make absolutely sure it's shallow so we don't incur the latency,
         * take our own lock, to avoid a race on a thread unlocking it.
         */
        _wake_early = false;
        if (MBED_CONF_TARGET_DEEP_SLEEP_LATENCY > 0 && !_deep_sleep_locked) {
            _deep_sleep_locked = true;
            sleep_manager_lock_deep_sleep();
        }
        insert_absolute(wake_time);
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::cancel_wake()
{
    MBED_ASSERT(!_ticking);
    // Remove ensures serialized access to SysTimer by stopping timer interrupt
    remove();

    _wake_time_set = false;
    _wake_time_passed = false;

    if (_deep_sleep_locked) {
        _deep_sleep_locked = false;
        sleep_manager_unlock_deep_sleep();
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
uint64_t SysTimer<US_IN_TICK, IRQ>::_elapsed_ticks() const
{
    uint64_t elapsed_us = ticker_read_us(_ticker_data) - _time_us;
    if (elapsed_us < US_IN_TICK) {
        return 0;
    } else if (elapsed_us < 2 * US_IN_TICK) {
        return 1;
    } else if (elapsed_us <= 0xFFFFFFFF) {
        // Fast common case avoiding 64-bit division
        return (uint32_t) elapsed_us / US_IN_TICK;
    } else {
        return elapsed_us / US_IN_TICK;
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::start_tick()
{
    _ticking = true;
    if (_unacknowledged_ticks > 0) {
        _set_irq_pending();
    }
    _schedule_tick();
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::_schedule_tick()
{
    insert_absolute(_time_us + US_IN_TICK);
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::acknowledge_tick()
{
    // Try to avoid missed ticks if OS's IRQ level is not keeping
    // up with our handler.
    // 8-bit counter to save space, and also make sure it we don't
    // try TOO hard to resync if something goes really awry -
    // resync will reset if the count hits 256.
    if (core_util_atomic_decr_u8(&_unacknowledged_ticks, 1) > 0) {
        _set_irq_pending();
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::cancel_tick()
{
    // Underlying call is interrupt safe

    remove();
    _ticking = false;

    _clear_irq_pending();
}

template<uint32_t US_IN_TICK, bool IRQ>
uint64_t SysTimer<US_IN_TICK, IRQ>::get_tick() const
{
    // Atomic is necessary as this can be called from any foreground context,
    // while IRQ can update it.
    return core_util_atomic_load_u64(&_tick);
}

template<uint32_t US_IN_TICK, bool IRQ>
uint64_t SysTimer<US_IN_TICK, IRQ>::update_and_get_tick()
{
    MBED_ASSERT(!_ticking && !_wake_time_set);
    // Can only be used when no interrupts are scheduled
    // Update counters to reflect elapsed time
    uint64_t elapsed_ticks = _elapsed_ticks();
    _unacknowledged_ticks = 0;
    _time_us += elapsed_ticks * US_IN_TICK;
    _tick += elapsed_ticks;

    return _tick;
}

template<uint32_t US_IN_TICK, bool IRQ>
us_timestamp_t SysTimer<US_IN_TICK, IRQ>::get_time() const
{
    // Underlying call is interrupt safe

    return ticker_read_us(_ticker_data);
}

template<uint32_t US_IN_TICK, bool IRQ>
us_timestamp_t SysTimer<US_IN_TICK, IRQ>::get_time_since_tick() const
{
    // Underlying call is interrupt safe, and _time_us is not updated by IRQ

    return get_time() - _time_us;
}

#if (defined(NO_SYSTICK))
template<uint32_t US_IN_TICK, bool IRQ>
IRQn_Type SysTimer<US_IN_TICK, IRQ>::get_irq_number()
{
    return mbed_get_m0_tick_irqn();
}
#elif (TARGET_CORTEX_M)
template<uint32_t US_IN_TICK, bool IRQ>
IRQn_Type SysTimer<US_IN_TICK, IRQ>::get_irq_number()
{
    return SysTick_IRQn;
}
#elif (TARGET_CORTEX_A)
template<uint32_t US_IN_TICK, bool IRQ>
IRQn_ID_t SysTimer<US_IN_TICK, IRQ>::get_irq_number()
{
    return mbed_get_a9_tick_irqn();
}
#endif

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::_set_irq_pending()
{
    // Protected function synchronized externally
    if (!IRQ) {
        return;
    }
#if (defined(NO_SYSTICK))
    NVIC_SetPendingIRQ(mbed_get_m0_tick_irqn());
#elif (TARGET_CORTEX_M)
    SCB->ICSR = SCB_ICSR_PENDSTSET_Msk;
#else
    IRQ_SetPending(mbed_get_a9_tick_irqn());
#endif
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::_clear_irq_pending()
{
    // Protected function synchronized externally
    if (!IRQ) {
        return;
    }
#if (defined(NO_SYSTICK))
    NVIC_ClearPendingIRQ(mbed_get_m0_tick_irqn());
#elif (TARGET_CORTEX_M)
    SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk;
#else
    IRQ_ClearPending(mbed_get_a9_tick_irqn());
#endif
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::_increment_tick()
{
    // Protected function synchronized externally

    _tick++;
    _time_us += US_IN_TICK;
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::handler()
{
    /* To reduce IRQ latency problems, we do not re-arm in the interrupt handler */
    if (_wake_time_set) {
        _wake_time_set = false;
        if (!_wake_early) {
            _wake_time_passed = true;
        }
        /* If this was an early interrupt, user has the responsibility to check and
         * note the combination of (!set, !passed), and re-arm the wake timer if
         * necessary.
         */
    } else if (_ticking) {
        _unacknowledged_ticks++;
        _set_irq_pending();
        _increment_tick();
        // We do this now, rather than in acknowledgement, as we get it "for free"
        // here - because we're in the ticker handler, the programming gets deferred
        // until end of dispatch, and the ticker would likely be rescheduling
        // anyway after dispatch.

        _schedule_tick();
    }
}

#if MBED_CONF_RTOS_PRESENT
/* Whatever the OS wants (in case it isn't 1ms) */
MBED_STATIC_ASSERT(1000000 % OS_TICK_FREQ == 0, "OS_TICK_FREQ must be a divisor of 1000000 for correct tick calculations");
#define OS_TICK_US (1000000 / OS_TICK_FREQ)
#if OS_TICK_US != 1000
template class SysTimer<OS_TICK_US>;
#endif
#endif

/* Standard 1ms SysTimer */
template class SysTimer<1000>;

/* Standard 1ms SysTimer that doesn't set interrupts, used for Greentea tests */
template class SysTimer<1000, false>;

/* Slowed-down SysTimer that doesn't set interrupts, used for Greentea tests */
template class SysTimer<42000, false>;

} // namespace internal
} // namespace mbed
<commit_msg>SysTimer: don't always hold deep sleep lock<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2006-2019 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "hal/us_ticker_api.h"
#include "hal/lp_ticker_api.h"
#include "mbed_atomic.h"
#include "mbed_critical.h"
#include "mbed_assert.h"
#include "platform/mbed_power_mgmt.h"
#include "platform/CriticalSectionLock.h"
#include "platform/SysTimer.h"
extern "C" {
#if MBED_CONF_RTOS_PRESENT
#include "rtx_lib.h"
#endif
}

#if (defined(NO_SYSTICK))
/**
 * Return an IRQ number that can be used in the absence of SysTick
 *
 * @return Free IRQ number that can be used
 */
extern "C" IRQn_Type mbed_get_m0_tick_irqn(void);
#endif

#if defined(TARGET_CORTEX_A)
extern "C" IRQn_ID_t mbed_get_a9_tick_irqn(void);
#endif

namespace mbed {
namespace internal {

template<uint32_t US_IN_TICK, bool IRQ>
SysTimer<US_IN_TICK, IRQ>::SysTimer() :
#if DEVICE_LPTICKER
    TimerEvent(get_lp_ticker_data()),
#else
    TimerEvent(get_us_ticker_data()),
#endif
    _time_us(ticker_read_us(_ticker_data)),
    _tick(0),
    _unacknowledged_ticks(0),
    _wake_time_set(false),
    _wake_time_passed(false),
    _ticking(false),
    _deep_sleep_locked(false)
{
}

template<uint32_t US_IN_TICK, bool IRQ>
SysTimer<US_IN_TICK, IRQ>::SysTimer(const ticker_data_t *data) :
    TimerEvent(data),
    _time_us(ticker_read_us(_ticker_data)),
    _tick(0),
    _unacknowledged_ticks(0),
    _wake_time_set(false),
    _wake_time_passed(false),
    _ticking(false),
    _deep_sleep_locked(false)
{
}

template<uint32_t US_IN_TICK, bool IRQ>
SysTimer<US_IN_TICK, IRQ>::~SysTimer()
{
    cancel_tick();
    cancel_wake();
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::set_wake_time(uint64_t at)
{
    // SysTimer must not be active - we must be in suspend state
    MBED_ASSERT(!_ticking);

    // There is a potential race here, when called from outside
    // a critical section. See function documentation for notes on
    // handling it.
    if (core_util_atomic_load_bool(&_wake_time_set)) {
        return;
    }

    // Analyse the timers
    if (update_and_get_tick() >= at) {
        _wake_time_passed = true;
        return;
    }

    uint64_t ticks_to_sleep = at - _tick;
    uint64_t wake_time = at * US_IN_TICK;

    /* Set this first, before attaching the interrupt that can unset it */
    _wake_time_set = true;
    _wake_time_passed = false;

    if (!_deep_sleep_locked && !_ticker_data->interface->runs_in_deep_sleep) {
        _deep_sleep_locked = true;
        sleep_manager_lock_deep_sleep();
    }

    /* If deep sleep is unlocked, and we have enough time, let's go for it */
    if (MBED_CONF_TARGET_DEEP_SLEEP_LATENCY > 0 &&
            ticks_to_sleep > MBED_CONF_TARGET_DEEP_SLEEP_LATENCY &&
            sleep_manager_can_deep_sleep()) {
        /* Schedule the wake up interrupt early, allowing for the deep sleep latency */
        _wake_early = true;
        insert_absolute(wake_time - MBED_CONF_TARGET_DEEP_SLEEP_LATENCY * US_IN_TICK);
    } else {
        /* Otherwise, we'll set up for shallow sleep at the precise time.
         * To make absolutely sure it's shallow so we don't incur the latency,
         * take our own lock, to avoid a race on a thread unlocking it.
         */
        _wake_early = false;
        if (MBED_CONF_TARGET_DEEP_SLEEP_LATENCY > 0 && !_deep_sleep_locked) {
            _deep_sleep_locked = true;
            sleep_manager_lock_deep_sleep();
        }
        insert_absolute(wake_time);
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::cancel_wake()
{
    MBED_ASSERT(!_ticking);
    // Remove ensures serialized access to SysTimer by stopping timer interrupt
    remove();

    _wake_time_set = false;
    _wake_time_passed = false;

    if (_deep_sleep_locked) {
        _deep_sleep_locked = false;
        sleep_manager_unlock_deep_sleep();
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
uint64_t SysTimer<US_IN_TICK, IRQ>::_elapsed_ticks() const
{
    uint64_t elapsed_us = ticker_read_us(_ticker_data) - _time_us;
    if (elapsed_us < US_IN_TICK) {
        return 0;
    } else if (elapsed_us < 2 * US_IN_TICK) {
        return 1;
    } else if (elapsed_us <= 0xFFFFFFFF) {
        // Fast common case avoiding 64-bit division
        return (uint32_t) elapsed_us / US_IN_TICK;
    } else {
        return elapsed_us / US_IN_TICK;
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::start_tick()
{
    _ticking = true;
    if (_unacknowledged_ticks > 0) {
        _set_irq_pending();
    }
    _schedule_tick();
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::_schedule_tick()
{
    insert_absolute(_time_us + US_IN_TICK);
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::acknowledge_tick()
{
    // Try to avoid missed ticks if OS's IRQ level is not keeping
    // up with our handler.
    // 8-bit counter to save space, and also make sure it we don't
    // try TOO hard to resync if something goes really awry -
    // resync will reset if the count hits 256.
    if (core_util_atomic_decr_u8(&_unacknowledged_ticks, 1) > 0) {
        _set_irq_pending();
    }
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::cancel_tick()
{
    // Underlying call is interrupt safe

    remove();
    _ticking = false;

    _clear_irq_pending();
}

template<uint32_t US_IN_TICK, bool IRQ>
uint64_t SysTimer<US_IN_TICK, IRQ>::get_tick() const
{
    // Atomic is necessary as this can be called from any foreground context,
    // while IRQ can update it.
    return core_util_atomic_load_u64(&_tick);
}

template<uint32_t US_IN_TICK, bool IRQ>
uint64_t SysTimer<US_IN_TICK, IRQ>::update_and_get_tick()
{
    MBED_ASSERT(!_ticking && !_wake_time_set);
    // Can only be used when no interrupts are scheduled
    // Update counters to reflect elapsed time
    uint64_t elapsed_ticks = _elapsed_ticks();
    _unacknowledged_ticks = 0;
    _time_us += elapsed_ticks * US_IN_TICK;
    _tick += elapsed_ticks;

    return _tick;
}

template<uint32_t US_IN_TICK, bool IRQ>
us_timestamp_t SysTimer<US_IN_TICK, IRQ>::get_time() const
{
    // Underlying call is interrupt safe

    return ticker_read_us(_ticker_data);
}

template<uint32_t US_IN_TICK, bool IRQ>
us_timestamp_t SysTimer<US_IN_TICK, IRQ>::get_time_since_tick() const
{
    // Underlying call is interrupt safe, and _time_us is not updated by IRQ

    return get_time() - _time_us;
}

#if (defined(NO_SYSTICK))
template<uint32_t US_IN_TICK, bool IRQ>
IRQn_Type SysTimer<US_IN_TICK, IRQ>::get_irq_number()
{
    return mbed_get_m0_tick_irqn();
}
#elif (TARGET_CORTEX_M)
template<uint32_t US_IN_TICK, bool IRQ>
IRQn_Type SysTimer<US_IN_TICK, IRQ>::get_irq_number()
{
    return SysTick_IRQn;
}
#elif (TARGET_CORTEX_A)
template<uint32_t US_IN_TICK, bool IRQ>
IRQn_ID_t SysTimer<US_IN_TICK, IRQ>::get_irq_number()
{
    return mbed_get_a9_tick_irqn();
}
#endif

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::_set_irq_pending()
{
    // Protected function synchronized externally
    if (!IRQ) {
        return;
    }
#if (defined(NO_SYSTICK))
    NVIC_SetPendingIRQ(mbed_get_m0_tick_irqn());
#elif (TARGET_CORTEX_M)
    SCB->ICSR = SCB_ICSR_PENDSTSET_Msk;
#else
    IRQ_SetPending(mbed_get_a9_tick_irqn());
#endif
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::_clear_irq_pending()
{
    // Protected function synchronized externally
    if (!IRQ) {
        return;
    }
#if (defined(NO_SYSTICK))
    NVIC_ClearPendingIRQ(mbed_get_m0_tick_irqn());
#elif (TARGET_CORTEX_M)
    SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk;
#else
    IRQ_ClearPending(mbed_get_a9_tick_irqn());
#endif
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::_increment_tick()
{
    // Protected function synchronized externally

    _tick++;
    _time_us += US_IN_TICK;
}

template<uint32_t US_IN_TICK, bool IRQ>
void SysTimer<US_IN_TICK, IRQ>::handler()
{
    /* To reduce IRQ latency problems, we do not re-arm in the interrupt handler */
    if (_wake_time_set) {
        _wake_time_set = false;
        if (!_wake_early) {
            _wake_time_passed = true;
        }
        /* If this was an early interrupt, user has the responsibility to check and
         * note the combination of (!set, !passed), and re-arm the wake timer if
         * necessary.
         */
    } else if (_ticking) {
        _unacknowledged_ticks++;
        _set_irq_pending();
        _increment_tick();
        // We do this now, rather than in acknowledgement, as we get it "for free"
        // here - because we're in the ticker handler, the programming gets deferred
        // until end of dispatch, and the ticker would likely be rescheduling
        // anyway after dispatch.

        _schedule_tick();
    }
}

#if MBED_CONF_RTOS_PRESENT
/* Whatever the OS wants (in case it isn't 1ms) */
MBED_STATIC_ASSERT(1000000 % OS_TICK_FREQ == 0, "OS_TICK_FREQ must be a divisor of 1000000 for correct tick calculations");
#define OS_TICK_US (1000000 / OS_TICK_FREQ)
#if OS_TICK_US != 1000
template class SysTimer<OS_TICK_US>;
#endif
#endif

/* Standard 1ms SysTimer */
template class SysTimer<1000>;

/* Standard 1ms SysTimer that doesn't set interrupts, used for Greentea tests */
template class SysTimer<1000, false>;

/* Slowed-down SysTimer that doesn't set interrupts, used for Greentea tests */
template class SysTimer<42000, false>;

} // namespace internal
} // namespace mbed
<|endoftext|>


<commit_before>#pragma once
#include <SDL2/SDL_thread.h>
#include "spinner/misc.hpp"
#include "sdlwrap.hpp"
#include <functional>
#include <chrono>
#include <deque>
#include "spinner/optional.hpp"
#include "spinner/pqueue.hpp"

using Clock = std::chrono::steady_clock;
using Timepoint = typename Clock::time_point;
using Duration = typename Clock::duration;
namespace sdlw {
	extern SDL_threadID thread_local tls_threadID;
}

using Exec = std::function<void ()>;
class Handler;
class Looper;
using UPLooper = std::unique_ptr<Looper>;

struct Message;
using OPMessage = spn::Optional<Message>;

int GetNewMessageID();
struct MsgID {
	int id;
	operator int () const;
	bool operator == (const MsgID& m) const;
	bool operator < (const MsgID& m) const;
};
struct MsgBase {
	const static MsgID ID;
};

struct Message {
	const static Duration NoDelay;
	Timepoint	tpoint;
	MsgID		id;
	// IExecを呼び出すまでもないパラメータを渡す時に使用
	struct Data {
		constexpr static int PAYLOAD_SIZE = 32;
		uint8_t		data[PAYLOAD_SIZE];
		Data() = default;
		Data(const Data& d) {
			std::memcpy(this, &d, sizeof(*this));
		}
	};
	Data		data;
	Handler*	handler;
	Exec		exec;

	Message() = default;
	Message(const Message& m) = delete;
	Message(Message&& m);
	Message(Duration delay, Exec&& e);
	template <class T, class = typename std::is_base_of<MsgBase,T>::type>
	Message(Duration delay, const T& info, Exec&& e = Exec()): tpoint(Clock::now() + delay), id{info.ID}, handler(nullptr), exec(std::move(e)) {
		static_assert(sizeof(T) <= sizeof(Message::Data), "invalid payload size (T > Message_Default)");
		std::memcpy(&data, &info, sizeof(T));
	}

	void operator = (const Message& m) = delete;
	Message& operator = (Message&& m);
	bool operator < (const Message& m) const;

	template <class T,
			class = typename std::is_base_of<MsgBase,T>::type,
			class = typename std::enable_if<std::is_pointer<T>::value>::type>
	operator T () {
		using TR = typename std::remove_pointer<T>::type;
		if(id == TR::ID)
			return payload<TR>();
		return nullptr;
	}
	template <class T,
			class = typename std::is_base_of<MsgBase,T>::type,
			class = typename std::enable_if<std::is_pointer<T>::value>::type>
	operator const T () const {
		T t = const_cast<Message*>(this)->operator T();
		return (const T)t;
	}

	template <class T>
	T* payload() {
		static_assert(sizeof(T) <= sizeof(Message::Data), "invalid payload size (T > Message_Default)");
		return reinterpret_cast<T*>(&data);
	}
	template <class T>
	const T* payload() const {
		return const_cast<Message*>(this)->payload<T>();
	}
};

using MsgQueue = spn::pqueue<Message, std::deque>;
class Looper {
// 	static thread_local UPLooper tls_looper;
	static sdlw::TLS<Looper>	tls_looper;
	bool			_bRun = true;
	MsgQueue		_msg;
	sdlw::CondV		_cond;
	sdlw::Mutex		_mutex;

	OPMessage _procMessage(std::function<bool (sdlw::UniLock&)> lf);
	public:
		Looper() = default;
		Looper(const Looper&) = delete;
		Looper(Looper&& lp);
		Looper& operator = (Looper&& lp);
		// 呼び出したスレッドでキューがまだ用意されて無ければイベントキューを作成
		static void Prepare();
		// キューに溜まったメッセージをハンドラに渡す -> キューをクリア
		OPMessage wait();
		OPMessage peek(std::chrono::milliseconds msec);
		static Looper& GetLooper();
		void pushEvent(Message&& m);
		void setState(bool bRun);
};

class Handler {
	Looper&		_looper;

	friend class Looper;
	protected:
		virtual void handleMessage(const Message& msg);
	public:
		Handler(Looper& loop);
		Looper& getLooper() const;
		void post(Message&& m);
		template <class... Args>
		void postArgsDelay(Args&&... args) {
			post(Message(std::forward<Args>(args)...));
		}
		template <class... Args>
		void postArgs(Args&&... args) {
			post(Message(std::chrono::seconds(0), std::forward<Args>(args)...));
		}
};
<commit_msg>Looper付きスレッドを追加<commit_after>#pragma once
#include <SDL2/SDL_thread.h>
#include "spinner/misc.hpp"
#include "sdlwrap.hpp"
#include <functional>
#include <chrono>
#include <deque>
#include "spinner/optional.hpp"
#include "spinner/pqueue.hpp"

using Clock = std::chrono::steady_clock;
using Timepoint = typename Clock::time_point;
using Duration = typename Clock::duration;
namespace sdlw {
	extern SDL_threadID thread_local tls_threadID;
}

using Exec = std::function<void ()>;
class Handler;
class Looper;
using UPLooper = std::unique_ptr<Looper>;

struct Message;
using OPMessage = spn::Optional<Message>;

int GetNewMessageID();
struct MsgID {
	int id;
	operator int () const;
	bool operator == (const MsgID& m) const;
	bool operator < (const MsgID& m) const;
};
struct MsgBase {
	const static MsgID ID;
};

struct Message {
	const static Duration NoDelay;
	Timepoint	tpoint;
	MsgID		id;
	// IExecを呼び出すまでもないパラメータを渡す時に使用
	struct Data {
		constexpr static int PAYLOAD_SIZE = 32;
		uint8_t		data[PAYLOAD_SIZE];
		Data() = default;
		Data(const Data& d) {
			std::memcpy(this, &d, sizeof(*this));
		}
	};
	Data		data;
	Handler*	handler;
	Exec		exec;

	Message() = default;
	Message(const Message& m) = delete;
	Message(Message&& m);
	Message(Duration delay, Exec&& e);
	template <class T, class = typename std::is_base_of<MsgBase,T>::type>
	Message(Duration delay, const T& info, Exec&& e = Exec()): tpoint(Clock::now() + delay), id{info.ID}, handler(nullptr), exec(std::move(e)) {
		static_assert(sizeof(T) <= sizeof(Message::Data), "invalid payload size (T > Message_Default)");
		std::memcpy(&data, &info, sizeof(T));
	}

	void operator = (const Message& m) = delete;
	Message& operator = (Message&& m);
	bool operator < (const Message& m) const;

	template <class T,
			class = typename std::is_base_of<MsgBase,T>::type,
			class = typename std::enable_if<std::is_pointer<T>::value>::type>
	operator T () {
		using TR = typename std::remove_pointer<T>::type;
		if(id == TR::ID)
			return payload<TR>();
		return nullptr;
	}
	template <class T,
			class = typename std::is_base_of<MsgBase,T>::type,
			class = typename std::enable_if<std::is_pointer<T>::value>::type>
	operator const T () const {
		T t = const_cast<Message*>(this)->operator T();
		return (const T)t;
	}

	template <class T>
	T* payload() {
		static_assert(sizeof(T) <= sizeof(Message::Data), "invalid payload size (T > Message_Default)");
		return reinterpret_cast<T*>(&data);
	}
	template <class T>
	const T* payload() const {
		return const_cast<Message*>(this)->payload<T>();
	}
};

using MsgQueue = spn::pqueue<Message, std::deque>;
class Looper {
// 	static thread_local UPLooper tls_looper;
	static sdlw::TLS<Looper>	tls_looper;
	bool			_bRun = true;
	MsgQueue		_msg;
	sdlw::CondV		_cond;
	sdlw::Mutex		_mutex;

	OPMessage _procMessage(std::function<bool (sdlw::UniLock&)> lf);
	public:
		Looper() = default;
		Looper(const Looper&) = delete;
		Looper(Looper&& lp);
		Looper& operator = (Looper&& lp);
		// 呼び出したスレッドでキューがまだ用意されて無ければイベントキューを作成
		static void Prepare();
		// キューに溜まったメッセージをハンドラに渡す -> キューをクリア
		OPMessage wait();
		OPMessage peek(std::chrono::milliseconds msec);
		static Looper& GetLooper();
		void pushEvent(Message&& m);
		void setState(bool bRun);
};

class Handler {
	Looper&		_looper;

	friend class Looper;
	protected:
		virtual void handleMessage(const Message& msg);
	public:
		Handler(Looper& loop);
		Looper& getLooper() const;
		void post(Message&& m);
		template <class... Args>
		void postArgsDelay(Args&&... args) {
			post(Message(std::forward<Args>(args)...));
		}
		template <class... Args>
		void postArgs(Args&&... args) {
			post(Message(std::chrono::seconds(0), std::forward<Args>(args)...));
		}
};
namespace sdlw {
	//! Looper付きスレッド
	template <class T>
	class ThreadL;
	template <class RET, class... Args>
	class ThreadL<RET (Args...)> : public Thread<RET (Args...)> {
		private:
			using base = Thread<RET (Args...)>;
			Looper*	_pLooper = nullptr;
		protected:
			using base::base;
			RET run(Args&&... args) override final {
				Looper::Prepare();
				_pLooper = &Looper::GetLooper();
				return runL(std::forward<Args>(args)...);
			}
			virtual RET runL(Args&&... args) = 0;
		public:
			bool interrupt() override {
				if(base::interrupt()) {
					_pLooper->setState(false);
					return true;
				}
				return false;
			}
			Looper* getLooper() {
				return _pLooper;
			}
	};
}
<|endoftext|>


<commit_before>#include <sirius.h>

using namespace sirius;

void test(int nGb, int gran, memory_t M__)
{
    std::unique_ptr<memory_pool> mp;
    if (M__ == memory_t::host_pinned) {
        mp = std::unique_ptr<memory_pool>(new memory_pool(M__, size_t(4) * (1 << 30)));
    } else {
        mp = std::unique_ptr<memory_pool>(new memory_pool(M__, size_t(0) * (1 << 30)));
    }
    memory_pool& mpool = *mp;

    std::vector<uint32_t> sizes;
    size_t tot_size{0};

    while (tot_size < size_t(nGb) * (1 << 30)) {
        auto s = std::max(utils::rnd() % (size_t(gran) * (1 << 20)), size_t(1));
        sizes.push_back(s);
        tot_size += s;
    }

    std::cout << "number of memory blocks: " << sizes.size() << "\n";
    std::cout << "total size: " << tot_size << "\n";

    utils::timer t1("alloc");
    std::vector<mdarray<char, 1>> v;
    for (int k = 0; k < 4; k++) {
        auto t = -utils::wtime();
        v.clear();
        for (auto s: sizes) {
            v.push_back(std::move(mdarray<char, 1>(mpool, s)));
            v.back().zero(M__);
        }
        std::random_shuffle(v.begin(), v.end());
        for (auto& e: v) {
            e.deallocate(M__);
        }

        if (mpool.total_size() != tot_size) {
            throw std::runtime_error("wrong total size");
        }
        if (mpool.free_size() != mpool.total_size()) {
            throw std::runtime_error("wrong free size");
        }
        if (mpool.num_blocks() != 1) {
            throw std::runtime_error("wrong number of blocks");
        }
        if (mpool.num_stored_ptr() != 0) {
            throw std::runtime_error("wrong number of stored pointers");
        }
        t += utils::wtime();
        std::cout << "pass : " << k << ", time : " << t << "\n";
        print_memory_usage(__FILE__, __LINE__);
    }
    t1.stop();
    utils::timer::print();
}

void test1(memory_t M__)
{
    memory_pool mpool(M__);

    mdarray<char, 1> a(mpool, 100);
    a.deallocate(M__);

    mdarray<char, 1> b(mpool, 200);
    b.deallocate(M__);

    std::cout << mpool.total_size() << "\n";

}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--memory_t=", "{string} type of the memory");
    args.register_key("--nGb=", "{int} total number of Gigabytes to allocate");
    args.register_key("--gran=", "{int} block granularity in Mb");

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);
    test(args.value<int>("nGb", 2), args.value<int>("gran", 32), get_memory_t(args.value<std::string>("memory_t", "host")));
    //test1(get_memory_t(args.value<std::string>("memory_t", "host")));
    sirius::finalize();
}
<commit_msg>update test<commit_after>#include <sirius.h>

using namespace sirius;

void test(int nGb, int gran, memory_t M__)
{
    std::unique_ptr<memory_pool> mp;
    if (M__ == memory_t::host_pinned) {
        mp = std::unique_ptr<memory_pool>(new memory_pool(M__, size_t(4) * (1 << 30)));
    } else {
        mp = std::unique_ptr<memory_pool>(new memory_pool(M__, size_t(2) * (1 << 30)));
    }
    memory_pool& mpool = *mp;

    std::vector<uint32_t> sizes;
    size_t tot_size{0};

    while (tot_size < size_t(nGb) * (1 << 30)) {
        auto s = std::max(utils::rnd() % (size_t(gran) * (1 << 20)), size_t(1));
        sizes.push_back(s);
        tot_size += s;
    }

    std::cout << "number of memory blocks: " << sizes.size() << "\n";
    std::cout << "total size: " << tot_size << "\n";

    utils::timer t1("alloc");
    std::vector<mdarray<char, 1>> v;
    for (int k = 0; k < 4; k++) {
        auto t = -utils::wtime();
        v.clear();
        for (auto s: sizes) {
            v.push_back(std::move(mdarray<char, 1>(mpool, s)));
            v.back().zero(M__);
        }
        std::random_shuffle(v.begin(), v.end());
        for (auto& e: v) {
            e.deallocate(M__);
        }

        //if (mpool.total_size() != tot_size) {
        //    throw std::runtime_error("wrong total size");
        //}
        if (mpool.free_size() != mpool.total_size()) {
            throw std::runtime_error("wrong free size");
        }
        if (mpool.num_blocks() != 1) {
            throw std::runtime_error("wrong number of blocks");
        }
        if (mpool.num_stored_ptr() != 0) {
            throw std::runtime_error("wrong number of stored pointers");
        }
        t += utils::wtime();
        std::cout << "pass : " << k << ", time : " << t << "\n";
        print_memory_usage(__FILE__, __LINE__);
    }
    t1.stop();
    utils::timer::print();
}

void test1(memory_t M__)
{
    memory_pool mpool(M__);

    mdarray<char, 1> a(mpool, 100);
    a.deallocate(M__);

    mdarray<char, 1> b(mpool, 200);
    b.deallocate(M__);

    std::cout << mpool.total_size() << "\n";

}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--memory_t=", "{string} type of the memory");
    args.register_key("--nGb=", "{int} total number of Gigabytes to allocate");
    args.register_key("--gran=", "{int} block granularity in Mb");

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);
    test(args.value<int>("nGb", 2), args.value<int>("gran", 32), get_memory_t(args.value<std::string>("memory_t", "host")));
    //test1(get_memory_t(args.value<std::string>("memory_t", "host")));
    sirius::finalize();
}
<|endoftext|>


<commit_before>// @(#)root/ged:$Name:  $:$Id: TGedFrame.cxx,v 1.21 2007/02/07 09:00:41 antcheva Exp $
// Author: Ilka Antcheva   10/05/04

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TGedFrame                                                           //
//                                                                      //
//  Base frame for implementing GUI - a service class.                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGedFrame.h"
#include "TGedEditor.h"
#include "TG3DLine.h"
#include "TClass.h"
#include "TCanvas.h"
#include "TGLabel.h"
#include "TGToolTip.h"
#include "TGCanvas.h"
#include "TGScrollBar.h"
#include "snprintf.h"

ClassImp(TGedFrame)

//______________________________________________________________________________
TGedFrame::TGedFrame(const TGWindow *p, Int_t width,
                     Int_t height, UInt_t options, Pixel_t back)
      : TGCompositeFrame(p, width, height, options, back),
        fInit(kTRUE),
        fGedEditor(0),
        fModelClass(0),
        fLayoutHints(0),
        fAvoidSignal(kFALSE),
        fExtraTabs(0),
        fPriority(50)
{
   // Constructor of the base GUI attribute frame.

   fName = "";
   fGedEditor = TGedEditor::GetFrameCreator();
   SetCleanup(kDeepCleanup);
}

//______________________________________________________________________________
TGedFrame::~TGedFrame()
{
   // Destructor of the base GUI attribute frame.

   if (fExtraTabs) {
      TGedSubFrame* sf;
      TIter next(fExtraTabs);
      while ((sf = (TGedSubFrame*) next()) != 0) {
         delete sf->fFrame;
         fExtraTabs->Remove(sf);
         delete sf;
      }
      delete fExtraTabs;
   }
   delete fLayoutHints;

   // Destructor of TGCompositeFrame will do the rest.
}

//______________________________________________________________________________
void TGedFrame::Update()
{
   // Update the current pad when an attribute is changed via GUI.

   fGedEditor->Update(this);
}

//______________________________________________________________________________
Option_t *TGedFrame::GetDrawOption() const
{
   // Get draw options of the selected object.

   if (!fGedEditor->GetPad()) return "";

   TListIter next(fGedEditor->GetPad()->GetListOfPrimitives());
   TObject *obj;
   while ((obj = next())) {
      if (obj == fGedEditor->GetModel()) return next.GetOption();
   }
   return "";
}

//______________________________________________________________________________
TGLayoutHints* TGedFrame::GetLayoutHints()
{
   // Get layout hints with which is added to TGedEditor frame.

   if (fLayoutHints == 0){
      fLayoutHints = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2);
      fLayoutHints->AddReference();
   }
   return fLayoutHints;
}

//______________________________________________________________________________
void TGedFrame::MakeTitle(const char *title)
{
   // Create attribute frame title.

   TGCompositeFrame *f1 = new TGCompositeFrame(this, 145, 10, kHorizontalFrame |
                                                              kFitWidth |
                                                              kFixedWidth |
                                                              kOwnBackground);
   f1->AddFrame(new TGLabel(f1, title),
                new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
   f1->AddFrame(new TGHorizontal3DLine(f1),
                new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
   AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0));
}

//______________________________________________________________________________
void TGedFrame::AddExtraTab(TGedSubFrame* sf)
{
  // Adds tab container to list of extra tabs.

   if (fExtraTabs == 0) fExtraTabs = new TList();
   fExtraTabs->Add(sf);
   sf->fFrame->SetCleanup(kDeepCleanup);
}

//______________________________________________________________________________
TGVerticalFrame* TGedFrame::CreateEditorTabSubFrame(const Text_t* name)
{
   // Create a vertical frame to be used by 'owner' in extra tab 'name'.
   // The new frame is registered into the sub-frame list.

   TGCompositeFrame* tabcont  = fGedEditor->GetEditorTab(name);

   TGVerticalFrame* newframe = new TGVerticalFrame(tabcont);
   AddExtraTab(new TGedFrame::TGedSubFrame(TString(name), newframe));
   return newframe;
}

//______________________________________________________________________________
void TGedFrame::Refresh(TObject* model)
{
   // Refresh the GUI info about the object attributes.

   SetModel(model);
}

//______________________________________________________________________________
void TGedFrame::SetDrawOption(Option_t *option)
{
   // Set drawing option for object. This option only affects
   // the drawing style and is stored in the option field of the
   // TObjOptLink supporting a TPad's primitive list (TList).

   if (!fGedEditor->GetPad() || !option) return;

   TListIter next(fGedEditor->GetPad()->GetListOfPrimitives());
   delete fGedEditor->GetPad()->FindObject("Tframe");
   TObject *obj;
   while ((obj = next())) {
      if (obj == fGedEditor->GetModel()) {
         next.SetOption(option);
         fGedEditor->GetPad()->Modified();
         fGedEditor->GetPad()->Update();
         return;
      }
   }
}

//______________________________________________________________________________
void TGedFrame::ActivateBaseClassEditors(TClass* cl)
{
   // Provide list of editors for base-classes.
   // In this class we return all classed with editors found via recursive
   // descent into list of base classes.
   // Override to control which editors are actually shown (see TH2Editor).

   // printf("%s::FillListOfBaseEditors %s\n", IsA()->GetName(), cl->GetName());
   if (cl->GetListOfBases()->IsEmpty() == kFALSE) {
      fGedEditor->ActivateEditors(cl->GetListOfBases(), kTRUE);
   }
}

//______________________________________________________________________________
TGedNameFrame::TGedNameFrame(const TGWindow *p, Int_t width,
                              Int_t height, UInt_t options, Pixel_t back)
   : TGedFrame(p, width, height, options | kVerticalFrame, back)
{
   // Create the frame containing the selected object name.

   fPriority = 0;

   f1 = new TGCompositeFrame(this, 145, 10, kHorizontalFrame |
                                            kFixedWidth      |
                                            kOwnBackground);
   f1->AddFrame(new TGLabel(f1,"Name"),
                new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
   f1->AddFrame(new TGHorizontal3DLine(f1),
                new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
   AddFrame(f1, new TGLayoutHints(kLHintsTop));

   f2 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame | kFixedWidth);
   fLabel = new TGLabel(f2, "");
   f2->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
   AddFrame(f2, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0));

   // Set red color for the name.
   Pixel_t color;
   gClient->GetColorByName("#ff0000", color);
   fLabel->SetTextColor(color, kFALSE);

   // create tool tip with delay 300 ms
   fTip = new TGToolTip(fClient->GetDefaultRoot(), this, "TGedNameFrame", 500);

   AddInput(kEnterWindowMask | kLeaveWindowMask | kKeyPressMask | kButtonPressMask);
}

//______________________________________________________________________________
TGedNameFrame::~TGedNameFrame()
{
   // Destructor.

   fLayoutHints = 0; // will be deleted via deep-cleanup of tab-containers
   delete fTip;
}

//______________________________________________________________________________
Bool_t TGedNameFrame::HandleCrossing(Event_t *event)
{
   // Handle mouse crossing event for tooltip.

   if (event->fType == kEnterNotify)
      fTip->Reset();
   else
      fTip->Hide();

   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGedNameFrame::HandleButton(Event_t * /*event*/)
{
   // Handle mouse button event.

   if (fTip) fTip->Hide();

   return kFALSE;
}

//______________________________________________________________________________
void TGedNameFrame::SetModel(TObject* obj)
{
   // Sets text for the label.

   TString string;

   if (obj == 0) {
      fLabel->SetText(new TGString("Object not selected"));
      return;
   }
   string.Append(obj->GetName());
   string.Append("::");
   string.Append(obj->ClassName());

   fLabel->SetText(new TGString(string));
   string = Form("Name: '%s'; Title: '%s'; Class: '%s'", obj->GetName(), obj->GetTitle(), obj->ClassName());
   fTip->SetText(string);

   // Resize label-frame to a reasonable width.
   {
      TGCanvas     *canvas = fGedEditor->GetTGCanvas();
      TGVScrollBar *vsb    = canvas->GetVScrollbar();

      Int_t hscrollw = (vsb && vsb->IsMapped()) ? vsb->GetWidth() : 0;
      Int_t labwidth = TMath::Min(fLabel->GetDefaultSize().fWidth,
                                  canvas->GetWidth() - 10 - hscrollw);
      f2->SetWidth(TMath::Max(labwidth, 80));
   }
}
<commit_msg>From Matevz: Break tooltip with name, title and class of the object into multiple lines.<commit_after>// @(#)root/ged:$Name:  $:$Id: TGedFrame.cxx,v 1.22 2007/05/23 15:43:30 rdm Exp $
// Author: Ilka Antcheva   10/05/04

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TGedFrame                                                           //
//                                                                      //
//  Base frame for implementing GUI - a service class.                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGedFrame.h"
#include "TGedEditor.h"
#include "TG3DLine.h"
#include "TClass.h"
#include "TCanvas.h"
#include "TGLabel.h"
#include "TGToolTip.h"
#include "TGCanvas.h"
#include "TGScrollBar.h"
#include "snprintf.h"

ClassImp(TGedFrame)

//______________________________________________________________________________
TGedFrame::TGedFrame(const TGWindow *p, Int_t width,
                     Int_t height, UInt_t options, Pixel_t back)
      : TGCompositeFrame(p, width, height, options, back),
        fInit(kTRUE),
        fGedEditor(0),
        fModelClass(0),
        fLayoutHints(0),
        fAvoidSignal(kFALSE),
        fExtraTabs(0),
        fPriority(50)
{
   // Constructor of the base GUI attribute frame.

   fName = "";
   fGedEditor = TGedEditor::GetFrameCreator();
   SetCleanup(kDeepCleanup);
}

//______________________________________________________________________________
TGedFrame::~TGedFrame()
{
   // Destructor of the base GUI attribute frame.

   if (fExtraTabs) {
      TGedSubFrame* sf;
      TIter next(fExtraTabs);
      while ((sf = (TGedSubFrame*) next()) != 0) {
         delete sf->fFrame;
         fExtraTabs->Remove(sf);
         delete sf;
      }
      delete fExtraTabs;
   }
   delete fLayoutHints;

   // Destructor of TGCompositeFrame will do the rest.
}

//______________________________________________________________________________
void TGedFrame::Update()
{
   // Update the current pad when an attribute is changed via GUI.

   fGedEditor->Update(this);
}

//______________________________________________________________________________
Option_t *TGedFrame::GetDrawOption() const
{
   // Get draw options of the selected object.

   if (!fGedEditor->GetPad()) return "";

   TListIter next(fGedEditor->GetPad()->GetListOfPrimitives());
   TObject *obj;
   while ((obj = next())) {
      if (obj == fGedEditor->GetModel()) return next.GetOption();
   }
   return "";
}

//______________________________________________________________________________
TGLayoutHints* TGedFrame::GetLayoutHints()
{
   // Get layout hints with which is added to TGedEditor frame.

   if (fLayoutHints == 0){
      fLayoutHints = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2);
      fLayoutHints->AddReference();
   }
   return fLayoutHints;
}

//______________________________________________________________________________
void TGedFrame::MakeTitle(const char *title)
{
   // Create attribute frame title.

   TGCompositeFrame *f1 = new TGCompositeFrame(this, 145, 10, kHorizontalFrame |
                                                              kFitWidth |
                                                              kFixedWidth |
                                                              kOwnBackground);
   f1->AddFrame(new TGLabel(f1, title),
                new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
   f1->AddFrame(new TGHorizontal3DLine(f1),
                new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
   AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0));
}

//______________________________________________________________________________
void TGedFrame::AddExtraTab(TGedSubFrame* sf)
{
  // Adds tab container to list of extra tabs.

   if (fExtraTabs == 0) fExtraTabs = new TList();
   fExtraTabs->Add(sf);
   sf->fFrame->SetCleanup(kDeepCleanup);
}

//______________________________________________________________________________
TGVerticalFrame* TGedFrame::CreateEditorTabSubFrame(const Text_t* name)
{
   // Create a vertical frame to be used by 'owner' in extra tab 'name'.
   // The new frame is registered into the sub-frame list.

   TGCompositeFrame* tabcont  = fGedEditor->GetEditorTab(name);

   TGVerticalFrame* newframe = new TGVerticalFrame(tabcont);
   AddExtraTab(new TGedFrame::TGedSubFrame(TString(name), newframe));
   return newframe;
}

//______________________________________________________________________________
void TGedFrame::Refresh(TObject* model)
{
   // Refresh the GUI info about the object attributes.

   SetModel(model);
}

//______________________________________________________________________________
void TGedFrame::SetDrawOption(Option_t *option)
{
   // Set drawing option for object. This option only affects
   // the drawing style and is stored in the option field of the
   // TObjOptLink supporting a TPad's primitive list (TList).

   if (!fGedEditor->GetPad() || !option) return;

   TListIter next(fGedEditor->GetPad()->GetListOfPrimitives());
   delete fGedEditor->GetPad()->FindObject("Tframe");
   TObject *obj;
   while ((obj = next())) {
      if (obj == fGedEditor->GetModel()) {
         next.SetOption(option);
         fGedEditor->GetPad()->Modified();
         fGedEditor->GetPad()->Update();
         return;
      }
   }
}

//______________________________________________________________________________
void TGedFrame::ActivateBaseClassEditors(TClass* cl)
{
   // Provide list of editors for base-classes.
   // In this class we return all classed with editors found via recursive
   // descent into list of base classes.
   // Override to control which editors are actually shown (see TH2Editor).

   // printf("%s::FillListOfBaseEditors %s\n", IsA()->GetName(), cl->GetName());
   if (cl->GetListOfBases()->IsEmpty() == kFALSE) {
      fGedEditor->ActivateEditors(cl->GetListOfBases(), kTRUE);
   }
}

//______________________________________________________________________________
TGedNameFrame::TGedNameFrame(const TGWindow *p, Int_t width,
                              Int_t height, UInt_t options, Pixel_t back)
   : TGedFrame(p, width, height, options | kVerticalFrame, back)
{
   // Create the frame containing the selected object name.

   fPriority = 0;

   f1 = new TGCompositeFrame(this, 145, 10, kHorizontalFrame |
                                            kFixedWidth      |
                                            kOwnBackground);
   f1->AddFrame(new TGLabel(f1,"Name"),
                new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
   f1->AddFrame(new TGHorizontal3DLine(f1),
                new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
   AddFrame(f1, new TGLayoutHints(kLHintsTop));

   f2 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame | kFixedWidth);
   fLabel = new TGLabel(f2, "");
   f2->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
   AddFrame(f2, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0));

   // Set red color for the name.
   Pixel_t color;
   gClient->GetColorByName("#ff0000", color);
   fLabel->SetTextColor(color, kFALSE);

   // create tool tip with delay 300 ms
   fTip = new TGToolTip(fClient->GetDefaultRoot(), this, "TGedNameFrame", 500);

   AddInput(kEnterWindowMask | kLeaveWindowMask | kKeyPressMask | kButtonPressMask);
}

//______________________________________________________________________________
TGedNameFrame::~TGedNameFrame()
{
   // Destructor.

   fLayoutHints = 0; // will be deleted via deep-cleanup of tab-containers
   delete fTip;
}

//______________________________________________________________________________
Bool_t TGedNameFrame::HandleCrossing(Event_t *event)
{
   // Handle mouse crossing event for tooltip.

   if (event->fType == kEnterNotify)
      fTip->Reset();
   else
      fTip->Hide();

   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGedNameFrame::HandleButton(Event_t * /*event*/)
{
   // Handle mouse button event.

   if (fTip) fTip->Hide();

   return kFALSE;
}

//______________________________________________________________________________
void TGedNameFrame::SetModel(TObject* obj)
{
   // Sets text for the label.

   TString string;

   if (obj == 0) {
      fLabel->SetText(new TGString("Object not selected"));
      return;
   }
   string.Append(obj->GetName());
   string.Append("::");
   string.Append(obj->ClassName());

   fLabel->SetText(new TGString(string));
   string = Form("Name: %s\nTitle:   %s\nClass: %s",
                 obj->GetName(), obj->GetTitle(), obj->ClassName());
   fTip->SetText(string);

   // Resize label-frame to a reasonable width.
   {
      TGCanvas     *canvas = fGedEditor->GetTGCanvas();
      TGVScrollBar *vsb    = canvas->GetVScrollbar();

      Int_t hscrollw = (vsb && vsb->IsMapped()) ? vsb->GetWidth() : 0;
      Int_t labwidth = TMath::Min(fLabel->GetDefaultSize().fWidth,
                                  canvas->GetWidth() - 10 - hscrollw);
      f2->SetWidth(TMath::Max(labwidth, 80));
   }
}
<|endoftext|>


<commit_before><commit_msg>Fix SortedCollectBlock skipping issue. Resolves #1482.<commit_after><|endoftext|>