Merge lp:~olafvdspek/drizzle/refactor11 into lp:~drizzle-trunk/drizzle/development

Proposed by Olaf van der Spek
Status: Work in progress
Proposed branch: lp:~olafvdspek/drizzle/refactor11
Merge into: lp:~drizzle-trunk/drizzle/development
Diff against target: 329 lines (+48/-100)
4 files modified
drizzled/atomic/gcc_traits.h (+0/-4)
drizzled/atomic/pthread_traits.h (+0/-6)
drizzled/atomics.h (+39/-53)
unittests/pthread_atomics_test.cc (+9/-37)
To merge this branch: bzr merge lp:~olafvdspek/drizzle/refactor11
Reviewer Review Type Date Requested Status
Monty Taylor Needs Information
Review via email: mp+82055@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Mark Atwood (fallenpegasus) wrote :

Hi. Touching the atomics and the trait constructors needs to be reviewed by Brian. I'm asking him to review this before merging.

Revision history for this message
Monty Taylor (mordred) wrote :

I would be interested in an explanation of what your refactor is doing in the atomic classes. I'm not saying that it's wrong, but the template code in there isn't exactly friendly, so I'd like to know what it is you're shooting for here.

review: Needs Information
Revision history for this message
Olaf van der Spek (olafvdspek) wrote :

On Tue, Nov 15, 2011 at 7:48 PM, Monty Taylor <email address hidden> wrote:
> Review: Needs Information
>
> I would be interested in an explanation of what your refactor is doing in the atomic classes. I'm not saying that it's wrong, but the template code in there isn't exactly friendly, so I'd like to know what it is you're shooting for here.

I removed emptry constructors and destructors.
Moved atomic_base into atomic_impl.
Removed a type.

--
Olaf

Revision history for this message
Monty Taylor (mordred) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/15/2011 05:04 PM, Olaf van der Spek wrote:
> On Tue, Nov 15, 2011 at 7:48 PM, Monty Taylor
> <email address hidden> wrote:
>> Review: Needs Information
>>
>> I would be interested in an explanation of what your refactor is
>> doing in the atomic classes. I'm not saying that it's wrong, but
>> the template code in there isn't exactly friendly, so I'd like to
>> know what it is you're shooting for here.
>
> I removed emptry constructors and destructors. Moved atomic_base
> into atomic_impl. Removed a type.

So - more specifically:

