You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by gc...@apache.org on 2015/10/27 19:39:47 UTC
incubator-hawq git commit: HAWQ-46. Change data type for Metadata
Versioning versions from int64 to uint64.
Repository: incubator-hawq
Updated Branches:
refs/heads/master 7fc93c378 -> dc9a5d903
HAWQ-46. Change data type for Metadata Versioning versions from int64 to uint64.
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/dc9a5d90
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/dc9a5d90
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/dc9a5d90
Branch: refs/heads/master
Commit: dc9a5d9037e6515735987b40f3488a915ff28047
Parents: 7fc93c3
Author: Nikos Armenatzoglou <ni...@gmail.com>
Authored: Wed Oct 21 15:56:44 2015 -0700
Committer: Nikos Armenatzoglou <ni...@gmail.com>
Committed: Tue Oct 27 11:37:30 2015 -0700
----------------------------------------------------------------------
src/backend/utils/cache/sharedcache.c | 2 +-
src/backend/utils/mdver/mdver_global_mdvsn.c | 4 +-
src/backend/utils/mdver/mdver_utils.c | 3 +-
src/backend/utils/misc/atomic.c | 62 +++++++-
src/backend/utils/misc/test/Makefile | 10 +-
src/backend/utils/misc/test/atomic_test.c | 156 +++++++++++++++++++
.../utils/workfile_manager/workfile_mgr_test.c | 8 +-
.../workfile_manager/workfile_queryspace.c | 6 +-
.../workfile_manager/workfile_segmentspace.c | 8 +-
src/include/utils/atomic.h | 3 +-
src/include/utils/mdver.h | 2 +-
11 files changed, 242 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/cache/sharedcache.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/cache/sharedcache.c b/src/backend/utils/cache/sharedcache.c
index b8f36e6..4e867af 100644
--- a/src/backend/utils/cache/sharedcache.c
+++ b/src/backend/utils/cache/sharedcache.c
@@ -1104,7 +1104,7 @@ void
Cache_UpdatePerfCounter64(int64 *counter, int64 delta)
{
Assert(counter + delta >= 0);
- gp_atomic_add_64(counter, delta);
+ gp_atomic_add_int64(counter, delta);
}
/*
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/mdver/mdver_global_mdvsn.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/mdver/mdver_global_mdvsn.c b/src/backend/utils/mdver/mdver_global_mdvsn.c
index a77c7c0..acae7d1 100644
--- a/src/backend/utils/mdver/mdver_global_mdvsn.c
+++ b/src/backend/utils/mdver/mdver_global_mdvsn.c
@@ -20,7 +20,7 @@
#define MDVER_GLOBAL_VER_SHMEM_NAME "MDVer Global Version Counter"
/* Pointer to the shared memory global version counter (GVC) */
-int64 *mdver_global_version_counter = NULL;
+uint64 *mdver_global_version_counter = NULL;
/* MDVer Global MDVSN is stored here, once attached to */
Cache *mdver_glob_mdvsn = NULL;
@@ -64,7 +64,7 @@ mdver_shmem_init(void)
sizeof(*mdver_global_version_counter),
&attach);
- mdver_global_version_counter = (int64 *)shmem_base;
+ mdver_global_version_counter = (uint64 *)shmem_base;
Assert(0 == *mdver_global_version_counter);
}
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/mdver/mdver_utils.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/mdver/mdver_utils.c b/src/backend/utils/mdver/mdver_utils.c
index ae7462b..56bce01 100644
--- a/src/backend/utils/mdver/mdver_utils.c
+++ b/src/backend/utils/mdver/mdver_utils.c
@@ -298,8 +298,7 @@ mdver_request_after_nuke(Oid key, uint64 *ddl_version, uint64 *dml_version)
uint64
mdver_next_global_version()
{
- /* TODO gcaragea 03/28/2014: Determine if we should use int64 or uint64 (MPP-23087) */
- return (uint64) gp_atomic_add_64(mdver_global_version_counter, 1);
+ return gp_atomic_add_uint64(mdver_global_version_counter, 1);
}
/*
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/misc/atomic.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/misc/atomic.c b/src/backend/utils/misc/atomic.c
index de5036b..42f4b12 100644
--- a/src/backend/utils/misc/atomic.c
+++ b/src/backend/utils/misc/atomic.c
@@ -176,11 +176,11 @@ int32 gp_atomic_add_32(volatile int32 *ptr, int32 inc)
}
/*
- * gp_atomic_add_64
+ * gp_atomic_add_int64
* Atomic increment a 64-bit address, and return the incremented value
* inc can be a positive or negative quantity
*/
-int64 gp_atomic_add_64(int64 *ptr, int64 inc)
+int64 gp_atomic_add_int64(int64 *ptr, int64 inc)
{
Assert(NULL != ptr);
@@ -231,6 +231,64 @@ int64 gp_atomic_add_64(int64 *ptr, int64 inc)
/*
+ * gp_atomic_add_uint64
+ * Atomic increment an unsigned 64-bit address, and return the incremented value
+ * inc can be a positive or negative quantity
+ */
+
+uint64 gp_atomic_add_uint64(uint64 *ptr, int64 inc)
+{
+ Assert(inc >= 0);
+ Assert(NULL != ptr);
+
+ volatile uint64 newValue = 0;
+ uint64 uInc = (uint64) inc;
+
+#if defined(__x86_64__)
+ uint64 oldValue = __sync_fetch_and_add(ptr, uInc);
+ newValue = oldValue + uInc;
+#elif defined(__i386)
+
+ volatile uint64* newValuePtr = &newValue;
+ int addValueLow = (int) uInc;
+ int addValueHigh = (int) (uInc>>32);
+
+ __asm__ __volatile__ (
+ "PUSHL %%ebx; \n\t" /* Save ebx, it's a special register we can't clobber */
+ "MOVL %0, %%edi; \n\t" /* Load ptr */
+ "MOVL (%%edi), %%eax; \n\t" /* Load first word from *ptr */
+ "MOVL 0x4(%%edi), %%edx; \n\t" /* Load second word from *ptr + 4 */
+ "tryAgain_add_uint64: \n\t"
+ "MOVL %1, %%ebx; \n\t" /* Load addValueLow */
+ "MOVL %2, %%ecx; \n\t" /* Load addValueHigh */
+ "ADDL %%eax, %%ebx; \n\t" /* Add first word */
+ "ADCL %%edx, %%ecx; \n\t" /* Add second word */
+ "lock cmpxchg8b (%%edi); \n\t" /* Compare and exchange 8 bytes atomically */
+ "jnz tryAgain_add_uint64; \n\t" /* If ptr has changed, try again with new value */
+
+ "MOVL %3, %%edi; \n\t" /* Put result in *newValuePtr */
+ "MOVL %%ebx, (%%edi); \n\t" /* first word */
+ "MOVL %%ecx, 0x4(%%edi); \n\t" /* second word */
+ "POPL %%ebx; \n\t" /* Restore ebx */
+
+ : /* no output registers */
+ : "m" (ptr), "m" (addValueLow), "m" (addValueHigh), "m" (newValuePtr) /* input registers */
+ : "memory", "%edi", "%edx", "%ecx", "%eax" /* clobber list */
+ );
+
+#elif defined(__sparc__)
+#error unsupported platform sparc: requires atomic_add_64 operation
+ /* For sparc we can probably use __sync_fetch_and_add as well */
+#else
+#error unsupported/unknown platform: requires atomic_add_64 operation
+#endif
+
+ return newValue;
+}
+
+
+
+/*
* atomic_incmod_value
*
* Atomically adds 1 to a value, modulo 'mod'
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/misc/test/Makefile
----------------------------------------------------------------------
diff --git a/src/backend/utils/misc/test/Makefile b/src/backend/utils/misc/test/Makefile
index b93f4ed..dcd2dbe 100644
--- a/src/backend/utils/misc/test/Makefile
+++ b/src/backend/utils/misc/test/Makefile
@@ -1,10 +1,10 @@
top_builddir=../../../../..
subdir=src/backend/utils/misc
-TARGETS=guc
+TARGETS=guc atomic
# Objects from backend, which don't need to be mocked but need to be linked.
-guc_REAL_OBJS=\
+common_REAL_OBJS=\
$(top_srcdir)/src/backend/access/hash/hashfunc.o \
$(top_srcdir)/src/backend/access/heap/tuptoaster.o \
$(top_srcdir)/src/backend/bootstrap/bootparse.o \
@@ -35,4 +35,10 @@ guc_REAL_OBJS=\
$(top_srcdir)/src/timezone/localtime.o \
$(top_srcdir)/src/timezone/pgtz.o
+guc_REAL_OBJS=$(common_REAL_OBJS)
+
+atomic_REAL_OBJS=$(common_REAL_OBJS) \
+ $(top_srcdir)/src/backend/utils/misc/guc.o
+
+
include ../../../../Makefile.mock
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/misc/test/atomic_test.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/misc/test/atomic_test.c b/src/backend/utils/misc/test/atomic_test.c
new file mode 100644
index 0000000..d77c050
--- /dev/null
+++ b/src/backend/utils/misc/test/atomic_test.c
@@ -0,0 +1,156 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include "cmockery.h"
+
+#include "c.h"
+#include "postgres.h"
+#include "../atomic.c"
+
+#define INT64_MAX 9223372036854775807
+#define INT64_MIN -9223372036854775807
+#define UINT64_MAX 18446744073709551615
+#define UINT64_MIN 0
+
+
+#define EXPECT_EXCEPTION() \
+ expect_any(ExceptionalCondition,conditionName); \
+ expect_any(ExceptionalCondition,errorType); \
+ expect_any(ExceptionalCondition,fileName); \
+ expect_any(ExceptionalCondition,lineNumber); \
+ will_be_called_with_sideeffect(ExceptionalCondition, &_ExceptionalCondition, NULL);\
+
+
+/*
+ * This method will emulate the real ExceptionalCondition
+ * function by re-throwing the exception, essentially falling
+ * back to the next available PG_CATCH();
+ */
+void
+_ExceptionalCondition()
+{
+ PG_RE_THROW();
+}
+
+
+/*
+ * Test gp_atomic_add_int64
+ */
+void
+test__gp_atomic_add_int64(void **state)
+{
+
+ /* Running sub-test: gp_atomic_add_int64 small addition */
+ int64 base = 25;
+ int64 inc = 3;
+ int64 result = 0;
+ int64 expected_result = base + inc;
+ result = gp_atomic_add_int64(&base, inc);
+ /* Examine if the value of base has been increased by the value of inc */
+ assert_true(result == expected_result && base == expected_result);
+ assert_true(result <= INT64_MAX && result >= INT64_MIN && base <= INT64_MAX && base >= INT64_MIN);
+
+ /* Running sub-test: gp_atomic_add_int64 small subtraction */
+ inc = -4;
+ result = 0;
+ expected_result = base + inc;
+ result = gp_atomic_add_int64(&base, inc);
+ assert_true(result == expected_result && base == expected_result);
+ assert_true(result <= INT64_MAX && result >= INT64_MIN && base <= INT64_MAX && base >= INT64_MIN);
+
+ /* Running sub-test: gp_atomic_add_int64 huge addition */
+ base = 37421634719307;
+ inc = 738246483234;
+ result = 0;
+ expected_result = base + inc;
+ result = gp_atomic_add_int64(&base, inc);
+ assert_true(result == expected_result && base == expected_result);
+ assert_true(result <= INT64_MAX && result >= INT64_MIN && base <= INT64_MAX && base >= INT64_MIN);
+
+ /* Ensure that an integer overflow occurs.*/
+ inc = INT64_MAX;
+ result = gp_atomic_add_int64(&base, inc);
+ assert_true(base < 0);
+ assert_true(result <= INT64_MAX && result >= INT64_MIN && base <= INT64_MAX && base >= INT64_MIN);
+
+ /* Running sub-test: gp_atomic_add_int64 huge subtraction */
+ base = 0;
+ inc = -32738246483234;
+ result = 0;
+ expected_result = base + inc;
+ result = gp_atomic_add_int64(&base, inc);
+ assert_true(result == expected_result && base == expected_result);
+ assert_true(result <= INT64_MAX && result >= INT64_MIN && base <= INT64_MAX && base >= INT64_MIN);
+
+ /* Ensure that an integer overflow occurs.*/
+ inc = INT64_MIN;
+ result = gp_atomic_add_int64(&base, inc);
+ assert_true(base > 0);
+ assert_true(result <= INT64_MAX && result >= INT64_MIN && base <= INT64_MAX && base >= INT64_MIN);
+
+}
+
+
+/*
+ * Test gp_atomic_add_uint64
+ */
+void
+test__gp_atomic_add_uint64(void **state)
+{
+
+ /* Running sub-test: gp_atomic_add_uint64 small addition */
+ uint64 base = 25;
+ int64 inc = 3;
+ uint64 result = 0;
+ uint64 expected_result = base + inc;
+ result = gp_atomic_add_uint64(&base, inc);
+ /* Examine if the value of base has been increased by the value of inc */
+ assert_true(result == expected_result && base == expected_result);
+ assert_true(result <= UINT64_MAX && result >= UINT64_MIN && base <= UINT64_MAX && base >= UINT64_MIN);
+
+ /* Running sub-test: gp_atomic_add_uint64 huge addition */
+ base = INT64_MAX;
+ inc = 738246483234;
+ result = 0;
+ expected_result = base + inc;
+ result = gp_atomic_add_uint64(&base, inc);
+ assert_true(result == expected_result && base == expected_result);
+ assert_true(result <= UINT64_MAX && result >= UINT64_MIN && base <= UINT64_MAX && base >= UINT64_MIN);
+
+ /* Ensure that an integer overflow occurs.*/
+ base = UINT64_MAX;
+ inc = 1;
+ result = gp_atomic_add_uint64(&base, inc);
+ assert_true(base == 0);
+
+ /* Running sub-test: gp_atomic_add_uint64 negative inc */
+#ifdef USE_ASSERT_CHECKING
+ EXPECT_EXCEPTION();
+ PG_TRY();
+ {
+ /* inc should be either zero or a positive integer. So, negative inc should fail. */
+ inc = -4;
+ result = gp_atomic_add_uint64(&base, inc);
+ assert_true(false);
+ }
+ PG_CATCH();
+ {
+ }
+ PG_END_TRY();
+#endif
+
+}
+
+
+
+int
+main(int argc, char* argv[]) {
+
+ cmockery_parse_arguments(argc, argv);
+ const UnitTest tests[] = {
+ unit_test(test__gp_atomic_add_int64),
+ unit_test(test__gp_atomic_add_uint64)
+ };
+
+ return run_tests(tests);
+}
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/workfile_manager/workfile_mgr_test.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/workfile_manager/workfile_mgr_test.c b/src/backend/utils/workfile_manager/workfile_mgr_test.c
index 57814a9..0f3e602 100644
--- a/src/backend/utils/workfile_manager/workfile_mgr_test.c
+++ b/src/backend/utils/workfile_manager/workfile_mgr_test.c
@@ -1797,7 +1797,7 @@ atomic_test(void)
int64 result = 0;
int64 expected_result = base + inc;
elog(DEBUG1, "Before: base=%lld, inc=%lld, result=%lld", (long long int) base, (long long int) inc, (long long int) result);
- result = gp_atomic_add_64(&base, inc);
+ result = gp_atomic_add_int64(&base, inc);
elog(DEBUG1, "After: base=%lld, inc=%lld, result=%lld", (long long int) base, (long long int) inc, (long long int) result);
unit_test_result(result == expected_result && base == expected_result);
@@ -1807,7 +1807,7 @@ atomic_test(void)
result = 0;
expected_result = base + inc;
elog(DEBUG1, "Before: base=%lld, inc=%lld, result=%lld", (long long int) base, (long long int) inc, (long long int) result);
- result = gp_atomic_add_64(&base, inc);
+ result = gp_atomic_add_int64(&base, inc);
elog(DEBUG1, "After: base=%lld, inc=%lld, result=%lld", (long long int) base, (long long int) inc, (long long int) result);
unit_test_result(result == expected_result && base == expected_result);
@@ -1817,7 +1817,7 @@ atomic_test(void)
result = 0;
expected_result = base + inc;
elog(DEBUG1, "Before: base=%lld, inc=%lld, result=%lld", (long long int) base, (long long int) inc, (long long int) result);
- result = gp_atomic_add_64(&base, inc);
+ result = gp_atomic_add_int64(&base, inc);
elog(DEBUG1, "After: base=%lld, inc=%lld, result=%lld", (long long int) base, (long long int) inc, (long long int) result);
unit_test_result(result == expected_result && base == expected_result);
@@ -1827,7 +1827,7 @@ atomic_test(void)
result = 0;
expected_result = base + inc;
elog(DEBUG1, "Before: base=%lld, inc=%lld, result=%lld", (long long int) base, (long long int) inc, (long long int) result);
- result = gp_atomic_add_64(&base, inc);
+ result = gp_atomic_add_int64(&base, inc);
elog(DEBUG1, "After: base=%lld, inc=%lld, result=%lld", (long long int) base, (long long int) inc, (long long int) result);
unit_test_result(result == expected_result && base == expected_result);
}
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/workfile_manager/workfile_queryspace.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/workfile_manager/workfile_queryspace.c b/src/backend/utils/workfile_manager/workfile_queryspace.c
index 78f61e3..fac91a9 100644
--- a/src/backend/utils/workfile_manager/workfile_queryspace.c
+++ b/src/backend/utils/workfile_manager/workfile_queryspace.c
@@ -133,7 +133,7 @@ WorkfileQueryspace_Reserve(int64 bytes_to_reserve)
return true;
}
- int64 total = gp_atomic_add_64(&queryEntry->queryDiskspace, bytes_to_reserve);
+ int64 total = gp_atomic_add_int64(&queryEntry->queryDiskspace, bytes_to_reserve);
Assert(total >= (int64) 0);
if (gp_workfile_limit_per_query == 0)
@@ -151,7 +151,7 @@ WorkfileQueryspace_Reserve(int64 bytes_to_reserve)
workfileError = WORKFILE_ERROR_LIMIT_PER_QUERY;
/* Revert the reserved space */
- gp_atomic_add_64(&queryEntry->queryDiskspace, - bytes_to_reserve);
+ gp_atomic_add_int64(&queryEntry->queryDiskspace, - bytes_to_reserve);
/* Set diskfull to true to stop any further attempts to write more data */
WorkfileDiskspace_SetFull(true /* isFull */);
}
@@ -187,7 +187,7 @@ WorkfileQueryspace_Commit(int64 commit_bytes, int64 reserved_bytes)
#if USE_ASSERT_CHECKING
int64 total =
#endif
- gp_atomic_add_64(&queryEntry->queryDiskspace, (commit_bytes - reserved_bytes));
+ gp_atomic_add_int64(&queryEntry->queryDiskspace, (commit_bytes - reserved_bytes));
Assert(total >= (int64) 0);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/backend/utils/workfile_manager/workfile_segmentspace.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/workfile_manager/workfile_segmentspace.c b/src/backend/utils/workfile_manager/workfile_segmentspace.c
index 000fc68..068ef2d 100644
--- a/src/backend/utils/workfile_manager/workfile_segmentspace.c
+++ b/src/backend/utils/workfile_manager/workfile_segmentspace.c
@@ -58,7 +58,7 @@ WorkfileSegspace_Reserve(int64 bytes_to_reserve)
{
Assert(NULL != used_segspace);
- int64 total = gp_atomic_add_64(used_segspace, bytes_to_reserve);
+ int64 total = gp_atomic_add_int64(used_segspace, bytes_to_reserve);
Assert(total >= (int64) 0);
if (gp_workfile_limit_per_segment == 0)
@@ -81,7 +81,7 @@ WorkfileSegspace_Reserve(int64 bytes_to_reserve)
{
/* Revert the reserved space */
- (void) gp_atomic_add_64(used_segspace, - bytes_to_reserve);
+ (void) gp_atomic_add_int64(used_segspace, - bytes_to_reserve);
CHECK_FOR_INTERRUPTS();
@@ -106,7 +106,7 @@ WorkfileSegspace_Reserve(int64 bytes_to_reserve)
}
/* Try to reserve again */
- total = gp_atomic_add_64(used_segspace, bytes_to_reserve);
+ total = gp_atomic_add_int64(used_segspace, bytes_to_reserve);
Assert(total >= (int64) 0);
if (total <= max_allowed_diskspace)
@@ -150,7 +150,7 @@ WorkfileSegspace_Commit(int64 commit_bytes, int64 reserved_bytes)
#if USE_ASSERT_CHECKING
int64 total =
#endif
- gp_atomic_add_64(used_segspace, (commit_bytes - reserved_bytes));
+ gp_atomic_add_int64(used_segspace, (commit_bytes - reserved_bytes));
Assert(total >= (int64) 0);
}
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/include/utils/atomic.h
----------------------------------------------------------------------
diff --git a/src/include/utils/atomic.h b/src/include/utils/atomic.h
index 5ed35f6..0ec292f 100644
--- a/src/include/utils/atomic.h
+++ b/src/include/utils/atomic.h
@@ -11,7 +11,8 @@ extern int32 compare_and_swap_ulong(unsigned long *dest,
unsigned long newval);
extern int32 gp_lock_test_and_set(volatile int32 *ptr, int32 val);
extern int32 gp_atomic_add_32(volatile int32 *ptr, int32 inc);
-extern int64 gp_atomic_add_64(int64 *ptr, int64 inc);
+extern int64 gp_atomic_add_int64(int64 *ptr, int64 inc);
+extern uint64 gp_atomic_add_uint64(uint64 *ptr, int64 inc);
extern int32 gp_atomic_incmod_32(volatile int32 *loc, int32 mod);
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/dc9a5d90/src/include/utils/mdver.h
----------------------------------------------------------------------
diff --git a/src/include/utils/mdver.h b/src/include/utils/mdver.h
index b764d19..3d3f794 100644
--- a/src/include/utils/mdver.h
+++ b/src/include/utils/mdver.h
@@ -43,7 +43,7 @@ typedef struct mdver_local_mdvsn
} mdver_local_mdvsn;
/* Pointer to the shared memory global version counter (GVC) */
-extern int64 *mdver_global_version_counter;
+extern uint64 *mdver_global_version_counter;
/* MD Versioning shared memory initialization */
void mdver_shmem_init(void);