%PDF- %PDF-
| Direktori : /proc/self/root/usr/include/boost/sort/block_indirect_sort/blk_detail/ |
| Current File : //proc/self/root/usr/include/boost/sort/block_indirect_sort/blk_detail/backbone.hpp |
//----------------------------------------------------------------------------
/// @file backbone.hpp
/// @brief This file constains the class backbone, which is part of the
/// block_indirect_sort algorithm
///
/// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n
/// Distributed under the Boost Software License, Version 1.0.\n
/// ( See accompanying file LICENSE_1_0.txt or copy at
/// http://www.boost.org/LICENSE_1_0.txt )
/// @version 0.1
///
/// @remarks
//-----------------------------------------------------------------------------
#ifndef __BOOST_SORT_PARALLEL_DETAIL_BACKBONE_HPP
#define __BOOST_SORT_PARALLEL_DETAIL_BACKBONE_HPP
#include <atomic>
#include <boost/sort/pdqsort/pdqsort.hpp>
#include <boost/sort/common/util/atomic.hpp>
#include <boost/sort/common/util/algorithm.hpp>
#include <boost/sort/common/stack_cnc.hpp>
#include <future>
#include <iostream>
#include <iterator>
#include <boost/sort/block_indirect_sort/blk_detail/block.hpp>
namespace boost
{
namespace sort
{
namespace blk_detail
{
//---------------------------------------------------------------------------
// USING SENTENCES
//---------------------------------------------------------------------------
namespace bsc = boost::sort::common;
namespace bscu = bsc::util;
using bsc::stack_cnc;
using bsc::range;
///---------------------------------------------------------------------------
/// @struct backbone
/// @brief This contains all the information shared betwen the classes of the
/// block indirect sort algorithm
//----------------------------------------------------------------------------
template < uint32_t Block_size, class Iter_t, class Compare >
struct backbone
{
//-------------------------------------------------------------------------
// D E F I N I T I O N S
//-------------------------------------------------------------------------
typedef typename std::iterator_traits< Iter_t >::value_type value_t;
typedef std::atomic< uint32_t > atomic_t;
typedef range< size_t > range_pos;
typedef range< Iter_t > range_it;
typedef range< value_t * > range_buf;
typedef std::function< void(void) > function_t;
typedef block< Block_size, Iter_t > block_t;
//------------------------------------------------------------------------
// V A R I A B L E S
//------------------------------------------------------------------------
// range with all the element to sort
range< Iter_t > global_range;
// index vector of block_pos elements
std::vector< block_pos > index;
// Number of elements to sort
size_t nelem;
// Number of blocks to sort
size_t nblock;
// Number of elements in the last block (tail)
size_t ntail;
// object for to compare two elements
Compare cmp;
// range of elements of the last block (tail)
range_it range_tail;
// thread local varible. It is a pointer to the buffer
static thread_local value_t *buf;
// concurrent stack where store the function_t elements
stack_cnc< function_t > works;
// global indicator of error
bool error;
//
//------------------------------------------------------------------------
// F U N C T I O N S
//------------------------------------------------------------------------
backbone (Iter_t first, Iter_t last, Compare comp);
//------------------------------------------------------------------------
// function : get_block
/// @brief obtain the block in the position pos
/// @param pos : position of the range
/// @return block required
//------------------------------------------------------------------------
block_t get_block (size_t pos) const
{
return block_t (global_range.first + (pos * Block_size));
};
//-------------------------------------------------------------------------
// function : get_range
/// @brief obtain the range in the position pos
/// @param pos : position of the range
/// @return range required
//-------------------------------------------------------------------------
range_it get_range (size_t pos) const
{
Iter_t it1 = global_range.first + (pos * Block_size);
Iter_t it2 =
(pos == (nblock - 1)) ? global_range.last : it1 + Block_size;
return range_it (it1, it2);
};
//-------------------------------------------------------------------------
// function : get_range_buf
/// @brief obtain the auxiliary buffer of the thread
//-------------------------------------------------------------------------
range_buf get_range_buf ( ) const
{
return range_buf (buf, buf + Block_size);
};
//-------------------------------------------------------------------------
// function : exec
/// @brief Initialize the thread local buffer with the ptr_buf pointer,
/// and begin with the execution of the functions stored in works
//
/// @param ptr_buf : Pointer to the memory assigned to the thread_local
/// buffer
/// @param counter : atomic counter for to invoke to the exec function
/// with only 1 parameter
//-------------------------------------------------------------------------
void exec (value_t *ptr_buf, atomic_t &counter)
{
buf = ptr_buf;
exec (counter);
};
void exec (atomic_t &counter);
//---------------------------------------------------------------------------
}; // end struct backbone
//---------------------------------------------------------------------------
//
//############################################################################
// ##
// ##
// N O N I N L I N E F U N C T I O N S ##
// ##
// ##
//############################################################################
//
// initialization of the thread_local pointer to the auxiliary buffer
template < uint32_t Block_size, class Iter_t, class Compare >
thread_local typename std::iterator_traits< Iter_t >
::value_type *backbone< Block_size, Iter_t, Compare >::buf = nullptr;
//------------------------------------------------------------------------
// function : backbone
/// @brief constructor of the class
//
/// @param first : iterator to the first element of the range to sort
/// @param last : iterator after the last element to the range to sort
/// @param comp : object for to compare two elements pointed by Iter_t
/// iterators
//------------------------------------------------------------------------
template < uint32_t Block_size, class Iter_t, class Compare >
backbone< Block_size, Iter_t, Compare >
::backbone (Iter_t first, Iter_t last, Compare comp)
: global_range (first, last), cmp (comp), error (false)
{
assert ((last - first) >= 0);
if (first == last) return; // nothing to do
nelem = size_t (last - first);
nblock = (nelem + Block_size - 1) / Block_size;
ntail = (nelem % Block_size);
index.reserve (nblock + 1);
for (size_t i = 0; i < nblock; ++i) index.emplace_back (block_pos (i));
range_tail.first =
(ntail == 0) ? last : (first + ((nblock - 1) * Block_size));
range_tail.last = last;
};
//
//-------------------------------------------------------------------------
// function : exec
/// @brief execute the function_t stored in works, until counter is zero
//
/// @param counter : atomic counter. When 0 exits the function
//-------------------------------------------------------------------------
template < uint32_t Block_size, class Iter_t, class Compare >
void backbone< Block_size, Iter_t, Compare >::exec (atomic_t &counter)
{
function_t func_exec;
while (bscu::atomic_read (counter) != 0)
{
if (works.pop_move_back (func_exec)) func_exec ( );
else std::this_thread::yield ( );
};
};
//
//****************************************************************************
}; // End namespace blk_detail
}; // End namespace sort
}; // End namespace boost
//****************************************************************************
#endif