← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2760: Make atomic includes work on mingw

 

------------------------------------------------------------
revno: 2760
committer: Jacek Sieka <arnetheduck@xxxxxxxxx>
branch nick: dcplusplus
timestamp: Tue 2011-12-27 20:47:56 +0100
message:
  Make atomic includes work on mingw
removed:
  atomic/atomic
added:
  atomic/boost/atomic/detail/cas64strong.hpp
  dcpp/atomic.hpp
modified:
  SConstruct
  dcpp/BufferedSocket.h
  dcpp/Client.h
  dcpp/MappingManager.h
  dcpp/ShareManager.h
  dcpp/stdinc.h


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'SConstruct'
--- SConstruct	2011-12-27 13:41:47 +0000
+++ SConstruct	2011-12-27 19:47:56 +0000
@@ -138,7 +138,7 @@
 
 env.SConsignFile()
 
-env.Append(CPPPATH = ['#/', '#/boost/', '#/intl/'])
+env.Append(CPPPATH = ['#/', '#/boost/', '#/intl/', '#/atomic/'])
 
 if dev.is_win32():
 	# Windows header defines <http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx>
@@ -171,9 +171,6 @@
 	link_flags = msvc_link_flags
 	defs = msvc_defs
 
-	# MSVC 10 doesn't have <atomic> so add this regardless of the stdatomic setting
-	env.Append(CPPPATH = ['#/atomic/'])
-
 	env.Append(LIBS = ['User32', 'shell32', 'Advapi32'])
 
 else:
@@ -192,9 +189,6 @@
 
 	env.Tool("gch", toolpath=".")
 
-	if not env['stdatomic']:
-		env.Append(CPPPATH = ['#/atomic/'])
-
 	env.Append(CPPPATH = ['#/htmlhelp/preload/', '#/htmlhelp/include/'])
 	html_lib = '#/htmlhelp/lib/'
 	if env['arch'] != 'x86':

=== removed file 'atomic/atomic'
--- atomic/atomic	2011-12-16 17:07:49 +0000
+++ atomic/atomic	1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
-/* Alternative implementation of <atomic> from Boost.Atomic
- * <http://www.chaoticmind.net/~hcb/projects/boost.atomic/>. */
-
-#include <boost/atomic.hpp>
-
-namespace std {
-	using boost::atomic;
-	using boost::atomic_flag;
-}
-
-// vim: set filetype=cpp :

