Commit bb9cc040 authored by serg@serg.mylan's avatar serg@serg.mylan

mmap portability layer, mmap for Windows

new macro: thread_safe_decrement, thread_safe_dec_and_test, statistic_decrement
parent de914eb3
...@@ -301,6 +301,9 @@ inline double ulonglong2double(ulonglong value) ...@@ -301,6 +301,9 @@ inline double ulonglong2double(ulonglong value)
#define HAVE_SETFILEPOINTER #define HAVE_SETFILEPOINTER
#define HAVE_VIO #define HAVE_VIO
#define HAME_MMAP /* in mysys/my_mmap.c */
#define HAVE_GETPAGESIZE /* in mysys/my_mmap.c */
#ifdef NOT_USED #ifdef NOT_USED
#define HAVE_SNPRINTF /* Gave link error */ #define HAVE_SNPRINTF /* Gave link error */
#define _snprintf snprintf #define _snprintf snprintf
......
...@@ -674,21 +674,43 @@ extern pthread_t shutdown_th, main_th, signal_th; ...@@ -674,21 +674,43 @@ extern pthread_t shutdown_th, main_th, signal_th;
#ifndef thread_safe_increment #ifndef thread_safe_increment
#ifdef HAVE_ATOMIC_ADD #ifdef HAVE_ATOMIC_ADD
#define thread_safe_increment(V,L) atomic_add(1,(atomic_t*) &V); #define thread_safe_increment(V,L) atomic_inc((atomic_t*) &V);
#define thread_safe_decrement(V,L) atomic_dec((atomic_t*) &V);
#define thread_safe_dec_and_test(V, L) atomic_dec_and_test((atomic_t*) &V);
#define thread_safe_add(V,C,L) atomic_add((C),(atomic_t*) &V); #define thread_safe_add(V,C,L) atomic_add((C),(atomic_t*) &V);
#define thread_safe_sub(V,C,L) atomic_sub((C),(atomic_t*) &V); #define thread_safe_sub(V,C,L) atomic_sub((C),(atomic_t*) &V);
#else #else
#define thread_safe_increment(V,L) \ #define thread_safe_increment(V,L) \
pthread_mutex_lock((L)); (V)++; pthread_mutex_unlock((L)); (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
#define thread_safe_add(V,C,L) \ #define thread_safe_decrement(V,L) \
pthread_mutex_lock((L)); (V)+=(C); pthread_mutex_unlock((L)); (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
#define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
#define thread_safe_sub(V,C,L) \ #define thread_safe_sub(V,C,L) \
pthread_mutex_lock((L)); (V)-=(C); pthread_mutex_unlock((L)); (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
#if defined (__GNUC__) || defined (__cplusplus)
static inline bool thread_safe_dec_and_test(ulong V, pthread_mutex_t *L)
{
ulong res;
pthread_mutex_lock(L);
res=V--;
pthread_mutex_unlock(L);
return res==0;
}
#else
/*
what should we do ? define it as static ?
a regular function somewhere in mysys/ ?
for now it's only used in c++ code, so there's no need to bother
*/
#warning "No thread_safe_dec_and_test() for this architecture"
#endif
#endif /* HAVE_ATOMIC_ADD */ #endif /* HAVE_ATOMIC_ADD */
#ifdef SAFE_STATISTICS #ifdef SAFE_STATISTICS
#define statistic_increment(V,L) thread_safe_increment((V),(L)) #define statistic_increment(V,L) thread_safe_increment((V),(L))
#define statistic_decrement(V,L) thread_safe_decrement((V),(L))
#define statistic_add(V,C,L) thread_safe_add((V),(C),(L)) #define statistic_add(V,C,L) thread_safe_add((V),(C),(L))
#else #else
#define statistic_decrement(V,L) (V)--
#define statistic_increment(V,L) (V)++ #define statistic_increment(V,L) (V)++
#define statistic_add(V,C,L) (V)+=(C) #define statistic_add(V,C,L) (V)+=(C)
#endif /* SAFE_STATISTICS */ #endif /* SAFE_STATISTICS */
......
...@@ -772,6 +772,32 @@ void my_free_open_file_info(void); ...@@ -772,6 +772,32 @@ void my_free_open_file_info(void);
ulonglong my_getsystime(void); ulonglong my_getsystime(void);
my_bool my_gethwaddr(uchar *to); my_bool my_gethwaddr(uchar *to);
#ifdef HAVE_MMAP
#include <sys/mman.h>
#ifndef MAP_NOSYNC
#define MAP_NOSYNC 0
#endif
#define my_mmap(a,b,c,d,e,f) mmap(a,b,c,d,e,f)
#define my_getpagesize() getpagesize()
#define my_munmap(a,b) munmap(a,b)
#else
/* not a complete set of mmap() flags, but only those that nesessary */
#define PROT_READ 1
#define PROT_WRITE 2
#define MAP_NOSYNC 0x800
#define MAP_FAILED ((void *)-1)
#define MS_SYNC 0x0000
int my_getpagesize(void);
void *my_mmap(void *, size_t, int, int, int, my_off_t);
int my_munmap(void *, size_t);
#endif
int my_msync(int, void *, size_t, int);
/* character sets */ /* character sets */
extern uint get_charset_number(const char *cs_name, uint cs_flags); extern uint get_charset_number(const char *cs_name, uint cs_flags);
extern uint get_collation_number(const char *name); extern uint get_collation_number(const char *name);
......
...@@ -26,7 +26,7 @@ noinst_HEADERS = mysys_priv.h my_static.h \ ...@@ -26,7 +26,7 @@ noinst_HEADERS = mysys_priv.h my_static.h \
my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \ my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \
my_os2dlfcn.c my_os2file64.c my_os2mutex.c \ my_os2dlfcn.c my_os2file64.c my_os2mutex.c \
my_os2thread.c my_os2tls.c my_os2thread.c my_os2tls.c
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c \ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
mf_path.c mf_loadpath.c my_file.c \ mf_path.c mf_loadpath.c my_file.c \
my_open.c my_create.c my_dup.c my_seek.c my_read.c \ my_open.c my_create.c my_dup.c my_seek.c my_read.c \
my_pread.c my_write.c \ my_pread.c my_write.c \
......
...@@ -48,9 +48,9 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) ...@@ -48,9 +48,9 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize)); DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
if (oldsize > newlength) if (oldsize > newlength)
{
#if defined(HAVE_SETFILEPOINTER) #if defined(HAVE_SETFILEPOINTER)
/* This is for the moment only true on windows */ /* This is for the moment only true on windows */
{
long is_success; long is_success;
HANDLE win_file= (HANDLE) _get_osfhandle(fd); HANDLE win_file= (HANDLE) _get_osfhandle(fd);
long length_low, length_high; long length_low, length_high;
...@@ -63,35 +63,29 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) ...@@ -63,35 +63,29 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
DBUG_RETURN(0); DBUG_RETURN(0);
my_errno= GetLastError(); my_errno= GetLastError();
goto err; goto err;
}
#elif defined(HAVE_FTRUNCATE) #elif defined(HAVE_FTRUNCATE)
{
if (ftruncate(fd, (off_t) newlength)) if (ftruncate(fd, (off_t) newlength))
{ {
my_errno= errno; my_errno= errno;
goto err; goto err;
} }
DBUG_RETURN(0); DBUG_RETURN(0);
}
#elif defined(HAVE_CHSIZE) #elif defined(HAVE_CHSIZE)
{
if (chsize(fd, (off_t) newlength)) if (chsize(fd, (off_t) newlength))
{ {
my_errno=errno; my_errno=errno;
goto err; goto err;
} }
DBUG_RETURN(0); DBUG_RETURN(0);
}
#else #else
{
/* /*
Fill space between requested length and true length with 'filler' Fill space between requested length and true length with 'filler'
We should never come here on any modern machine We should never come here on any modern machine
*/ */
VOID(my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))); VOID(my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE)));
swap_variables(my_off_t, newlength, oldsize); swap_variables(my_off_t, newlength, oldsize);
}
#endif #endif
}
/* Full file with 'filler' until it's as big as requested */ /* Full file with 'filler' until it's as big as requested */
bfill(buff, IO_SIZE, filler); bfill(buff, IO_SIZE, filler);
......
/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#ifdef HAVE_MMAP
/*
system msync() only syncs mmap'ed area to fs cache.
fsync() is required to really sync to disc
*/
int my_msync(int fd, void *addr, size_t len, int flags)
{
msync(addr, len, flags);
return my_sync(fd, MYF(0));
}
#else
#ifdef __WIN__
static SECURITY_ATTRIBUTES mmap_security_attributes=
{sizeof(SECURITY_ATTRIBUTES), 0, TRUE};
int my_getpagesize(void)
{
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwPageSize;
}
void *my_mmap(void *addr, size_t len, int prot,
int flags, int fd, my_off_t offset)
{
DWORD flProtect=0;
HANDLE hFileMap;
LPVOID ptr;
flProtect|=SEC_COMMIT;
hFileMap=CreateFileMapping(fd, NULL, &mmap_security_attributes,
PAGE_READWRITE, 0, len, 0);
if (hFileMap == 0)
return MAP_FAILED;
ptr=MapViewOfFile(hFileMap,
flags & PROT_WRITE ? FILE_MAP_WRITE : FILE_MAP_READ,
(DWORD)(offset >> 32), (DWORD)offset, len);
/*
MSDN explicitly states that it's possible to close File Mapping Object
even when a view is not unmapped - then the object will be held open
implicitly until unmap, as every view stores internally a handler of
a corresponding File Mapping Object
*/
CloseHandle(hFileMap);
if (ptr)
return ptr;
return MAP_FAILED;
}
int my_munmap(void *addr, size_t len)
{
return UnmapViewOfFile(addr) ? 0 : -1;
}
int my_msync(int fd, void *addr, size_t len, int flags)
{
return FlushViewOfFile(addr, len) ? 0 : -1;
}
#endif
#error "no mmap!"
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment