From 965ac3c8142a5b8afdd7410f930c23fa9d5657a9 Mon Sep 17 00:00:00 2001 From: Tsutomu Yamada Date: Fri, 28 Aug 2009 18:39:49 +0900 Subject: [PATCH 2/3] fix for Windows x64 * add defines for WIN64 * support over 4GB shared memory * fix API portablity --- src/backend/port/win32_shmem.c | 29 +++++++++++++++++++---------- src/backend/postmaster/postmaster.c | 4 ++++ src/backend/postmaster/syslogger.c | 2 +- src/include/pg_config.h.win32 | 8 ++++++++ src/include/storage/pg_shmem.h | 4 ++++ src/include/storage/s_lock.h | 12 ++++++++++++ src/port/open.c | 2 +- 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index fc8e51b..6a31b1c 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -16,7 +16,7 @@ #include "storage/ipc.h" #include "storage/pg_shmem.h" -unsigned long UsedShmemSegID = 0; +HANDLE UsedShmemSegID = 0; void *UsedShmemSegAddr = NULL; static Size UsedShmemSegSize = 0; @@ -125,6 +125,8 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) hmap2; char *szShareMem; int i; + DWORD size_high; + DWORD size_low; /* Room for a header? */ Assert(size > MAXALIGN(sizeof(PGShmemHeader))); @@ -133,6 +135,13 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) UsedShmemSegAddr = NULL; +#ifdef _WIN64 + size_high = size >> 32; +#else + size_high = 0; +#endif + size_low = (DWORD) size; + /* * When recycling a shared memory segment, it may take a short while * before it gets dropped from the global namespace. So re-try after @@ -147,11 +156,11 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) */ SetLastError(0); - hmap = CreateFileMapping((HANDLE) 0xFFFFFFFF, /* Use the pagefile */ + hmap = CreateFileMapping(INVALID_HANDLE_VALUE, /* Use the pagefile */ NULL, /* Default security attrs */ PAGE_READWRITE, /* Memory is Read/Write */ - 0L, /* Size Upper 32 Bits */ - (DWORD) size, /* Size Lower 32 bits */ + size_high, /* Size Upper 32 Bits */ + size_low, /* Size Lower 32 bits */ szShareMem); if (!hmap) @@ -203,7 +212,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) /* Register on-exit routine to delete the new segment */ - on_shmem_exit(pgwin32_SharedMemoryDelete, Int32GetDatum((unsigned long) hmap2)); + on_shmem_exit(pgwin32_SharedMemoryDelete, PointerGetDatum(hmap2)); /* * Get a pointer to the new shared memory segment. Map the whole segment @@ -235,7 +244,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) /* Save info for possible future use */ UsedShmemSegAddr = memAddress; UsedShmemSegSize = size; - UsedShmemSegID = (unsigned long) hmap2; + UsedShmemSegID = hmap2; return hdr; } @@ -266,10 +275,10 @@ PGSharedMemoryReAttach(void) elog(FATAL, "failed to release reserved memory region (addr=%p): %lu", UsedShmemSegAddr, GetLastError()); - hdr = (PGShmemHeader *) MapViewOfFileEx((HANDLE) UsedShmemSegID, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, UsedShmemSegAddr); + hdr = (PGShmemHeader *) MapViewOfFileEx(UsedShmemSegID, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, UsedShmemSegAddr); if (!hdr) - elog(FATAL, "could not reattach to shared memory (key=%d, addr=%p): %lu", - (int) UsedShmemSegID, UsedShmemSegAddr, GetLastError()); + elog(FATAL, "could not reattach to shared memory (key=%p, addr=%p): %lu", + UsedShmemSegID, UsedShmemSegAddr, GetLastError()); if (hdr != origUsedShmemSegAddr) elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)", hdr, origUsedShmemSegAddr); @@ -308,7 +317,7 @@ static void pgwin32_SharedMemoryDelete(int status, Datum shmId) { PGSharedMemoryDetach(); - if (!CloseHandle((HANDLE) DatumGetInt32(shmId))) + if (!CloseHandle(DatumGetPointer(shmId))) elog(LOG, "could not close handle to shared memory: %lu", GetLastError()); } diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index e94181a..d1e52d1 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -402,7 +402,11 @@ typedef struct int ListenSocket[MAXLISTEN]; long MyCancelKey; int MyPMChildSlot; +#ifndef WIN32 unsigned long UsedShmemSegID; +#else + HANDLE UsedShmemSegID; +#endif void *UsedShmemSegAddr; slock_t *ShmemLock; VariableCache ShmemVariableCache; diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index 96865e1..ebc4388 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -573,7 +573,7 @@ SysLogger_Start(void) * chunking protocol. */ fflush(stderr); - fd = _open_osfhandle((long) syslogPipe[1], + fd = _open_osfhandle((intptr_t) syslogPipe[1], _O_APPEND | _O_BINARY); if (dup2(fd, _fileno(stderr)) < 0) ereport(FATAL, diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index b1981fd..0621c15 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -590,13 +590,21 @@ /* #undef PTHREAD_CREATE_JOINABLE */ /* The size of a `size_t', as computed by sizeof. */ +#ifdef _WIN64 +#define SIZEOF_SIZE_T 8 +#else #define SIZEOF_SIZE_T 4 +#endif /* The size of a `unsigned long', as computed by sizeof. */ #define SIZEOF_UNSIGNED_LONG 4 /* The size of `void *', as computed by sizeof. */ +#ifdef _WIN64 +#define SIZEOF_VOID_P 8 +#else #define SIZEOF_VOID_P 4 +#endif /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h index 37fae22..bc23c1d 100644 --- a/src/include/storage/pg_shmem.h +++ b/src/include/storage/pg_shmem.h @@ -40,7 +40,11 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */ #ifdef EXEC_BACKEND +#ifndef WIN32 extern unsigned long UsedShmemSegID; +#else +extern HANDLE UsedShmemSegID; +#endif extern void *UsedShmemSegAddr; extern void PGSharedMemoryReAttach(void); diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index 48208b9..74c6dd7 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -836,12 +836,24 @@ typedef LONG slock_t; #define SPIN_DELAY() spin_delay() +/* If using Visual C 2005 or 2008 on Win64, inline assembly is unavailable. + * Use a __noop instrinsic instead of rep nop. + * Might be slightly less efficient on EMT64, but its the same for AMD. + */ +#if defined(_WIN64) && defined(_MSC_VER) && (_MSC_VER == 1400 || _MSC_VER == 1500) +static __forceinline void +spin_delay(void) +{ + __noop(); +} +#else static __forceinline void spin_delay(void) { /* See comment for gcc code. Same code, MASM syntax */ __asm rep nop; } +#endif #endif diff --git a/src/port/open.c b/src/port/open.c index f3a0a15..74edc99 100644 --- a/src/port/open.c +++ b/src/port/open.c @@ -124,7 +124,7 @@ pgwin32_open(const char *fileName, int fileFlags,...) } /* _open_osfhandle will, on error, set errno accordingly */ - if ((fd = _open_osfhandle((long) h, fileFlags & O_APPEND)) < 0) + 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) -- 1.6.4