Merge lp:~percona-dev/percona-server/atomic-fixes-55 into lp:percona-server/5.5

Proposed by Laurynas Biveinis
Status: Superseded
Proposed branch: lp:~percona-dev/percona-server/atomic-fixes-55
Merge into: lp:percona-server/5.5
Prerequisite: lp:~percona-dev/percona-server/release-5.5.12-20.3
Diff against target: 166 lines (+34/-91)
1 file modified
response_time_distribution.patch (+34/-91)
To merge this branch: bzr merge lp:~percona-dev/percona-server/atomic-fixes-55
Reviewer Review Type Date Requested Status
Stewart Smith (community) Needs Fixing
Valentine Gostev qa Pending
Review via email: mp+63955@code.launchpad.net

This proposal has been superseded by a proposal from 2011-06-21.

Description of the change

Fix LP bug 737947: unportable atomic constructs break build on various platforms.

The fix is to remove query_response_time.cc-specific atomic code, and use MySQL primitives in my_atomic.h. This way the portability is not limited in any way by the patch as well as minimizing future maintenance burden.

Testing results:
x86_64 Linux: OK,
FreeBSD 8.2 i386: OK,
Solaris 11 x86_64: build fails due to unrelated error, the Solaris atomics are correctly detected and compiled..

Please ignore the prerequisite branch, I will merge before it is merged, I'm leaving it in to show only the relevant diffs.

To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Please ignore the apparent conflict in series.

Revision history for this message
Stewart Smith (stewart) wrote :

