Proposal: More portable way to support 64bit platforms - Mailing list pgsql-hackers
From | Tsutomu Yamada |
---|---|
Subject | Proposal: More portable way to support 64bit platforms |
Date | |
Msg-id | 62100.1246007244@srapc2360.sra.co.jp Whole thread Raw |
Responses |
Re: Proposal: More portable way to support 64bit platforms
Re: Proposal: More portable way to support 64bit platforms |
List | pgsql-hackers |
Proposal: More portable way to support 64bit platforms Short description: Current PostgreSQL implementation has some portability issues to support 64bit platforms: pointer calculations using long is not portable, for example on Windows x64 platform. We propose to use intptr_t instead of long, which appears in in C99. Details: intptr_t is defined in <stdint.h>. configure script already has HAVE_STDINT_H but never uses it. This needs to be enabled. Please note that Windows/VC++ defines intptr_t in <crtdefs.h>. Included is a conceptual patch to use intptr_t. Comments are welcome. Some notes for the patches: access/common/heaptuple.c: Casting using (long) is removed. It is no more necessary if we introduce intptr_t. include/c.h: Many Alignment macros which use "long" are rewritten to use intrptr_t. The patches is against PostgreSQL 8.4beta2. Regression test passed. Windows x64 is ok even with shared_buffers = 3000MB. Tested platforms are as follows: Windows Server 2008 SP1 x64 + Visual Studio 2005 RHEL 4 x86_64 + gcc 3.4.6 FreeBSD 7.1 i386 + gcc 4.2.1 TODO: Some problems may occur on older platforms, which do not have stdint.h. In this case we need to add something like below to include/port/*.h. /* LP64, IPL64, ILP32, LP32 */ typedef long intptr_t; typedef unsigned long uintptr_t; /* LLP64 */ typedef long long intptr_t; typedef unsigned long long uintptr_t; Thanks, -- Tsutomu Yamada // tsutomu@sraoss.co.jp SRA OSS, Inc. Japan diff -cwbr postgresql-8.4beta2-orig/src/backend/access/common/heaptuple.c postgresql-8.4beta2-winx64/src/backend/access/common/heaptuple.c *** postgresql-8.4beta2-orig/src/backend/access/common/heaptuple.c 2009-03-30 13:08:43.000000000 +0900 --- postgresql-8.4beta2-winx64/src/backend/access/common/heaptuple.c 2009-06-19 16:26:01.000000000 +0900 *************** *** 192,198 **** if (att[i]->attbyval) { /* pass-by-value */ ! data = (char *) att_align_nominal((long) data, att[i]->attalign); store_att_byval(data, values[i], att[i]->attlen); data_length = att[i]->attlen; } --- 192,198 ---- if (att[i]->attbyval) { /* pass-by-value */ ! data = (char *) att_align_nominal(data, att[i]->attalign); store_att_byval(data, values[i], att[i]->attlen); data_length = att[i]->attlen; } *************** *** 226,232 **** else { /* full 4-byte header varlena */ ! data = (char *) att_align_nominal((long) data, att[i]->attalign); data_length = VARSIZE(val); memcpy(data, val, data_length); --- 226,232 ---- else { /* full 4-byte header varlena */ ! data = (char *) att_align_nominal(data, att[i]->attalign); data_length = VARSIZE(val); memcpy(data, val, data_length); *************** *** 243,249 **** else { /* fixed-length pass-by-reference */ ! data = (char *) att_align_nominal((long) data, att[i]->attalign); Assert(att[i]->attlen > 0); data_length = att[i]->attlen; memcpy(data, DatumGetPointer(values[i]), data_length); --- 243,249 ---- else { /* fixed-length pass-by-reference */ ! data = (char *) att_align_nominal(data, att[i]->attalign); Assert(att[i]->attlen > 0); data_length = att[i]->attlen; memcpy(data, DatumGetPointer(values[i]), data_length); diff -cwbr postgresql-8.4beta2-orig/src/backend/access/hash/hashfunc.c postgresql-8.4beta2-winx64/src/backend/access/hash/hashfunc.c *** postgresql-8.4beta2-orig/src/backend/access/hash/hashfunc.c 2009-02-10 06:18:28.000000000 +0900 --- postgresql-8.4beta2-winx64/src/backend/access/hash/hashfunc.c 2009-06-18 22:37:46.000000000 +0900 *************** *** 319,325 **** a = b = c = 0x9e3779b9 + len + 3923095; /* If the source pointer is word-aligned, we use word-wide fetches */ ! if (((long) k & UINT32_ALIGN_MASK) == 0) { /* Code path for aligned source data */ register const uint32 *ka = (const uint32 *) k; --- 319,325 ---- a = b = c = 0x9e3779b9 + len + 3923095; /* If the source pointer is word-aligned, we use word-wide fetches */ ! if (((intptr_t) k & UINT32_ALIGN_MASK) == 0) { /* Code path for aligned source data */ register const uint32 *ka = (const uint32 *) k; diff -cwbr postgresql-8.4beta2-orig/src/include/access/tupmacs.h postgresql-8.4beta2-winx64/src/include/access/tupmacs.h *** postgresql-8.4beta2-orig/src/include/access/tupmacs.h 2009-01-02 02:23:56.000000000 +0900 --- postgresql-8.4beta2-winx64/src/include/access/tupmacs.h 2009-06-19 16:20:02.000000000 +0900 *************** *** 142,148 **** #define att_align_nominal(cur_offset, attalign) \ ( \ ((attalign) == 'i') ? INTALIGN(cur_offset) : \ ! (((attalign) == 'c') ? (long) (cur_offset) : \ (((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \ ( \ AssertMacro((attalign) == 's'), \ --- 142,148 ---- #define att_align_nominal(cur_offset, attalign) \ ( \ ((attalign) == 'i') ? INTALIGN(cur_offset) : \ ! (((attalign) == 'c') ? (intptr_t) (cur_offset) : \ (((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \ ( \ AssertMacro((attalign) == 's'), \ diff -cwbr postgresql-8.4beta2-orig/src/include/c.h postgresql-8.4beta2-winx64/src/include/c.h *** postgresql-8.4beta2-orig/src/include/c.h 2009-03-27 07:26:07.000000000 +0900 --- postgresql-8.4beta2-winx64/src/include/c.h 2009-06-19 15:43:35.000000000 +0900 *************** *** 82,87 **** --- 82,91 ---- #include <SupportDefs.h> #endif + #ifdef HAVE_STDINT_H + #include <stdint.h> + #endif + #if defined(WIN32) || defined(__CYGWIN__) /* We have to redefine some system functions after they are included above. */ #include "pg_config_os.h" *************** *** 492,498 **** * True iff pointer is properly aligned to point to the given type. */ #define PointerIsAligned(pointer, type) \ ! (((long)(pointer) % (sizeof (type))) == 0) #define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) --- 496,502 ---- * True iff pointer is properly aligned to point to the given type. */ #define PointerIsAligned(pointer, type) \ ! (((intptr_t)(pointer) % (sizeof (type))) == 0) #define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) *************** *** 538,544 **** */ #define TYPEALIGN(ALIGNVAL,LEN) \ ! (((long) (LEN) + ((ALIGNVAL) - 1)) & ~((long) ((ALIGNVAL) - 1))) #define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN)) #define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN)) --- 542,548 ---- */ #define TYPEALIGN(ALIGNVAL,LEN) \ ! (((intptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((intptr_t) ((ALIGNVAL) - 1))) #define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN)) #define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN)) *************** *** 549,555 **** #define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN)) #define TYPEALIGN_DOWN(ALIGNVAL,LEN) \ ! (((long) (LEN)) & ~((long) ((ALIGNVAL) - 1))) #define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN)) #define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN)) --- 553,559 ---- #define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN)) #define TYPEALIGN_DOWN(ALIGNVAL,LEN) \ ! (((intptr_t) (LEN)) & ~((intptr_t) ((ALIGNVAL) - 1))) #define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN)) #define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN)) *************** *** 630,636 **** int _val = (val); \ Size _len = (len); \ \ ! if ((((long) _vstart) & LONG_ALIGN_MASK) == 0 && \ (_len & LONG_ALIGN_MASK) == 0 && \ _val == 0 && \ _len <= MEMSET_LOOP_LIMIT && \ --- 634,640 ---- int _val = (val); \ Size _len = (len); \ \ ! if ((((intptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \ (_len & LONG_ALIGN_MASK) == 0 && \ _val == 0 && \ _len <= MEMSET_LOOP_LIMIT && \ diff -cwbr postgresql-8.4beta2-orig/src/include/pg_config.h.win32 postgresql-8.4beta2-winx64/src/include/pg_config.h.win32 *** postgresql-8.4beta2-orig/src/include/pg_config.h.win32 2009-05-15 11:18:27.000000000 +0900 --- postgresql-8.4beta2-winx64/src/include/pg_config.h.win32 2009-06-18 19:38:25.000000000 +0900 *************** *** 350,356 **** /* #undef HAVE_SRANDOM */ /* Define to 1 if you have the <stdint.h> header file. */ ! #define HAVE_STDINT_H 1 /* Define to 1 if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 --- 350,356 ---- /* #undef HAVE_SRANDOM */ /* Define to 1 if you have the <stdint.h> header file. */ ! /* #undef HAVE_STDINT_H */ /* Define to 1 if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 diff -cwbr postgresql-8.4beta2-orig/src/interfaces/ecpg/ecpglib/data.c postgresql-8.4beta2-winx64/src/interfaces/ecpg/ecpglib/data.c *** postgresql-8.4beta2-orig/src/interfaces/ecpg/ecpglib/data.c 2009-01-15 20:52:55.000000000 +0900 --- postgresql-8.4beta2-winx64/src/interfaces/ecpg/ecpglib/data.c 2009-06-18 19:29:20.000000000 +0900 *************** *** 153,163 **** if (pval) { if (varcharsize == 0 || varcharsize * offset >= size) ! memcpy((char *) ((long) var + offset * act_tuple), pval, size); else { ! memcpy((char *) ((long) var + offset * act_tuple), pval, varcharsize * offset); if (varcharsize * offset < size) --- 153,163 ---- if (pval) { if (varcharsize == 0 || varcharsize * offset >= size) ! memcpy((char *) ((intptr_t) var + offset * act_tuple), pval, size); else { ! memcpy((char *) ((intptr_t) var + offset * act_tuple), pval, varcharsize * offset); if (varcharsize * offset < size) *************** *** 392,401 **** if (pval) { if (varcharsize == 0 || varcharsize > size) ! strncpy((char *) ((long) var + offset * act_tuple), pval, size + 1); else { ! strncpy((char *) ((long) var + offset * act_tuple), pval, varcharsize); if (varcharsize < size) { --- 392,401 ---- if (pval) { if (varcharsize == 0 || varcharsize > size) ! strncpy((char *) ((intptr_t) var + offset * act_tuple), pval, size + 1); else { ! strncpy((char *) ((intptr_t) var + offset * act_tuple), pval, varcharsize); if (varcharsize < size) { *************** *** 434,440 **** if (pval) { struct ECPGgeneric_varchar *variable = ! (struct ECPGgeneric_varchar *) ((long) var + offset * act_tuple); variable->len = size; if (varcharsize == 0) --- 434,440 ---- if (pval) { struct ECPGgeneric_varchar *variable = ! (struct ECPGgeneric_varchar *) ((intptr_t) var + offset * act_tuple); variable->len = size; if (varcharsize == 0) diff -cwbr postgresql-8.4beta2-orig/src/pl/plperl/plperl.c postgresql-8.4beta2-winx64/src/pl/plperl/plperl.c *** postgresql-8.4beta2-orig/src/pl/plperl/plperl.c 2009-02-20 19:39:19.000000000 +0900 --- postgresql-8.4beta2-winx64/src/pl/plperl/plperl.c 2009-06-18 19:25:06.000000000 +0900 *************** *** 2192,2198 **** ************************************************************/ qdesc = (plperl_query_desc *) malloc(sizeof(plperl_query_desc)); MemSet(qdesc, 0, sizeof(plperl_query_desc)); ! snprintf(qdesc->qname, sizeof(qdesc->qname), "%lx", (long) qdesc); qdesc->nargs = argc; qdesc->argtypes = (Oid *) malloc(argc * sizeof(Oid)); qdesc->arginfuncs = (FmgrInfo *) malloc(argc * sizeof(FmgrInfo)); --- 2192,2198 ---- ************************************************************/ qdesc = (plperl_query_desc *) malloc(sizeof(plperl_query_desc)); MemSet(qdesc, 0, sizeof(plperl_query_desc)); ! snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc); qdesc->nargs = argc; qdesc->argtypes = (Oid *) malloc(argc * sizeof(Oid)); qdesc->arginfuncs = (FmgrInfo *) malloc(argc * sizeof(FmgrInfo)); diff -cwbr postgresql-8.4beta2-orig/src/port/open.c postgresql-8.4beta2-winx64/src/port/open.c *** postgresql-8.4beta2-orig/src/port/open.c 2009-01-02 02:24:04.000000000 +0900 --- postgresql-8.4beta2-winx64/src/port/open.c 2009-06-18 19:22:08.000000000 +0900 *************** *** 123,129 **** } /* _open_osfhandle will, on error, set errno accordingly */ ! if ((fd = _open_osfhandle((long) h, fileFlags & O_APPEND)) < 0) CloseHandle(h); /* will not affect errno */ else if (fileFlags & (O_TEXT | O_BINARY) && _setmode(fd, fileFlags & (O_TEXT | O_BINARY)) < 0) --- 123,129 ---- } /* _open_osfhandle will, on error, set errno accordingly */ ! if ((fd = _open_osfhandle((intptr_t) h, fileFlags & O_APPEND)) < 0) CloseHandle(h); /* will not affect errno */ else if (fileFlags & (O_TEXT | O_BINARY) && _setmode(fd, fileFlags & (O_TEXT | O_BINARY)) < 0)
pgsql-hackers by date: