Fix more DSA problems uncovered by the buildfarm.

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.
This commit is contained in:
Robert Haas 2016-12-05 10:38:08 -05:00
parent 670b3bc8f5
commit 88f626f868
2 changed files with 16 additions and 11 deletions

View File

@ -98,7 +98,7 @@
#define DSA_OFFSET_BITMASK (((dsa_pointer) 1 << DSA_OFFSET_WIDTH) - 1) #define DSA_OFFSET_BITMASK (((dsa_pointer) 1 << DSA_OFFSET_WIDTH) - 1)
/* The maximum size of a DSM segment. */ /* 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. */ /* Number of pages (see FPM_PAGE_SIZE) per regular superblock. */
#define DSA_PAGES_PER_SUPERBLOCK 16 #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 * The minimum contiguous size that any segment in this bin should
* have. We'll re-bin if we see segments with fewer. * 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; dsa_segment_index segment_index;
/* Search this bin for a segment with enough contiguous space. */ /* Search this bin for a segment with enough contiguous space. */

View File

@ -24,20 +24,25 @@ struct dsa_area;
typedef struct dsa_area dsa_area; typedef struct dsa_area dsa_area;
/* /*
* If this system doesn't support atomic operations on 64 bit values then * If this system only uses a 32-bit value for Size, then use the 32-bit
* we fall back to 32 bit dsa_pointer. For testing purposes, * implementation of DSA. This limits the amount of DSA that can be created
* USE_SMALL_DSA_POINTER can be defined to force the use of 32 bit * to something significantly less than the entire 4GB address space because
* dsa_pointer even on systems that support 64 bit atomics. * 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 #if SIZEOF_SIZE_T == 4 || !defined(PG_HAVE_ATOMIC_U64_SUPPORT) || \
#define SIZEOF_DSA_POINTER 4 defined(USE_SMALL_DSA_POINTER)
#else
#ifdef USE_SMALL_DSA_POINTER
#define SIZEOF_DSA_POINTER 4 #define SIZEOF_DSA_POINTER 4
#else #else
#define SIZEOF_DSA_POINTER 8 #define SIZEOF_DSA_POINTER 8
#endif #endif
#endif
/* /*
* The type of 'relative pointers' to memory allocated by a dynamic shared * The type of 'relative pointers' to memory allocated by a dynamic shared