switch over to use boost.atomic instead of home-built one

This commit is contained in:
Arvid Norberg 2014-08-01 07:32:54 +00:00
parent f32f5e96aa
commit c60ceacb71
12 changed files with 38 additions and 167 deletions

View File

@ -15,7 +15,6 @@ nobase_include_HEADERS = \
alloca.hpp \ alloca.hpp \
allocator.hpp \ allocator.hpp \
assert.hpp \ assert.hpp \
atomic.hpp \
bandwidth_limit.hpp \ bandwidth_limit.hpp \
bandwidth_manager.hpp \ bandwidth_manager.hpp \
bandwidth_socket.hpp \ bandwidth_socket.hpp \

View File

@ -1,131 +0,0 @@
/*
Copyright (c) 2012-2013, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_ATOMIC_HPP_INCLUDED
#define TORRENT_ATOMIC_HPP_INCLUDED
#include "libtorrent/config.hpp"
#if TORRENT_USE_OSATOMIC
#include <libkern/OSAtomic.h>
#endif
#if TORRENT_USE_INTERLOCKED_ATOMIC
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif
#if TORRENT_USE_BEOS_ATOMIC
#include <be/support/SupportDefs.h>
#endif
#if TORRENT_USE_SOLARIS_ATOMIC
#include <atomic.h>
#endif
namespace libtorrent
{
struct atomic_count
{
atomic_count() : m_value(0) {}
atomic_count(int v) : m_value(v) {}
#if TORRENT_USE_INTERLOCKED_ATOMIC
typedef LONG value_type;
#elif TORRENT_USE_SOLARIS_ATOMIC
typedef unsigned int value_type;
#else
typedef int value_type;
#endif
#if TORRENT_USE_OSATOMIC
operator value_type() const { return OSAtomicAdd32(0, const_cast<value_type*>(&m_value)); }
value_type operator-=(int v) { return OSAtomicAdd32Barrier(-v, &m_value); }
value_type operator+=(int v) { return OSAtomicAdd32Barrier(v, &m_value); }
// pre inc/dec operators
value_type operator++() { return OSAtomicAdd32Barrier(1, &m_value); }
value_type operator--() { return OSAtomicAdd32Barrier(-1, &m_value); }
// post inc/dec operators
value_type operator++(int) { return OSAtomicAdd32Barrier(1, &m_value)-1; }
value_type operator--(int) { return OSAtomicAdd32Barrier(-1, &m_value)+1; }
#elif TORRENT_USE_GCC_ATOMIC
operator value_type() const { return __sync_fetch_and_add(const_cast<value_type*>(&m_value), 0); }
value_type operator-=(value_type v) { return __sync_sub_and_fetch(&m_value, v); }
value_type operator+=(value_type v) { return __sync_add_and_fetch(&m_value, v); }
// pre inc/dec operators
value_type operator++() { return __sync_add_and_fetch(&m_value, 1); }
value_type operator--() { return __sync_add_and_fetch(&m_value, -1); }
// post inc/dec operators
value_type operator++(int) { return __sync_fetch_and_add(&m_value, 1); }
value_type operator--(int) { return __sync_fetch_and_add(&m_value, -1); }
#elif TORRENT_USE_INTERLOCKED_ATOMIC
operator value_type() const { return InterlockedExchangeAdd(const_cast<value_type*>(&m_value), 0); }
value_type operator-=(value_type v) { return InterlockedExchangeAdd(&m_value, -v); }
value_type operator+=(value_type v) { return InterlockedExchangeAdd(&m_value, v); }
// pre inc/dec operators
value_type operator++() { return InterlockedIncrement(&m_value); }
value_type operator--() { return InterlockedDecrement(&m_value); }
// post inc/dec operators
value_type operator++(int) { return InterlockedIncrement(&m_value) - 1; }
value_type operator--(int) { return InterlockedDecrement(&m_value) + 1; }
#elif TORRENT_USE_SOLARIS_ATOMIC
operator value_type() const { return atomic_add_32_nv(const_cast<value_type*>(&m_value), 0); }
value_type operator-=(value_type v) { return atomic_add_32(&m_value, -v); }
value_type operator+=(value_type v) { return atomic_add_32(&m_value, v); }
// pre inc/dec operators
value_type operator++() { return atomic_add_32_nv(&m_value, 1); }
value_type operator--() { return atomic_add_32_nv(&m_value, -1); }
// post inc/dec operators
value_type operator++(int) { return atomic_add_32_nv(&m_value, 1) - 1; }
value_type operator--(int) { return atomic_add_32_nv(&m_value, -1) + 1; }
#elif TORRENT_USE_BEOS_ATOMIC
operator value_type() const { return atomic_add(const_cast<value_type*>(&m_value), 0); }
value_type operator-=(value_type v) { return atomic_add(&m_value, -v) - v; }
value_type operator+=(value_type v) { return atomic_add(&m_value, v) + v; }
// pre inc/dec operators
value_type operator++() { return atomic_add(&m_value, 1) + 1; }
value_type operator--() { return atomic_add(&m_value, -1) - 1; }
// post inc/dec operators
value_type operator++(int) { return atomic_add(&m_value, 1); }
value_type operator--(int) { return atomic_add(&m_value, -1); }
#else
#error "don't know which atomic operations to use"
#endif
private:
volatile value_type m_value;
};
}
#endif

View File

@ -56,7 +56,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include "libtorrent/aux_/session_settings.hpp" #include "libtorrent/aux_/session_settings.hpp"
#include "libtorrent/thread.hpp" #include "libtorrent/thread.hpp"
#include "libtorrent/atomic.hpp" #include <boost/atomic.hpp>
namespace libtorrent namespace libtorrent
{ {
@ -146,9 +146,10 @@ namespace libtorrent
std::vector<cached_piece_info> pieces; std::vector<cached_piece_info> pieces;
#ifndef TORRENT_NO_DEPRECATE
// the total number of 16 KiB blocks written to disk // the total number of 16 KiB blocks written to disk
// since this session was started. // since this session was started.
atomic_count blocks_written; int blocks_written;
// the total number of write operations performed since this // the total number of write operations performed since this
// session was started. // session was started.
@ -156,22 +157,21 @@ namespace libtorrent
// The ratio (``blocks_written`` - ``writes``) / ``blocks_written`` represents // The ratio (``blocks_written`` - ``writes``) / ``blocks_written`` represents
// the number of saved write operations per total write operations. i.e. a kind // the number of saved write operations per total write operations. i.e. a kind
// of cache hit ratio for the write cahe. // of cache hit ratio for the write cahe.
atomic_count writes; int writes;
// the number of blocks that were requested from the // the number of blocks that were requested from the
// bittorrent engine (from peers), that were served from disk or cache. // bittorrent engine (from peers), that were served from disk or cache.
atomic_count blocks_read; int blocks_read;
// the number of blocks that was just copied from the read cache // the number of blocks that was just copied from the read cache
// //
// The ratio ``blocks_read_hit`` / ``blocks_read`` is the cache hit ratio // The ratio ``blocks_read_hit`` / ``blocks_read`` is the cache hit ratio
// for the read cache. // for the read cache.
size_type blocks_read_hit; int blocks_read_hit;
// the number of read operations used // the number of read operations used
atomic_count reads; int reads;
#ifndef TORRENT_NO_DEPRECATE
// the number of bytes queued for writing, including bytes // the number of bytes queued for writing, including bytes
// submitted to the OS for writing, but not yet complete // submitted to the OS for writing, but not yet complete
mutable size_type queued_bytes; mutable size_type queued_bytes;
@ -217,10 +217,10 @@ namespace libtorrent
// the number of milliseconds spent in all disk jobs, and specific ones // the number of milliseconds spent in all disk jobs, and specific ones
// since the start of the session. Times are specified in milliseconds // since the start of the session. Times are specified in milliseconds
atomic_count cumulative_job_time; int cumulative_job_time;
atomic_count cumulative_read_time; int cumulative_read_time;
atomic_count cumulative_write_time; int cumulative_write_time;
atomic_count cumulative_hash_time; int cumulative_hash_time;
// the number of blocks that had to be read back from disk because // the number of blocks that had to be read back from disk because
// they were flushed before the SHA-1 hash got to hash them. If this // they were flushed before the SHA-1 hash got to hash them. If this
@ -500,12 +500,12 @@ namespace libtorrent
// this is a counter which is atomically incremented // this is a counter which is atomically incremented
// by each thread as it's started up, in order to // by each thread as it's started up, in order to
// assign a unique id to each thread // assign a unique id to each thread
atomic_count m_num_threads; boost::atomic<int> m_num_threads;
// this is a counter of how many threads are currently running. // this is a counter of how many threads are currently running.
// it's used to identify the last thread still running while // it's used to identify the last thread still running while
// shutting down. This last thread is responsible for cleanup // shutting down. This last thread is responsible for cleanup
atomic_count m_num_running_threads; boost::atomic<int> m_num_running_threads;
// the actual threads running disk jobs // the actual threads running disk jobs
std::vector<boost::shared_ptr<thread> > m_threads; std::vector<boost::shared_ptr<thread> > m_threads;
@ -554,7 +554,7 @@ namespace libtorrent
// limit the number of jobs issued in parallel. It also creates // limit the number of jobs issued in parallel. It also creates
// an opportunity to sort the jobs by physical offset before // an opportunity to sort the jobs by physical offset before
// issued to the AIO subsystem // issued to the AIO subsystem
atomic_count m_outstanding_jobs; boost::atomic<int> m_outstanding_jobs;
// this is the main thread io_service. Callbacks are // this is the main thread io_service. Callbacks are
// posted on this in order to have them execute in // posted on this in order to have them execute in
@ -565,7 +565,7 @@ namespace libtorrent
// jobs are queued up in their respective storage, waiting for // jobs are queued up in their respective storage, waiting for
// the fence to be lowered. This counter is just used to know // the fence to be lowered. This counter is just used to know
// when it's OK to exit the main loop of the disk thread // when it's OK to exit the main loop of the disk thread
atomic_count m_num_blocked_jobs; boost::atomic<int> m_num_blocked_jobs;
// this keeps the io_service::run() call blocked from // this keeps the io_service::run() call blocked from
// returning. When shutting down, it's possible that // returning. When shutting down, it's possible that

View File

@ -37,11 +37,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/intrusive_ptr.hpp> #include <boost/intrusive_ptr.hpp>
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
#include "libtorrent/atomic.hpp" #include <boost/atomic.hpp>
namespace libtorrent namespace libtorrent
{ {
// TODO: 2 remove this class and transition over to using shared_ptr and make_shared instead // TODO: 2 remove this class and transition over to using shared_ptr and
// make_shared instead
template<class T> template<class T>
struct intrusive_ptr_base struct intrusive_ptr_base
{ {
@ -76,7 +77,7 @@ namespace libtorrent
private: private:
// reference counter for intrusive_ptr // reference counter for intrusive_ptr
mutable atomic_count m_refs; mutable boost::atomic<int> m_refs;
}; };
} }

View File

@ -48,6 +48,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/intrusive_ptr.hpp> #include <boost/intrusive_ptr.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <boost/atomic.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
@ -61,7 +62,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/file.hpp" #include "libtorrent/file.hpp"
#include "libtorrent/disk_buffer_holder.hpp" #include "libtorrent/disk_buffer_holder.hpp"
#include "libtorrent/thread.hpp" #include "libtorrent/thread.hpp"
#include "libtorrent/atomic.hpp"
#include "libtorrent/storage_defs.hpp" #include "libtorrent/storage_defs.hpp"
#include "libtorrent/allocator.hpp" #include "libtorrent/allocator.hpp"
#include "libtorrent/file_pool.hpp" // pool_file_status #include "libtorrent/file_pool.hpp" // pool_file_status
@ -575,7 +575,8 @@ namespace libtorrent
// but the flush job should be posted (i.e. put on the job queue) // but the flush job should be posted (i.e. put on the job queue)
// fence_post_none if both the fence and the flush jobs were queued. // fence_post_none if both the fence and the flush jobs were queued.
enum { fence_post_fence = 0, fence_post_flush = 1, fence_post_none = 2 }; enum { fence_post_fence = 0, fence_post_flush = 1, fence_post_none = 2 };
int raise_fence(disk_io_job* fence_job, disk_io_job* flush_job, atomic_count* blocked_counter); int raise_fence(disk_io_job* fence_job, disk_io_job* flush_job
, boost::atomic<int>* blocked_counter);
bool has_fence() const; bool has_fence() const;
// called whenever a job completes and is posted back to the // called whenever a job completes and is posted back to the
@ -607,7 +608,7 @@ namespace libtorrent
// to this torrent, currently pending, hanging off of // to this torrent, currently pending, hanging off of
// cached_piece_entry objects. This is used to determine // cached_piece_entry objects. This is used to determine
// when the fence can be lowered // when the fence can be lowered
atomic_count m_outstanding_jobs; boost::atomic<int> m_outstanding_jobs;
// must be held when accessing m_has_fence and // must be held when accessing m_has_fence and
// m_blocked_jobs // m_blocked_jobs

View File

@ -35,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/thread.hpp" #include "libtorrent/thread.hpp"
#include "libtorrent/atomic.hpp" #include <boost/atomic.hpp>
#include <deque> #include <deque>
#include <vector> #include <vector>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
@ -152,7 +152,7 @@ namespace libtorrent
// this is a counter which is atomically incremented // this is a counter which is atomically incremented
// by each thread as it's started up, in order to // by each thread as it's started up, in order to
// assign a unique id to each thread // assign a unique id to each thread
atomic_count m_num_threads; boost::atomic<int> m_num_threads;
}; };
} }

View File

@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#if TORRENT_PRODUCTION_ASSERTS #if TORRENT_PRODUCTION_ASSERTS
#include "libtorrent/atomic.hpp" #include <boost/atomic.hpp>
#endif #endif
#if (defined TORRENT_DEBUG && !TORRENT_NO_ASSERTS) || defined TORRENT_ASIO_DEBUGGING || defined TORRENT_PROFILE_CALLS || TORRENT_RELEASE_ASSERTS #if (defined TORRENT_DEBUG && !TORRENT_NO_ASSERTS) || defined TORRENT_ASIO_DEBUGGING || defined TORRENT_PROFILE_CALLS || TORRENT_RELEASE_ASSERTS
@ -213,7 +213,7 @@ TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth)
#if TORRENT_PRODUCTION_ASSERTS #if TORRENT_PRODUCTION_ASSERTS
char const* libtorrent_assert_log = "asserts.log"; char const* libtorrent_assert_log = "asserts.log";
// the number of asserts we've printed to the log // the number of asserts we've printed to the log
libtorrent::atomic_count assert_counter(0); boost::atomic<int> assert_counter(0);
#endif #endif
TORRENT_EXPORT void assert_print(char const* fmt, ...) TORRENT_EXPORT void assert_print(char const* fmt, ...)
@ -241,7 +241,7 @@ TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
{ {
#if TORRENT_PRODUCTION_ASSERTS #if TORRENT_PRODUCTION_ASSERTS
// no need to flood the assert log with infinite number of asserts // no need to flood the assert log with infinite number of asserts
if (++assert_counter > 500) return; if (assert_counter.fetch_add(1) + 1 > 500) return;
#endif #endif
char stack[8192]; char stack[8192];
@ -274,7 +274,7 @@ TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
"%s\n" "%s\n"
, message , message
#if TORRENT_PRODUCTION_ASSERTS #if TORRENT_PRODUCTION_ASSERTS
, int(assert_counter) , assert_counter.load()
#endif #endif
, file, line, function, expr , file, line, function, expr
, value ? value : "", value ? "\n" : "" , value ? value : "", value ? "\n" : ""

View File

@ -101,7 +101,7 @@ namespace libtorrent
{ {
#ifdef TORRENT_DISK_STATS #ifdef TORRENT_DISK_STATS
static atomic_count event_id; static boost::atomic<int> event_id;
static mutex disk_access_mutex; static mutex disk_access_mutex;
// this is opened and closed by the disk_io_thread class // this is opened and closed by the disk_io_thread class
@ -1600,7 +1600,8 @@ namespace libtorrent
// j is the fence job. It must have exclusive access to the storage // j is the fence job. It must have exclusive access to the storage
// fj is the flush job. If the job j is queued, we need to issue // fj is the flush job. If the job j is queued, we need to issue
// this job // this job
int disk_job_fence::raise_fence(disk_io_job* j, disk_io_job* fj, atomic_count* blocked_counter) int disk_job_fence::raise_fence(disk_io_job* j, disk_io_job* fj
, boost::atomic<int>* blocked_counter)
{ {
TORRENT_ASSERT((j->flags & disk_io_job::fence) == 0); TORRENT_ASSERT((j->flags & disk_io_job::fence) == 0);
j->flags |= disk_io_job::fence; j->flags |= disk_io_job::fence;

View File

@ -152,13 +152,13 @@ namespace libtorrent
, m_total_uploaded(0) , m_total_uploaded(0)
, m_total_downloaded(0) , m_total_downloaded(0)
, m_tracker_timer(ses.get_io_service()) , m_tracker_timer(ses.get_io_service())
, m_stats_counters(ses.stats_counters())
, m_host_resolver(ses.get_io_service()) , m_host_resolver(ses.get_io_service())
, m_trackerid(p.trackerid) , m_trackerid(p.trackerid)
, m_save_path(complete(p.save_path)) , m_save_path(complete(p.save_path))
, m_url(p.url) , m_url(p.url)
, m_uuid(p.uuid) , m_uuid(p.uuid)
, m_source_feed_url(p.source_feed_url) , m_source_feed_url(p.source_feed_url)
, m_stats_counters(ses.stats_counters())
, m_storage_constructor(p.storage) , m_storage_constructor(p.storage)
, m_added_time(time(0)) , m_added_time(time(0))
, m_completed_time(0) , m_completed_time(0)

View File

@ -54,7 +54,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket_type.hpp" #include "libtorrent/socket_type.hpp"
#include "libtorrent/instantiate_connection.hpp" #include "libtorrent/instantiate_connection.hpp"
#include "libtorrent/ip_filter.hpp" #include "libtorrent/ip_filter.hpp"
#include "libtorrent/atomic.hpp"
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
#include <boost/asio/ssl/stream.hpp> #include <boost/asio/ssl/stream.hpp>

View File

@ -36,7 +36,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/session.hpp" #include "libtorrent/session.hpp"
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include "test.hpp" #include "test.hpp"
#include "libtorrent/atomic.hpp"
namespace libtorrent namespace libtorrent
{ {

View File

@ -2,12 +2,14 @@
#include "libtorrent/disk_io_job.hpp" #include "libtorrent/disk_io_job.hpp"
#include "test.hpp" #include "test.hpp"
#include <boost/atomic.hpp>
using namespace libtorrent; using namespace libtorrent;
void test_disk_job_empty_fence() void test_disk_job_empty_fence()
{ {
libtorrent::disk_job_fence fence; libtorrent::disk_job_fence fence;
atomic_count counter(0); boost::atomic<int> counter(0);
disk_io_job test_job[10]; disk_io_job test_job[10];
@ -42,7 +44,7 @@ void test_disk_job_empty_fence()
void test_disk_job_fence() void test_disk_job_fence()
{ {
atomic_count counter(0); boost::atomic<int> counter(0);
libtorrent::disk_job_fence fence; libtorrent::disk_job_fence fence;
disk_io_job test_job[10]; disk_io_job test_job[10];
@ -115,7 +117,7 @@ void test_disk_job_fence()
void test_disk_job_double_fence() void test_disk_job_double_fence()
{ {
atomic_count counter(0); boost::atomic<int> counter(0);
libtorrent::disk_job_fence fence; libtorrent::disk_job_fence fence;
disk_io_job test_job[10]; disk_io_job test_job[10];