]> granicus.if.org Git - postgresql/commitdiff
Fix more DSA problems uncovered by the buildfarm.
authorRobert Haas <rhaas@postgresql.org>
Mon, 5 Dec 2016 15:38:08 +0000 (10:38 -0500)
committerRobert Haas <rhaas@postgresql.org>
Mon, 5 Dec 2016 15:38:08 +0000 (10:38 -0500)
On 32-bit systems, don't try to use 64-bit DSA pointers, because the
computation of DSA_MAX_SEGMENT_SIZE overflows Size.

Cast 1 to Size before shifting it, so that the compiler doesn't
produce a result of the wrong width.

In passing, change one use of size_t to Size.

src/backend/utils/mmgr/dsa.c
src/include/utils/dsa.h

index 0e49e7020df16fd6724be7e14cf1a00e2a6f189c..aa3ab58d38a730ba4b6a199b54d73f5386dd9ff4 100644 (file)
@@ -98,7 +98,7 @@
 #define DSA_OFFSET_BITMASK (((dsa_pointer) 1 << DSA_OFFSET_WIDTH) - 1)
 
 /* The maximum size of a DSM segment. */
-#define DSA_MAX_SEGMENT_SIZE ((size_t) 1 << DSA_OFFSET_WIDTH)
+#define DSA_MAX_SEGMENT_SIZE ((Size) 1 << DSA_OFFSET_WIDTH)
 
 /* Number of pages (see FPM_PAGE_SIZE) per regular superblock. */
 #define DSA_PAGES_PER_SUPERBLOCK               16
@@ -1919,7 +1919,7 @@ get_best_segment(dsa_area *area, Size npages)
                 * The minimum contiguous size that any segment in this bin should
                 * have.  We'll re-bin if we see segments with fewer.
                 */
-               Size            threshold = 1 << (bin - 1);
+               Size            threshold = (Size) 1 << (bin - 1);
                dsa_segment_index segment_index;
 
                /* Search this bin for a segment with enough contiguous space. */
index a6d674df577be5cac332fed629c111f44326dab8..0e2778c95d73b7eaba948d15ea731e55dd4955ab 100644 (file)
@@ -24,20 +24,25 @@ struct dsa_area;
 typedef struct dsa_area dsa_area;
 
 /*
- * If this system doesn't support atomic operations on 64 bit values then
- * we fall back to 32 bit dsa_pointer.  For testing purposes,
- * USE_SMALL_DSA_POINTER can be defined to force the use of 32 bit
- * dsa_pointer even on systems that support 64 bit atomics.
+ * If this system only uses a 32-bit value for Size, then use the 32-bit
+ * implementation of DSA.  This limits the amount of DSA that can be created
+ * to something significantly less than the entire 4GB address space because
+ * the DSA pointer must encode both a segment identifier and an offset, but
+ * that shouldn't be a significant limitation in practice.
+ *
+ * If this system doesn't support atomic operations on 64-bit values, then
+ * we fall back to 32-bit dsa_pointer for lack of other options.
+ *
+ * For testing purposes, USE_SMALL_DSA_POINTER can be defined to force the use
+ * of 32-bit dsa_pointer even on systems capable of supporting a 64-bit
+ * dsa_pointer.
  */
-#ifndef PG_HAVE_ATOMIC_U64_SUPPORT
-#define SIZEOF_DSA_POINTER 4
-#else
-#ifdef USE_SMALL_DSA_POINTER
+#if SIZEOF_SIZE_T == 4 || !defined(PG_HAVE_ATOMIC_U64_SUPPORT) || \
+       defined(USE_SMALL_DSA_POINTER)
 #define SIZEOF_DSA_POINTER 4
 #else
 #define SIZEOF_DSA_POINTER 8
 #endif
-#endif
 
 /*
  * The type of 'relative pointers' to memory allocated by a dynamic shared