Please remerge with trunk, we have 5.5.13 in there now.

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'response_time_distribution.patch'
2--- response_time_distribution.patch 2011-06-16 01:19:11 +0000
3+++ response_time_distribution.patch 2011-06-21 02:38:08 +0000
4@@ -178,12 +178,8 @@
5 diff -ruN /dev/null b/sql/query_response_time.cc
6 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
7 +++ b/sql/query_response_time.cc 2011-04-10 00:27:11.000000000 +0400
8-@@ -0,0 +1,367 @@
9+@@ -0,0 +1,310 @@
10 +#include "mysql_version.h"
11-+#ifdef __FreeBSD__
12-+#include <sys/types.h>
13-+#include <machine/atomic.h>
14-+#endif // __FreeBSD__
15 +#include "my_global.h"
16 +#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
17 +#include "mysql_com.h"
18@@ -337,98 +333,39 @@
19 + }
20 + buffer[result_length]= 0;
21 +}
22-+#ifdef __x86_64__
23-+typedef uint64 TimeCounter;
24-+void add_time_atomic(TimeCounter* counter, uint64 time)
25-+{
26-+ __sync_fetch_and_add(counter,time);
27-+}
28-+#endif // __x86_64__
29-+#ifdef __i386__
30-+inline uint32 get_high(uint64 value)
31-+{
32-+ return ((value >> 32) << 32);
33-+}
34-+inline uint32 get_low(uint64 value)
35-+{
36-+ return ((value << 32) >> 32);
37-+}
38-+#ifdef __FreeBSD__
39-+inline bool compare_and_swap(volatile uint32 *target, uint32 old, uint32 new_value)
40-+{
41-+ return atomic_cmpset_32(target,old,new_value);
42-+}
43-+#else // __FreeBSD__
44-+inline bool compare_and_swap(volatile uint32* target, uint32 old, uint32 new_value)
45-+{
46-+ return __sync_bool_compare_and_swap(target,old,new_value);
47-+}
48-+#endif // __FreeBSD__
49-+class TimeCounter
50-+{
51-+public:
52-+ TimeCounter& operator=(uint64 time)
53-+ {
54-+ this->m_high= get_high(time);
55-+ this->m_low= get_low(time);
56-+ return *this;
57-+ }
58-+ operator uint64() const
59-+ {
60-+ return ((static_cast<uint64>(m_high) << 32) + static_cast<uint64>(m_low));
61-+ }
62-+ void add(uint64 time)
63-+ {
64-+ uint32 time_high = get_high(time);
65-+ uint32 time_low = get_low(time);
66-+ uint64 time_low64= time_low;
67-+ while(true)
68-+ {
69-+ uint32 old_low= this->m_low;
70-+ uint64 old_low64= old_low;
71-+
72-+ uint64 new_low64= old_low64 + time_low64;
73-+ uint32 new_low= (get_low(new_low64));
74-+ bool add_high= (get_high(new_low64) != 0);
75-+
76-+ if(!compare_and_swap(&m_low,old_low,new_low))
77-+ {
78-+ continue;
79-+ }
80-+ if(add_high)
81-+ {
82-+ ++time_high;
83-+ }
84-+ if(time_high > 0)
85-+ {
86-+ __sync_fetch_and_add(&m_high,time_high);
87-+ }
88-+ break;
89-+ }
90-+ }
91-+private:
92-+ uint32 m_low;
93-+ uint32 m_high;
94-+};
95-+void add_time_atomic(TimeCounter* counter, uint64 time)
96-+{
97-+ counter->add(time);
98-+}
99-+#endif // __i386__
100 +
101 +class time_collector
102 +{
103 +public:
104 + time_collector(utility& u) : m_utility(&u)
105 + {
106-+ }
107-+ uint32 count(uint index) const { return m_count[index]; }
108-+ uint64 total(uint index) const { return m_total[index]; }
109++ my_atomic_rwlock_init(&time_collector_lock);
110++ }
111++ ~time_collector()
112++ {
113++ my_atomic_rwlock_destroy(&time_collector_lock);
114++ }
115++ uint32 count(uint index) const
116++ {
117++ my_atomic_rwlock_rdlock(&time_collector_lock);
118++ uint32 result= my_atomic_load32((volatile int32*)&m_count[index]);
119++ my_atomic_rwlock_rdunlock(&time_collector_lock);
120++ return result;
121++ }
122++ uint64 total(uint index) const
123++ {
124++ my_atomic_rwlock_rdlock(&time_collector_lock);
125++ uint64 result= my_atomic_load64((volatile int64*)&m_total[index]);
126++ my_atomic_rwlock_rdunlock(&time_collector_lock);
127++ return result;
128++ }
129 +public:
130 + void flush()
131 + {
132-+ memset(&m_count,0,sizeof(m_count));
133++ my_atomic_rwlock_wrlock(&time_collector_lock);
134++ memset((void*)&m_count,0,sizeof(m_count));
135 + memset((void*)&m_total,0,sizeof(m_total));
136++ my_atomic_rwlock_wrunlock(&time_collector_lock);
137 + }
138 + void collect(uint64 time)
139 + {
140@@ -437,16 +374,22 @@
141 + {
142 + if(m_utility->bound(i) > time)
143 + {
144-+ __sync_fetch_and_add(&(m_count[i]),(uint32)1);
145-+ add_time_atomic(&(m_total[i]),time);
146++ my_atomic_rwlock_wrlock(&time_collector_lock);
147++ my_atomic_add32((volatile int32*)(&m_count[i]), 1);
148++ my_atomic_add64((volatile int64*)(&m_total[i]), time);
149++ my_atomic_rwlock_wrunlock(&time_collector_lock);
150 + break;
151 + }
152 + }
153 + }
154 +private:
155 + utility* m_utility;
156-+ uint32 m_count[OVERALL_POWER_COUNT + 1];
157-+ TimeCounter m_total[OVERALL_POWER_COUNT + 1];
158++ /* The lock for atomic operations on m_count and m_total. Only actually
159++ used on architectures that do not have atomic implementation of atomic
160++ operations. */
161++ my_atomic_rwlock_t time_collector_lock;
162++ volatile uint32 m_count[OVERALL_POWER_COUNT + 1];
163++ volatile uint64 m_total[OVERALL_POWER_COUNT + 1];
164 +};
165 +
166 +class collector

Subscribers

People subscribed via source and target branches