summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Wu <alexepico@gmail.com>2013-02-04 17:39:18 +0800
committerPeng Wu <alexepico@gmail.com>2013-02-04 17:39:18 +0800
commitb0e127fb24247f038ec643803c93a09831667920 (patch)
tree66e5c488276136967226247d2e38c69f752588f8
parentdbd8fa467a1034c89d3c2ca9ab06228eae3b9cb9 (diff)
downloadlibpinyin-b0e127fb24247f038ec643803c93a09831667920.tar.gz
libpinyin-b0e127fb24247f038ec643803c93a09831667920.tar.xz
libpinyin-b0e127fb24247f038ec643803c93a09831667920.zip
add mmap support
-rw-r--r--configure.ac1
-rw-r--r--src/include/memory_chunk.h58
2 files changed, 45 insertions, 14 deletions
diff --git a/configure.ac b/configure.ac
index d5ff4b0..e32e1cf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,7 @@ AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_FUNC_REALLOC
AC_FUNC_STAT
+AC_FUNC_MMAP
AC_CHECK_FUNCS([gettimeofday memmove memset setlocale])
AC_CHECK_HEADERS([libintl.h string.h])
diff --git a/src/include/memory_chunk.h b/src/include/memory_chunk.h
index 0d9eecb..29eb586 100644
--- a/src/include/memory_chunk.h
+++ b/src/include/memory_chunk.h
@@ -22,16 +22,21 @@
#ifndef MEMORY_CHUNK_H
#define MEMORY_CHUNK_H
+#include <config.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
#include "stl_lite.h"
namespace pinyin{
/* for unmanaged mode
- * m_free_func == free , when memory is allocated by malloc
+ * m_free_func == free, when memory is allocated by malloc
+ * m_free_func == munmap, when memory is allocated by mmap
* m_free_func == NULL,
* when memory is in small protion of allocated area
* m_free_func == other,
@@ -46,7 +51,7 @@ namespace pinyin{
*/
class MemoryChunk{
- typedef void (* free_func_t)(void *);
+ typedef void (* free_func_t)(...);
private:
char * m_data_begin;
char * m_data_end; //one data pass the end.
@@ -54,9 +59,22 @@ private:
free_func_t m_free_func;
private:
+ void freemem(){
+ if ((free_func_t)free == m_free_func)
+ free(m_data_begin);
+#ifdef HAVE_MMAP
+ else if ((free_func_t)munmap == m_free_func)
+ munmap(m_data_begin, capacity());
+#endif
+ else
+ assert(FALSE);
+ }
+
+
void reset(){
- if ( m_free_func )
- (*m_free_func)(m_data_begin);
+ if (m_free_func)
+ freemem();
+
m_data_begin = NULL;
m_data_end = NULL;
m_allocated = NULL;
@@ -74,7 +92,7 @@ private:
if ( 0 == extra_size ) return;
size_t newsize;
size_t cursize = size();
- if ( m_free_func != free ) {
+ if ( m_free_func != (free_func_t)free ) {
/* copy on resize */
newsize = cursize + extra_size;
/* do the copy */
@@ -83,15 +101,13 @@ private:
memset(tmp, 0, newsize);
memmove(tmp, m_data_begin, cursize);
/* free the origin memory */
- if ( m_free_func){
- (*m_free_func)(m_data_begin);
- }
-
+ if (m_free_func)
+ freemem();
/* change varibles */
m_data_begin = tmp;
m_data_end = m_data_begin + cursize;
m_allocated = m_data_begin + newsize;
- m_free_func = free;
+ m_free_func = (free_func_t)free;
return;
}
/* the memory area is managed by this memory chunk */
@@ -192,8 +208,8 @@ public:
*
*/
void set_chunk(void* begin, size_t length, free_func_t free_func){
- if ( m_free_func )
- m_free_func( m_data_begin );
+ if (m_free_func)
+ freemem();
m_data_begin = (char *) begin;
m_data_end = (char *) m_data_begin + length;
@@ -312,7 +328,7 @@ public:
*
*/
void compact_memory(){
- if ( m_free_func != free )
+ if ( m_free_func != (free_func_t)free )
return;
size_t newsize = size();
m_data_begin = (char *) realloc(m_data_begin, newsize);
@@ -342,6 +358,19 @@ public:
fseek(file, 0, SEEK_SET);
int data_len = file_size;
+
+#ifdef HAVE_MMAP
+ int fd = fileno(file);
+ void* data = mmap(NULL, data_len, PROT_READ|PROT_WRITE, MAP_PRIVATE,
+ fd, 0);
+
+ if (MAP_FAILED == data) {
+ fclose(file);
+ return false;
+ }
+
+ set_chunk(data, data_len, (free_func_t)munmap);
+#else
void* data = malloc(data_len);
if ( !data ){
fclose(file);
@@ -349,7 +378,8 @@ public:
}
data_len = fread(data, 1, data_len, file);
- set_chunk(data, data_len, free);
+ set_chunk(data, data_len, (free_func_t)free);
+#endif
fclose(file);
return true;