What are you accomplishing with the atomic_base -> atomic_impl move.
(not saying it's bad - I just want to know what you wanted to do here)

Why did you remove the empty constructors? They were preventing
default constructors from writing data to memory locations that we
didn't want them to write to?

Additionally - the pthread_atomics_test was there specifically to test
that the pthread-based atomic class worked, even if you happened to be
running the tests on a machine that happened to have real atomic
support. With the change to use the top-level atomic class, the test
no longer tests that.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk7CvGEACgkQ2Jv7/VK1RgHwjwCg7Z+H8fbm8sVVA2T+EJjpEXgm
T2gAnRewAHJ/sEOshwZj1DlyXazdE02s
=aVWw
-----END PGP SIGNATURE-----

Revision history for this message
Olaf van der Spek (olafvdspek) wrote :

On Tue, Nov 15, 2011 at 8:28 PM, Monty Taylor <email address hidden> wrote:
> What are you accomplishing with the atomic_base -> atomic_impl move.
> (not saying it's bad - I just want to know what you wanted to do here)

Simpler code.

> Why did you remove the empty constructors? They were preventing
> default constructors from writing data to memory locations that we
> didn't want them to write to?

Eh, to what memory would default constructors write?

> Additionally - the pthread_atomics_test was there specifically to test
> that the pthread-based atomic class worked, even if you happened to be
> running the tests on a machine that happened to have real atomic
> support. With the change to use the top-level atomic class, the test
> no longer tests that.

Ah. Does it make sense to test code you're not going to use though?

--
Olaf

Revision history for this message
Brian Aker (brianaker) wrote :

@Olaf I'd leave the atomic implementation alone. This is an area where in the future someone could want what you are removing (and what has tests).

re: query_id
Right now it is one step closer to being encapsulated for catalogs, why remove that?

For if(), go on and put { } around what you expect it to execute. Over the years I've found just too many unintended bugs based on code getting shuffled, and no one realizing that the behavior of the branch had changed.

Revision history for this message
Olaf van der Spek (olafvdspek) wrote :

On Wed, Nov 16, 2011 at 10:08 AM, Brian Aker <email address hidden> wrote:
> @Olaf I'd leave the atomic implementation alone. This is an area where in the future someone could want what you are removing (and what has tests).

I'll restore the tests to test the pthread implementation.
But what removed code could someone want in the future?

> re: query_id
> Right now it is one step closer to being encapsulated for catalogs, why remove that?

How does it relate to catalogs?

Olaf

lp:~olafvdspek/drizzle/refactor11 updated
2462. By Olaf van der Spek

Merge trunk

Revision history for this message
Olaf van der Spek (olafvdspek) wrote :

On Tue, Nov 15, 2011 at 8:37 PM, Olaf van der Spek <email address hidden> wrote:
> On Tue, Nov 15, 2011 at 8:28 PM, Monty Taylor <email address hidden> wrote:
>> What are you accomplishing with the atomic_base -> atomic_impl move.
>> (not saying it's bad - I just want to know what you wanted to do here)
>
> Simpler code.
>
>> Why did you remove the empty constructors? They were preventing
>> default constructors from writing data to memory locations that we
>> didn't want them to write to?
>
> Eh, to what memory would default constructors write?
>
>> Additionally - the pthread_atomics_test was there specifically to test
>> that the pthread-based atomic class worked, even if you happened to be
>> running the tests on a machine that happened to have real atomic
>> support. With the change to use the top-level atomic class, the test
>> no longer tests that.
>
> Ah. Does it make sense to test code you're not going to use though?

Monty?

--
Olaf

lp:~olafvdspek/drizzle/refactor11 updated
2463. By Olaf van der Spek

Merge trunk

2464. By Olaf van der Spek

Merge trunk

Unmerged revisions

2464. By Olaf van der Spek

Merge trunk

2463. By Olaf van der Spek

Merge trunk

2462. By Olaf van der Spek

Merge trunk

2461. By Olaf van der Spek

Refactor

2460. By Olaf van der Spek

Refactor

2459. By Olaf van der Spek

Refactor

2458. By Olaf van der Spek

Refactor

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'drizzled/atomic/gcc_traits.h'
2--- drizzled/atomic/gcc_traits.h 2011-03-14 05:40:28 +0000
3+++ drizzled/atomic/gcc_traits.h 2011-12-16 16:07:29 +0000
4@@ -25,12 +25,9 @@
5 template<typename T, typename D>
6 class gcc_traits
7 {
8-
9 public:
10 typedef T value_type;
11
12- gcc_traits() {}
13-
14 inline value_type add_and_fetch(volatile value_type *value, D addend )
15 {
16 return __sync_add_and_fetch(value, addend);
17@@ -91,4 +88,3 @@
18
19 } /* namespace internal */
20 } /* namespace drizzled */
21-
22
23=== modified file 'drizzled/atomic/pthread_traits.h'
24--- drizzled/atomic/pthread_traits.h 2011-03-14 05:40:28 +0000
25+++ drizzled/atomic/pthread_traits.h 2011-12-16 16:07:29 +0000
26@@ -21,7 +21,6 @@
27 #pragma once
28
29 namespace drizzled {
30-
31 namespace internal {
32
33 class mutex_wrapper
34@@ -61,11 +60,8 @@
35 mutex_wrapper my_lock;
36
37 public:
38-
39 typedef T value_type;
40
41- pthread_traits() {}
42-
43 inline value_type add_and_fetch(volatile value_type *value, D addend )
44 {
45 my_lock.lock();
46@@ -147,5 +143,3 @@
47
48 } /* namespace internal */
49 } /* namespace drizzled */
50-
51-
52
53=== modified file 'drizzled/atomics.h'
54--- drizzled/atomics.h 2011-08-14 17:04:01 +0000
55+++ drizzled/atomics.h 2011-12-16 16:07:29 +0000
56@@ -38,80 +38,67 @@
57 namespace drizzled {
58 namespace internal {
59
60-template<typename I> // Primary template
61-struct atomic_base {
62- volatile I my_value;
63- atomic_base() : my_value(0) {}
64- virtual ~atomic_base() {}
65-};
66-
67-template<typename I, typename D, typename T >
68-class atomic_impl: private atomic_base<I>
69+template<typename T, typename TR>
70+class atomic_impl
71 {
72- T traits;
73+ TR traits;
74+ volatile T my_value;
75 public:
76- typedef I value_type;
77-
78- atomic_impl() : atomic_base<I>(), traits() {}
79-
80- value_type add_and_fetch( D addend )
81+ typedef T value_type;
82+
83+ atomic_impl() : my_value(0) {}
84+
85+ value_type add_and_fetch( T addend )
86 {
87- return traits.add_and_fetch(&this->my_value, addend);
88+ return traits.add_and_fetch(&my_value, addend);
89 }
90
91- value_type fetch_and_add( D addend )
92+ value_type fetch_and_add( T addend )
93 {
94- return traits.fetch_and_add(&this->my_value, addend);
95+ return traits.fetch_and_add(&my_value, addend);
96 }
97
98 value_type fetch_and_increment()
99 {
100- return traits.fetch_and_increment(&this->my_value);
101+ return traits.fetch_and_increment(&my_value);
102 }
103
104 value_type fetch_and_decrement()
105 {
106- return traits.fetch_and_decrement(&this->my_value);
107+ return traits.fetch_and_decrement(&my_value);
108 }
109
110 value_type fetch_and_store( value_type value )
111 {
112- return traits.fetch_and_store(&this->my_value, value);
113+ return traits.fetch_and_store(&my_value, value);
114 }
115
116 bool compare_and_swap( value_type value, value_type comparand )
117 {
118- return traits.compare_and_swap(&this->my_value, value, comparand);
119+ return traits.compare_and_swap(&my_value, value, comparand);
120 }
121
122 operator value_type() const volatile
123 {
124- return traits.fetch(&this->my_value);
125- }
126-
127- value_type& _internal_reference() const
128- {
129- return this->my_value;
130- }
131-
132-protected:
133- value_type store_with_release( value_type rhs )
134- {
135- return traits.store_with_release(&this->my_value, rhs);
136- }
137-
138-public:
139- atomic_impl<I,D,T>& operator+=( D addend )
140+ return traits.fetch(&my_value);
141+ }
142+
143+ void store_with_release( value_type value )
144+ {
145+ traits.store_with_release(&my_value, value);
146+ }
147+
148+ atomic_impl& operator+=( T addend )
149 {
150 increment(addend);
151 return *this;
152 }
153
154- atomic_impl<I,D,T>& operator-=( D addend )
155+ atomic_impl& operator-=( T addend )
156 {
157 // Additive inverse of addend computed using binary minus,
158 // instead of unary minus, for sake of avoiding compiler warnings.
159- return operator+=(D(0)-addend);
160+ return operator+=(T(0)-addend);
161 }
162
163 value_type increment()
164@@ -121,7 +108,7 @@
165
166 value_type decrement()
167 {
168- return add_and_fetch(D(-1));
169+ return add_and_fetch(T(-1));
170 }
171 };
172
173@@ -131,15 +118,16 @@
174 /** See the Reference for details.
175 @ingroup synchronization */
176 template<typename T>
177-struct atomic {
178+struct atomic
179+{
180 };
181
182 /* *INDENT-OFF* */
183-#define __DRIZZLE_DECL_ATOMIC(T) \
184- template<> struct atomic<T> \
185- : internal::atomic_impl<T,T,ATOMIC_TRAITS<T,T> > { \
186- atomic<T>() : internal::atomic_impl<T,T,ATOMIC_TRAITS<T,T> >() {} \
187- atomic<T>& operator=( T rhs ) { store_with_release(rhs); return *this; } \
188+#define __DRIZZLE_DECL_ATOMIC(T) \
189+ template<> \
190+ struct atomic<T> : internal::atomic_impl<T, ATOMIC_TRAITS<T, T> > \
191+ { \
192+ void operator=(T v) { store_with_release(v); } \
193 };
194 /* *INDENT-ON* */
195
196@@ -164,11 +152,10 @@
197 __DRIZZLE_DECL_ATOMIC(unsigned long long)
198 # else
199 # define __DRIZZLE_DECL_ATOMIC64(T) \
200- template<> struct atomic<T> \
201- : internal::atomic_impl<T,T,internal::pthread_traits<T,T> > { \
202- atomic<T>() \
203- : internal::atomic_impl<T,T,internal::pthread_traits<T,T> >() {} \
204- T operator=( T rhs ) { return store_with_release(rhs); } \
205+ template<> \
206+ struct atomic<T> : internal::atomic_impl<T, internal::pthread_traits<T, T> > \
207+ { \
208+ void operator=(T v) { store_with_release(v); } \
209 };
210 __DRIZZLE_DECL_ATOMIC64(long long)
211 __DRIZZLE_DECL_ATOMIC64(unsigned long long)
212@@ -176,4 +163,3 @@
213 /* *INDENT-ON* */
214
215 }
216-
217
218=== modified file 'unittests/pthread_atomics_test.cc'
219--- unittests/pthread_atomics_test.cc 2011-02-17 00:14:13 +0000
220+++ unittests/pthread_atomics_test.cc 2011-12-16 16:07:29 +0000
221@@ -21,44 +21,16 @@
222 #include <config.h>
223
224 #define BOOST_TEST_DYN_LINK
225+
226 #include <boost/test/unit_test.hpp>
227-
228-# if defined(__SUNPRO_CC)
229-# include <drizzled/atomic/sun_studio.h>
230-# endif
231-
232-# if !defined(__ICC) && (defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(__SUNPRO_CC))
233-# include <drizzled/atomic/gcc_traits.h>
234-# define ATOMIC_TRAITS internal::gcc_traits
235-# else /* use pthread impl */
236-# define ATOMIC_TRAITS internal::pthread_traits
237-# endif
238-
239-#include <pthread.h>
240-#include <drizzled/atomic/pthread_traits.h>
241-
242 #include <drizzled/atomics.h>
243
244 using namespace drizzled;
245
246-template<typename T>
247-struct atomic_pthread {
248-};
249-
250-# define __DRIZZLE_DECL_ATOMIC_PTHREAD(T) \
251- template<> struct atomic_pthread<T> \
252- : internal::atomic_impl<T,T, internal::pthread_traits<T,T> > { \
253- atomic_pthread<T>() \
254- : internal::atomic_impl<T,T, internal::pthread_traits<T,T> >() {} \
255- T operator=( T rhs ) { return store_with_release(rhs); } \
256- };
257-
258-__DRIZZLE_DECL_ATOMIC_PTHREAD(unsigned int)
259-
260 BOOST_AUTO_TEST_SUITE(PthreadAtomicOperations)
261 BOOST_AUTO_TEST_CASE(fetch_and_store)
262 {
263- atomic_pthread<uint32_t> u235;
264+ atomic<uint32_t> u235;
265
266 BOOST_REQUIRE_EQUAL(0, u235.fetch_and_store(1));
267
268@@ -70,7 +42,7 @@
269
270 BOOST_AUTO_TEST_CASE(fetch_and_increment)
271 {
272- atomic_pthread<uint32_t> u235;
273+ atomic<uint32_t> u235;
274
275 BOOST_REQUIRE_EQUAL(0, u235.fetch_and_increment());
276 BOOST_REQUIRE_EQUAL(1, u235);
277@@ -78,7 +50,7 @@
278
279 BOOST_AUTO_TEST_CASE(fetch_and_add)
280 {
281- atomic_pthread<uint32_t> u235;
282+ atomic<uint32_t> u235;
283
284 BOOST_REQUIRE_EQUAL(0, u235.fetch_and_add(2));
285 BOOST_REQUIRE_EQUAL(2, u235);
286@@ -86,7 +58,7 @@
287
288 BOOST_AUTO_TEST_CASE(add_and_fetch)
289 {
290- atomic_pthread<uint32_t> u235;
291+ atomic<uint32_t> u235;
292
293 BOOST_REQUIRE_EQUAL(10, u235.add_and_fetch(10));
294 BOOST_REQUIRE_EQUAL(10, u235);
295@@ -94,7 +66,7 @@
296
297 BOOST_AUTO_TEST_CASE(fetch_and_decrement)
298 {
299- atomic_pthread<uint32_t> u235;
300+ atomic<uint32_t> u235;
301
302 u235.fetch_and_store(15);
303
304@@ -104,7 +76,7 @@
305
306 BOOST_AUTO_TEST_CASE(compare_and_swap)
307 {
308- atomic_pthread<uint32_t> u235;
309+ atomic<uint32_t> u235;
310
311 u235.fetch_and_store(100);
312
313@@ -115,14 +87,14 @@
314
315 BOOST_AUTO_TEST_CASE(increment)
316 {
317- atomic_pthread<uint32_t> u235;
318+ atomic<uint32_t> u235;
319 u235.fetch_and_store(200);
320 BOOST_REQUIRE_EQUAL(201, u235.increment());
321 }
322
323 BOOST_AUTO_TEST_CASE(decrement)
324 {
325- atomic_pthread<uint32_t> u235;
326+ atomic<uint32_t> u235;
327 u235.fetch_and_store(200);
328
329 BOOST_REQUIRE_EQUAL(199, u235.decrement());