summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/config-win.h3
-rw-r--r--include/my_pthread.h32
-rw-r--r--include/my_sys.h26
-rw-r--r--mysys/Makefile.am2
-rw-r--r--mysys/my_chsize.c10
-rw-r--r--mysys/my_mmap.c89
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
+