=== added file 'atomic/boost/atomic/detail/cas64strong.hpp'
--- atomic/boost/atomic/detail/cas64strong.hpp	1970-01-01 00:00:00 +0000
+++ atomic/boost/atomic/detail/cas64strong.hpp	2011-12-27 19:47:56 +0000
@@ -0,0 +1,434 @@
+#ifndef BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP
+#define BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  Copyright (c) 2011 Helge Bahmann
+
+// Build 64-bit atomic operation from platform_cmpxchg64_strong
+// primitive. It is assumed that 64-bit loads/stores are not
+// atomic, so they are funnelled through cmpxchg as well.
+
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/base.hpp>
+
+namespace boost {
+namespace detail {
+namespace atomic {
+
+/* integral types */
+
+template<typename T, bool Sign>
+class base_atomic<T, int, 8, Sign> {
+	typedef base_atomic this_type;
+	typedef T value_type;
+	typedef T difference_type;
+public:
+	explicit base_atomic(value_type v) : v_(v) {}
+	base_atomic(void) {}
+	
+	void
+	store(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type expected = v_;
+		do {
+		} while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
+	}
+	
+	value_type
+	load(memory_order order = memory_order_seq_cst) const volatile
+	{
+		value_type v = const_cast<const volatile value_type &>(v_);
+		do {
+		} while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
+		return v;
+	}
+	
+	value_type
+	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	bool
+	compare_exchange_weak(
+		value_type & expected,
+		value_type desired,
+		memory_order success_order,
+		memory_order failure_order) volatile
+	{
+		return compare_exchange_strong(expected, desired, success_order, failure_order);
+	}
+	
+	bool
+	compare_exchange_strong(
+		value_type & expected,
+		value_type desired,
+		memory_order success_order,
+		memory_order failure_order) volatile
+	{
+		platform_fence_before(success_order);
+		
+		bool success = platform_cmpxchg64_strong(expected, desired, &v_);
+		
+		if (success) {
+			platform_fence_after(success_order);
+		} else {
+			platform_fence_after(failure_order);
+		}
+		
+		return success;
+	}
+	
+	value_type
+	fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	value_type
+	fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	value_type
+	fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	value_type
+	fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	value_type
+	fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	bool
+	is_lock_free(void) const volatile
+	{
+		return true;
+	}
+	
+	BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
+private:
+	base_atomic(const base_atomic &) /* = delete */ ;
+	void operator=(const base_atomic &) /* = delete */ ;
+	value_type v_;
+};
+
+/* pointer types */
+
+template<bool Sign>
+class base_atomic<void *, void *, 8, Sign> {
+	typedef base_atomic this_type;
+	typedef void * value_type;
+	typedef ptrdiff_t difference_type;
+public:
+	explicit base_atomic(value_type v) : v_(v) {}
+	base_atomic(void) {}
+	
+	void
+	store(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type expected = v_;
+		do {
+		} while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
+	}
+	
+	value_type
+	load(memory_order order = memory_order_seq_cst) const volatile
+	{
+		value_type v = const_cast<const volatile value_type &>(v_);
+		do {
+		} while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
+		return v;
+	}
+	
+	value_type
+	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	bool
+	compare_exchange_weak(
+		value_type & expected,
+		value_type desired,
+		memory_order success_order,
+		memory_order failure_order) volatile
+	{
+		return compare_exchange_strong(expected, desired, success_order, failure_order);
+	}
+	
+	bool
+	compare_exchange_strong(
+		value_type & expected,
+		value_type desired,
+		memory_order success_order,
+		memory_order failure_order) volatile
+	{
+		platform_fence_before(success_order);
+		
+		bool success = platform_cmpxchg64_strong(expected, desired, &v_);
+		
+		if (success) {
+			platform_fence_after(success_order);
+		} else {
+			platform_fence_after(failure_order);
+		}
+		
+		return success;
+	}
+	
+	value_type
+	fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	value_type
+	fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	bool
+	is_lock_free(void) const volatile
+	{
+		return true;
+	}
+	
+	BOOST_ATOMIC_DECLARE_BASE_OPERATORS
+private:
+	base_atomic(const base_atomic &) /* = delete */ ;
+	void operator=(const base_atomic &) /* = delete */ ;
+	value_type v_;
+};
+
+template<typename T, bool Sign>
+class base_atomic<T *, void *, 8, Sign> {
+	typedef base_atomic this_type;
+	typedef T * value_type;
+	typedef ptrdiff_t difference_type;
+public:
+	explicit base_atomic(value_type v) : v_(v) {}
+	base_atomic(void) {}
+	
+	void
+	store(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type expected = v_;
+		do {
+		} while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
+	}
+	
+	value_type
+	load(memory_order order = memory_order_seq_cst) const volatile
+	{
+		value_type v = const_cast<const volatile value_type &>(v_);
+		do {
+		} while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
+		return v;
+	}
+	
+	value_type
+	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	bool
+	compare_exchange_weak(
+		value_type & expected,
+		value_type desired,
+		memory_order success_order,
+		memory_order failure_order) volatile
+	{
+		return compare_exchange_strong(expected, desired, success_order, failure_order);
+	}
+	
+	bool
+	compare_exchange_strong(
+		value_type & expected,
+		value_type desired,
+		memory_order success_order,
+		memory_order failure_order) volatile
+	{
+		platform_fence_before(success_order);
+		
+		bool success = platform_cmpxchg64_strong(expected, desired, &v_);
+		
+		if (success) {
+			platform_fence_after(success_order);
+		} else {
+			platform_fence_after(failure_order);
+		}
+		
+		return success;
+	}
+	
+	value_type
+	fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	value_type
+	fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	bool
+	is_lock_free(void) const volatile
+	{
+		return true;
+	}
+	
+	BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
+private:
+	base_atomic(const base_atomic &) /* = delete */ ;
+	void operator=(const base_atomic &) /* = delete */ ;
+	value_type v_;
+};
+
+/* generic types */
+
+template<typename T, bool Sign>
+class base_atomic<T, void, 8, Sign> {
+	typedef base_atomic this_type;
+	typedef T value_type;
+	typedef uint64_t storage_type;
+public:
+	explicit base_atomic(value_type v) : v_(0)
+	{
+		memcpy(&v_, &v, sizeof(value_type));
+	}
+	base_atomic(void) : v_(0) {}
+	
+	void
+	store(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type expected;
+		memcpy(&expected, const_cast<storage_type *>(&v_), sizeof(value_type));
+		do {
+		} while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
+	}
+	
+	value_type
+	load(memory_order order = memory_order_seq_cst) const volatile
+	{
+		value_type v;
+		memcpy(&v, const_cast<storage_type *>(&v_), sizeof(value_type));
+		do {
+		} while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
+		return v;
+	}
+	
+	value_type
+	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
+	{
+		value_type original = load(memory_order_relaxed);
+		do {
+		} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
+		return original;
+	}
+	
+	bool
+	compare_exchange_weak(
+		value_type & expected,
+		value_type desired,
+		memory_order success_order,
+		memory_order failure_order) volatile
+	{
+		return compare_exchange_strong(expected, desired, success_order, failure_order);
+	}
+	
+	bool
+	compare_exchange_strong(
+		value_type & expected,
+		value_type desired,
+		memory_order success_order,
+		memory_order failure_order) volatile
+	{
+		
+		storage_type expected_s = 0, desired_s = 0;
+		memcpy(&expected_s, &expected, sizeof(value_type));
+		memcpy(&desired_s, &desired, sizeof(value_type));
+		
+		platform_fence_before(success_order);
+		bool success = platform_cmpxchg64_strong(expected_s, desired_s, &v_);
+		
+		if (success) {
+			platform_fence_after(success_order);
+		} else {
+			platform_fence_after(failure_order);
+			memcpy(&expected, &expected_s, sizeof(value_type));
+		}
+		
+		return success;
+	}
+	
+	bool
+	is_lock_free(void) const volatile
+	{
+		return true;
+	}
+	
+	BOOST_ATOMIC_DECLARE_BASE_OPERATORS
+private:
+	base_atomic(const base_atomic &) /* = delete */ ;
+	void operator=(const base_atomic &) /* = delete */ ;
+	storage_type v_;
+};
+
+}
+}
+}
+
+#endif

=== modified file 'dcpp/BufferedSocket.h'
--- dcpp/BufferedSocket.h	2011-09-24 21:13:31 +0000
+++ dcpp/BufferedSocket.h	2011-12-27 19:47:56 +0000
@@ -19,7 +19,6 @@
 #ifndef DCPLUSPLUS_DCPP_BUFFERED_SOCKET_H
 #define DCPLUSPLUS_DCPP_BUFFERED_SOCKET_H
 
-#include <atomic>
 #include <deque>
 #include <memory>
 
@@ -30,10 +29,10 @@
 #include "Thread.h"
 #include "Speaker.h"
 #include "Socket.h"
+#include "atomic.hpp"
 
 namespace dcpp {
 
-using std::atomic;
 using std::deque;
 using std::pair;
 using std::unique_ptr;

=== modified file 'dcpp/Client.h'
--- dcpp/Client.h	2011-12-03 21:53:57 +0000
+++ dcpp/Client.h	2011-12-27 19:47:56 +0000
@@ -21,8 +21,6 @@
 
 #include "compiler.h"
 
-#include <atomic>
-
 #include "forward.h"
 
 #include "Speaker.h"
@@ -30,11 +28,10 @@
 #include "TimerManager.h"
 #include "ClientListener.h"
 #include "OnlineUser.h"
+#include "atomic.hpp"
 
 namespace dcpp {
 
-using std::atomic;
-
 /** Yes, this should probably be called a Hub */
 class Client : public Speaker<ClientListener>, public BufferedSocketListener, protected TimerManagerListener {
 public:

=== modified file 'dcpp/MappingManager.h'
--- dcpp/MappingManager.h	2011-12-17 16:25:32 +0000
+++ dcpp/MappingManager.h	2011-12-27 19:47:56 +0000
@@ -19,7 +19,6 @@
 #ifndef DCPLUSPLUS_DCPP_MAPPING_MANAGER_H
 #define DCPLUSPLUS_DCPP_MAPPING_MANAGER_H
 
-#include <atomic>
 #include <memory>
 #include <functional>
 #include <vector>
@@ -28,10 +27,10 @@
 #include "typedefs.h"
 #include "Mapper.h"
 #include "TimerManager.h"
+#include "atomic.hpp"
 
 namespace dcpp {
 
-using std::atomic_flag;
 using std::function;
 using std::unique_ptr;
 using std::vector;

=== modified file 'dcpp/ShareManager.h'
--- dcpp/ShareManager.h	2011-04-13 19:16:51 +0000
+++ dcpp/ShareManager.h	2011-12-27 19:47:56 +0000
@@ -19,7 +19,6 @@
 #ifndef DCPLUSPLUS_DCPP_SHARE_MANAGER_H
 #define DCPLUSPLUS_DCPP_SHARE_MANAGER_H
 
-#include <atomic>
 #include <list>
 #include <memory>
 #include <set>
@@ -40,12 +39,13 @@
 #include "MerkleTree.h"
 #include "Pointer.h"
 
+#include "atomic.hpp"
+
 namespace dcpp {
 
 using std::set;
 using std::unique_ptr;
 using std::unordered_map;
-using std::atomic_flag;
 
 STANDARD_EXCEPTION(ShareException);
 

=== added file 'dcpp/atomic.hpp'
--- dcpp/atomic.hpp	1970-01-01 00:00:00 +0000
+++ dcpp/atomic.hpp	2011-12-27 19:47:56 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2001-2011 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DCPLUSPLUS_DCPP_ATOMIC_HPP_
+#define DCPLUSPLUS_DCPP_ATOMIC_HPP_
+
+// GCC 4.6 and below has issues with atomic - see https://bugs.launchpad.net/dcplusplus/+bug/735512
+// MSVC 10 doesn't have atomic at all
+#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)) || defined(_MSC_VER)
+
+#include <boost/atomic/atomic.hpp>
+
+namespace dcpp
+{
+
+using boost::atomic;
+using boost::atomic_flag;
+
+}
+
+#else
+
+#include <atomic>
+
+namespace dcpp
+{
+
+using std::atomic;
+using std::atomic_flag;
+
+}
+
+#endif
+
+
+
+#endif /* DCPLUSPLUS_DCPP_ATOMIC_HPP_ */

=== modified file 'dcpp/stdinc.h'
--- dcpp/stdinc.h	2011-10-13 13:43:14 +0000
+++ dcpp/stdinc.h	2011-12-27 19:47:56 +0000
@@ -55,7 +55,6 @@
 #include <ctime>
 
 #include <algorithm>
-#include <atomic>
 #include <deque>
 #include <functional>
 #include <list>