* Sebastian Hammer, Adam Dickmeiss
*
* $Log: nmem.c,v $
- * Revision 1.21 2000-02-29 13:44:55 adam
+ * Revision 1.26 2001-07-19 19:51:42 adam
+ * Added typecasts to make C++ happy.
+ *
+ * Revision 1.25 2001/06/26 14:11:27 adam
+ * Added MUTEX functions for NMEM module (used by OID utility).
+ *
+ * Revision 1.24 2000/05/11 14:37:55 adam
+ * Minor changes.
+ *
+ * Revision 1.23 2000/05/09 10:55:05 adam
+ * Public nmem_print_list (for debugging).
+ *
+ * Revision 1.22 2000/05/03 22:00:00 adam
+ * Reference counter (if multiple modules are init/freeing nmem).
+ *
+ * Revision 1.21 2000/02/29 13:44:55 adam
* Check for config.h (currently not generated).
*
* Revision 1.20 2000/01/06 14:59:13 adam
#define NMEM_LEAVE
#endif
+
+struct nmem_mutex {
+#ifdef WIN32
+ CRITICAL_SECTION m_handle;
+#elif _REENTRANT
+ pthread_mutex_t m_handle;
+#else
+ int m_handle;
+#endif
+};
+
+YAZ_EXPORT void nmem_mutex_create(NMEM_MUTEX *p)
+{
+ NMEM_ENTER;
+ if (!*p)
+ {
+ *p = (NMEM_MUTEX) malloc (sizeof(**p));
+#ifdef WIN32
+ InitializeCriticalSection(&(*p)->m_handle);
+#elif _REENTRANT
+ pthread_mutex_init (&(*p)->m_handle, 0);
+#endif
+ }
+ NMEM_LEAVE;
+}
+
+YAZ_EXPORT void nmem_mutex_enter(NMEM_MUTEX p)
+{
+ if (p)
+ {
+#ifdef WIN32
+ EnterCriticalSection(&p->m_handle);
+#elif _REENTRANT
+ pthread_mutex_lock(&p->m_handle);
+#endif
+ }
+}
+
+YAZ_EXPORT void nmem_mutex_leave(NMEM_MUTEX p)
+{
+ if (p)
+ {
+#ifdef WIN32
+ LeaveCriticalSection(&p->m_handle);
+#elif _REENTRANT
+ pthread_mutex_unlock(&p->m_handle);
+#endif
+ }
+}
+
+YAZ_EXPORT void nmem_mutex_destroy(NMEM_MUTEX *p)
+{
+ NMEM_ENTER;
+ if (*p)
+ {
+#ifdef WIN32
+ DeleteCriticalSection(&(*p)->m_handle);
+#endif
+ free (*p);
+ *p = 0;
+ }
+ NMEM_LEAVE;
+}
+
static nmem_block *freelist = NULL; /* "global" freelists */
static nmem_control *cfreelist = NULL;
static int nmem_active_no = 0;
static int nmem_init_flag = 0;
#if NMEM_DEBUG
-struct nmem_debug {
+struct nmem_debug_info {
void *p;
char file[40];
int line;
- struct nmem_debug *next;
+ struct nmem_debug_info *next;
};
-struct nmem_debug *nmem_debug_list = 0;
+struct nmem_debug_info *nmem_debug_list = 0;
#endif
static void free_block(nmem_block *p)
#if NMEM_DEBUG
void nmem_print_list (void)
{
- struct nmem_debug *p;
+ struct nmem_debug_info *p;
yaz_log (LOG_DEBUG, "nmem print list");
NMEM_ENTER;
for (p = nmem_debug_list; p; p = p->next)
- yaz_log (LOG_DEBUG, " %s:%d p=%p", p->file, p->line, p->p);
+ yaz_log (LOG_DEBUG, " %s:%d p=%p size=%d", p->file, p->line, p->p,
+ nmem_total(p->p));
NMEM_LEAVE;
}
#endif
{
NMEM r;
#if NMEM_DEBUG
- struct nmem_debug *debug_p;
+ struct nmem_debug_info *debug_p;
#endif
NMEM_ENTER;
#endif
{
#if NMEM_DEBUG
- struct nmem_debug **debug_p;
+ struct nmem_debug_info **debug_p;
int ok = 0;
#endif
if (!n)
for (debug_p = &nmem_debug_list; *debug_p; debug_p = &(*debug_p)->next)
if ((*debug_p)->p == n)
{
- struct nmem_debug *debug_save = *debug_p;
+ struct nmem_debug_info *debug_save = *debug_p;
*debug_p = (*debug_p)->next;
xfree (debug_save);
ok = 1;
void nmem_init (void)
{
- nmem_init_flag = 1;
+ if (++nmem_init_flag == 1)
+ {
#ifdef WIN32
- InitializeCriticalSection(&critical_section);
+ InitializeCriticalSection(&critical_section);
#endif
- nmem_active_no = 0;
- freelist = NULL;
- cfreelist = NULL;
+ nmem_active_no = 0;
+ freelist = NULL;
+ cfreelist = NULL;
+ }
}
void nmem_exit (void)
{
- while (freelist)
- {
- struct nmem_block *fl = freelist;
- freelist = freelist->next;
- xfree (fl->buf);
- xfree (fl);
- }
- while (cfreelist)
+ if (--nmem_init_flag == 0)
{
- struct nmem_control *cfl = cfreelist;
- cfreelist = cfreelist->next;
- xfree (cfl);
- }
- nmem_init_flag = 0;
+ 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);
+ }
#ifdef WIN32
- DeleteCriticalSection(&critical_section);
+ DeleteCriticalSection(&critical_section);
#endif
+ }
}