diff options
-rw-r--r-- | include/config-win.h | 3 | ||||
-rw-r--r-- | include/my_pthread.h | 32 | ||||
-rw-r--r-- | include/my_sys.h | 26 | ||||
-rw-r--r-- | mysys/Makefile.am | 2 | ||||
-rw-r--r-- | mysys/my_chsize.c | 10 | ||||
-rw-r--r-- | mysys/my_mmap.c | 89 |
6 files changed, 148 insertions, 14 deletions
diff --git a/include/config-win.h b/include/config-win.h index d28bb25cd09..32ce837e926 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -301,6 +301,9 @@ inline double ulonglong2double(ulonglong value) #define HAVE_SETFILEPOINTER #define HAVE_VIO +#define HAME_MMAP /* in mysys/my_mmap.c */ +#define HAVE_GETPAGESIZE /* in mysys/my_mmap.c */ + #ifdef NOT_USED #define HAVE_SNPRINTF /* Gave link error */ #define _snprintf snprintf diff --git a/include/my_pthread.h b/include/my_pthread.h index cd0cf49a891..b47cf64aa12 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -674,21 +674,43 @@ extern pthread_t shutdown_th, main_th, signal_th; #ifndef thread_safe_increment #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_sub(V,C,L) atomic_sub((C),(atomic_t*) &V); #else #define thread_safe_increment(V,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)); + (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L))) +#define thread_safe_decrement(V,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) \ - 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 */ #ifdef SAFE_STATISTICS #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)) #else +#define statistic_decrement(V,L) (V)-- #define statistic_increment(V,L) (V)++ #define statistic_add(V,C,L) (V)+=(C) #endif /* SAFE_STATISTICS */ diff --git a/include/my_sys.h b/include/my_sys.h index e99b2d343ff..8d017f2d614 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -772,6 +772,32 @@ void my_free_open_file_info(void); ulonglong my_getsystime(void); 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 */ extern uint get_charset_number(const char *cs_name, uint cs_flags); extern uint get_collation_number(const char *name); diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 8eae7551f34..6a118df03cc 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -26,7 +26,7 @@ noinst_HEADERS = mysys_priv.h my_static.h \ my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \ my_os2dlfcn.c my_os2file64.c my_os2mutex.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 \ my_open.c my_create.c my_dup.c my_seek.c my_read.c \ my_pread.c my_write.c \ diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c index cf26428d65f..c258121226d 100644 --- a/mysys/my_chsize.c +++ b/mysys/my_chsize.c @@ -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)); if (oldsize > newlength) + { #if defined(HAVE_SETFILEPOINTER) /* This is for the moment only true on windows */ - { long is_success; HANDLE win_file= (HANDLE) _get_osfhandle(fd); long length_low, length_high; @@ -63,35 +63,29 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) DBUG_RETURN(0); my_errno= GetLastError(); goto err; - } #elif defined(HAVE_FTRUNCATE) - { if (ftruncate(fd, (off_t) newlength)) { my_errno= errno; goto err; } DBUG_RETURN(0); - } #elif defined(HAVE_CHSIZE) - { if (chsize(fd, (off_t) newlength)) { my_errno=errno; goto err; } DBUG_RETURN(0); - } #else - { /* Fill space between requested length and true length with 'filler' We should never come here on any modern machine */ VOID(my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))); swap_variables(my_off_t, newlength, oldsize); - } #endif + } /* Full file with 'filler' until it's as big as requested */ bfill(buff, IO_SIZE, filler); diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c new file mode 100644 index 00000000000..883181edd6c --- /dev/null +++ b/mysys/my_mmap.c @@ -0,0 +1,89 @@ +/* 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 + |