X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fnmem.c;h=920d4e5fb880197fe50f5f1413ef866a22076285;hp=4f2504e28d83b4a58856a715ed02932091aa5a75;hb=69cc5b167c5afbc8d14c0db30f9a5fb34dda0a24;hpb=fe575eb97799f141b6e97d17c0e64619c4a9cd03 diff --git a/src/nmem.c b/src/nmem.c index 4f2504e..920d4e5 100644 --- a/src/nmem.c +++ b/src/nmem.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 1995-2005, Index Data ApS + * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: nmem.c,v 1.14 2005-01-21 09:23:27 adam Exp $ + * $Id: nmem.c,v 1.27 2006-12-13 15:29:01 adam Exp $ */ /** @@ -43,18 +43,33 @@ #define NMEM_CHUNK (4*1024) +struct nmem_block +{ + char *buf; /* memory allocated in this block */ + size_t size; /* size of buf */ + size_t top; /* top of buffer */ + struct nmem_block *next; +}; + +struct nmem_control +{ + int total; + struct nmem_block *blocks; + struct nmem_control *next; +}; + struct align { char x; union { - char c; - short s; - int i; - long l; + char c; + short s; + int i; + long l; #if HAVE_LONG_LONG - long long ll; + long long ll; #endif - float f; - double d; + float f; + double d; } u; }; @@ -92,25 +107,30 @@ struct nmem_mutex { }; #endif +size_t nmem_memory_in_use = 0; +size_t nmem_memory_free = 0; + YAZ_EXPORT void nmem_mutex_create(NMEM_MUTEX *p) { - if (!log_level_initialized) - { - log_level = yaz_log_module_level("nmem"); - log_level_initialized = 1; - } - + NMEM_ENTER; if (!*p) { - *p = (NMEM_MUTEX) malloc (sizeof(**p)); + *p = (NMEM_MUTEX) malloc(sizeof(**p)); #ifdef WIN32 - InitializeCriticalSection(&(*p)->m_handle); + InitializeCriticalSection(&(*p)->m_handle); #elif YAZ_POSIX_THREADS - pthread_mutex_init (&(*p)->m_handle, 0); + pthread_mutex_init(&(*p)->m_handle, 0); #elif YAZ_GNU_THREADS - pth_mutex_init (&(*p)->m_handle); + pth_mutex_init(&(*p)->m_handle); #endif } + NMEM_LEAVE; + if (!log_level_initialized) + { + log_level_initialized = 1; + log_level = yaz_log_module_level("nmem"); + } + } YAZ_EXPORT void nmem_mutex_enter(NMEM_MUTEX p) @@ -118,9 +138,9 @@ YAZ_EXPORT void nmem_mutex_enter(NMEM_MUTEX p) if (p) { #ifdef WIN32 - EnterCriticalSection(&p->m_handle); + EnterCriticalSection(&p->m_handle); #elif YAZ_POSIX_THREADS - pthread_mutex_lock(&p->m_handle); + pthread_mutex_lock(&p->m_handle); #endif } } @@ -130,9 +150,9 @@ YAZ_EXPORT void nmem_mutex_leave(NMEM_MUTEX p) if (p) { #ifdef WIN32 - LeaveCriticalSection(&p->m_handle); + LeaveCriticalSection(&p->m_handle); #elif YAZ_POSIX_THREADS - pthread_mutex_unlock(&p->m_handle); + pthread_mutex_unlock(&p->m_handle); #endif } } @@ -142,18 +162,28 @@ YAZ_EXPORT void nmem_mutex_destroy(NMEM_MUTEX *p) if (*p) { #ifdef WIN32 - DeleteCriticalSection(&(*p)->m_handle); + DeleteCriticalSection(&(*p)->m_handle); #endif - free (*p); - *p = 0; + free(*p); + *p = 0; } } -static nmem_block *freelist = NULL; /* "global" freelists */ -static nmem_control *cfreelist = NULL; +/** \brief free NMEM memory blocks . Reused in get_block */ +static struct nmem_block *freelist = NULL; + +/** \brief free NMEM control blocks. Reused in nmem_create */ +static struct nmem_control *cfreelist = NULL; + +/** \brief number NMEM's in use (number of nmem_controls not in free list) */ static int nmem_active_no = 0; + +/** \brief NMEM usage counter */ static int nmem_init_flag = 0; +/** \brief whether nmem blocks should be reassigned to heap */ +static int nmem_release_in_heap = 0; + #if NMEM_DEBUG struct nmem_debug_info { void *p; @@ -165,11 +195,21 @@ struct nmem_debug_info { struct nmem_debug_info *nmem_debug_list = 0; #endif -static void free_block(nmem_block *p) +static void free_block(struct nmem_block *p) { - memset(p->buf, 'Y', p->size); - p->next = freelist; - freelist = p; + nmem_memory_in_use -= p->size; + if (nmem_release_in_heap) + { + xfree(p->buf); + xfree(p); + } + else + { + memset(p->buf, 'Y', p->size); + p->next = freelist; + freelist = p; + nmem_memory_free += p->size; + } if (log_level) yaz_log (log_level, "nmem free_block p=%p", p); } @@ -177,7 +217,7 @@ static void free_block(nmem_block *p) #if NMEM_DEBUG void nmem_print_list (void) { - if(log_level) + if (log_level) nmem_print_list_l(log_level); } @@ -188,62 +228,65 @@ void nmem_print_list_l (int level) yaz_log (level, "nmem print list"); NMEM_ENTER; for (p = nmem_debug_list; p; p = p->next) - yaz_log (level, " %s:%d p=%p size=%d", p->file, p->line, p->p, - nmem_total(p->p)); + yaz_log (level, " %s:%d p=%p size=%d", p->file, p->line, p->p, + nmem_total(p->p)); NMEM_LEAVE; } #endif /* * acquire a block with a minimum of size free bytes. */ -static nmem_block *get_block(int size) +static struct nmem_block *get_block(size_t size) { - nmem_block *r, *l; + struct nmem_block *r, *l; if (log_level) - yaz_log (log_level, "nmem get_block size=%d", size); + yaz_log (log_level, "nmem get_block size=%ld", (long) size); for (r = freelist, l = 0; r; l = r, r = r->next) - if (r->size >= size) - break; + if (r->size >= size) + break; if (r) { if (log_level) - yaz_log (log_level, "nmem get_block found free block p=%p", r); - if (l) - l->next = r->next; - else - freelist = r->next; + yaz_log (log_level, "nmem get_block found free block p=%p", r); + if (l) + l->next = r->next; + else + freelist = r->next; + nmem_memory_free -= r->size; } else { - int get = NMEM_CHUNK; + size_t get = NMEM_CHUNK; - if (get < size) - get = size; + if (get < size) + get = size; if(log_level) - yaz_log (log_level, "nmem get_block alloc new block size=%d", get); + yaz_log (log_level, "nmem get_block alloc new block size=%ld", + (long) get); - r = (nmem_block *)xmalloc(sizeof(*r)); - r->buf = (char *)xmalloc(r->size = get); + r = (struct nmem_block *) xmalloc(sizeof(*r)); + r->buf = (char *)xmalloc(r->size = get); } + nmem_memory_in_use += r->size; r->top = 0; return r; } void nmem_reset(NMEM n) { - nmem_block *t; + struct nmem_block *t; yaz_log (log_level, "nmem_reset p=%p", n); if (!n) - return; + return; NMEM_ENTER; while (n->blocks) { - t = n->blocks; - n->blocks = n->blocks->next; - free_block(t); + t = n->blocks; + n->blocks = n->blocks->next; + free_block(t); } n->total = 0; NMEM_LEAVE; @@ -273,11 +316,11 @@ void *nmem_malloc(NMEM n, int size) #endif NMEM_ENTER; p = n->blocks; - if (!p || p->size - p->top < size) + if (!p || p->size < size + p->top) { - p = get_block(size); - p->next = n->blocks; - n->blocks = p; + p = get_block(size); + p->next = n->blocks; + n->blocks = p; } r = p->buf + p->top; /* align size */ @@ -312,9 +355,9 @@ NMEM nmem_create(void) nmem_active_no++; r = cfreelist; if (r) - cfreelist = cfreelist->next; + cfreelist = cfreelist->next; else - r = (nmem_control *)xmalloc(sizeof(*r)); + r = (struct nmem_control *)xmalloc(sizeof(*r)); NMEM_LEAVE; #if NMEM_DEBUG @@ -327,11 +370,11 @@ NMEM nmem_create(void) #if NMEM_DEBUG for (debug_p = nmem_debug_list; debug_p; debug_p = debug_p->next) - if (debug_p->p == r) - { - yaz_log (YLOG_FATAL, "multi used block in nmem"); - abort (); - } + if (debug_p->p == r) + { + yaz_log (YLOG_FATAL, "multi used block in nmem"); + abort (); + } debug_p = xmalloc (sizeof(*debug_p)); strncpy (debug_p->file, file, sizeof(debug_p->file)-1); debug_p->file[sizeof(debug_p->file)-1] = '\0'; @@ -356,51 +399,72 @@ void nmem_destroy(NMEM n) int ok = 0; #endif if (!n) - return; + return; #if NMEM_DEBUG yaz_log (log_level, "%s:%d: nmem_destroy %d p=%p", file, line, nmem_active_no-1, n); NMEM_ENTER; for (debug_p = &nmem_debug_list; *debug_p; debug_p = &(*debug_p)->next) - if ((*debug_p)->p == n) - { - struct nmem_debug_info *debug_save = *debug_p; - *debug_p = (*debug_p)->next; - xfree (debug_save); - ok = 1; - break; - } + if ((*debug_p)->p == n) + { + struct nmem_debug_info *debug_save = *debug_p; + *debug_p = (*debug_p)->next; + xfree (debug_save); + ok = 1; + break; + } NMEM_LEAVE; nmem_print_list(); if (!ok) { - yaz_log (YLOG_WARN, "%s:%d destroying unallocated nmem block p=%p", - file, line, n); - return; + yaz_log (YLOG_WARN, "%s:%d destroying unallocated nmem block p=%p", + file, line, n); + return; } #endif nmem_reset(n); NMEM_ENTER; nmem_active_no--; - n->next = cfreelist; - cfreelist = n; + if (nmem_release_in_heap) + { + xfree(n); + } + else + { + n->next = cfreelist; + cfreelist = n; + } NMEM_LEAVE; } void nmem_transfer (NMEM dst, NMEM src) { - nmem_block *t; + struct nmem_block *t; while ((t = src->blocks)) { - src->blocks = t->next; - t->next = dst->blocks; - dst->blocks = t; + src->blocks = t->next; + t->next = dst->blocks; + dst->blocks = t; } dst->total += src->total; src->total = 0; } +void nmem_get_memory_in_use(size_t *p) +{ + NMEM_ENTER; + *p = nmem_memory_in_use; + NMEM_LEAVE; +} + +void nmem_get_memory_free(size_t *p) +{ + NMEM_ENTER; + *p = nmem_memory_free; + NMEM_LEAVE; +} + void nmem_critical_enter (void) { NMEM_ENTER; @@ -413,17 +477,16 @@ void nmem_critical_leave (void) void nmem_init (void) { - if (++nmem_init_flag == 1) { #ifdef WIN32 - InitializeCriticalSection(&critical_section); + InitializeCriticalSection(&critical_section); #elif YAZ_GNU_THREADS pth_init (); #endif - nmem_active_no = 0; - freelist = NULL; - cfreelist = NULL; + nmem_active_no = 0; + freelist = NULL; + cfreelist = NULL; } if (!log_level_initialized) { @@ -437,21 +500,22 @@ void nmem_exit (void) if (--nmem_init_flag == 0) { oid_exit(); - while (freelist) - { - struct nmem_block *fl = freelist; - freelist = freelist->next; - xfree (fl->buf); - xfree (fl); - } - while (cfreelist) - { - struct nmem_control *cfl = cfreelist; - cfreelist = cfreelist->next; - xfree (cfl); - } + while (freelist) + { + struct nmem_block *fl = freelist; + nmem_memory_free -= fl->size; + freelist = freelist->next; + xfree (fl->buf); + xfree (fl); + } + while (cfreelist) + { + struct nmem_control *cfl = cfreelist; + cfreelist = cfreelist->next; + xfree (cfl); + } #ifdef WIN32 - DeleteCriticalSection(&critical_section); + DeleteCriticalSection(&critical_section); #endif } } @@ -459,16 +523,16 @@ void nmem_exit (void) #ifdef WIN32 BOOL WINAPI DllMain (HINSTANCE hinstDLL, - DWORD reason, - LPVOID reserved) + DWORD reason, + LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: - nmem_init (); - break; + nmem_init (); + break; case DLL_PROCESS_DETACH: - nmem_exit (); + nmem_exit (); } return TRUE; } @@ -501,16 +565,16 @@ void yaz_strerror(char *buf, int max) if (err) { FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default lang */ - (LPTSTR) buf, - max-1, - NULL); + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default lang */ + (LPTSTR) buf, + max-1, + NULL); } else - *buf = '\0'; + *buf = '\0'; #else /* UNIX */ #if HAVE_STRERROR_R @@ -529,7 +593,15 @@ void yaz_strerror(char *buf, int max) /* UNIX */ #endif if ((cp = strrchr(buf, '\n'))) - *cp = '\0'; + *cp = '\0'; if ((cp = strrchr(buf, '\r'))) - *cp = '\0'; + *cp = '\0'; } +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +