help-glpk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-glpk] Multithreading patch/hack


From: Rios, Joseph L. (ARC-AFO)
Subject: [Help-glpk] Multithreading patch/hack
Date: Thu, 29 Jul 2010 13:04:23 -0500

Hi all,

The topic of multithreading GLPK comes up quite often on the help-glpk
message list.  Here are some of the conversations:

http://lists.gnu.org/archive/html/help-glpk/2010-07/msg00062.html
http://lists.gnu.org/archive/html/help-glpk/2010-04/msg00031.html
http://lists.gnu.org/archive/html/help-glpk/2009-06/msg00071.html
http://lists.gnu.org/archive/html/help-glpk/2009-07/msg00000.html
http://lists.gnu.org/archive/html/help-glpk/2007-08/msg00040.html
http://lists.gnu.org/archive/html/help-glpk/2006-09/msg00004.html
http://lists.gnu.org/archive/html/help-glpk/2003-11/msg00038.html

In one of those message threads, I offered a hacky patch to enable use of
multithreading with the GLPK library.  I've had to re-visit this issue and
updated my version of GLPK to 4.44.  I'm attaching another patch for this
more current version of GLPK.  Also, just including the patch in the message
body below.  And for extra ease, I'm attaching the single file that was
altered (glpenv05.c).  To use it, just replace the existing file of the same
name in the src/ directory and make glpk.

The solution that worked for my projects was simply to replace the custom
malloc() calls with regular malloc() calls.  malloc() is thread safe on most
systems nowadays.  You can easily replace the malloc() call with another
memory allocator (e.g. tcmalloc).  For some conversations on malloc and
multiple threads see:

http://goog-perftools.sourceforge.net/doc/tcmalloc.html
http://stackoverflow.com/questions/147298/multithreaded-memory-allocators-fo
r-c-c
http://stackoverflow.com/questions/855763/malloc-thread-safe

Before this conversation gets too far afield on what is thread-safety and
re-entrant code, I want to be clear that I am not claiming this patch is a
cure-all for multi-threading.  It is simply a work-around to allow people to
do GLPK work that requires multiple threads.  Also, I should note that
depending on what parts of GLPK you are using, you may very well still have
multithreading problems when using this patch.  Andrew has offered some very
clear ways to go about making GLPK thread-safe and this isn't necessarily
one of them.  Implement TLS appropriately if you want something more robust.

I welcome any comments/suggestions/discussions on the patch.  One obvious
improvement would be to check the return value of malloc(), which I¹ve
neglected.

Joey

PS: Anything in this email is not covered under any warranty from me or my
employer.  Use at your own risk!


--- /home/jrios/temp/glpk-4.44/src/glpenv05.c    2010-06-03
01:00:00.000000000 -0700
+++ src/glpenv05.c    2010-07-01 16:43:08.000000000 -0700
@@ -54,7 +54,7 @@
 *  To free this block the routine glp_free (not free!) must be used. */
 
 void *glp_malloc(int size)
-{     ENV *env = get_env_ptr();
+{     /*ENV *env = get_env_ptr();
       MEM *desc;
       int size_of_desc = align_datasize(sizeof(MEM));
       if (size < 1 || size > INT_MAX - size_of_desc)
@@ -81,7 +81,8 @@
       env->mem_total = xladd(env->mem_total, xlset(size));
       if (xlcmp(env->mem_tpeak, env->mem_total) < 0)
          env->mem_tpeak = env->mem_total;
-      return (void *)((char *)desc + size_of_desc);
+      return (void *)((char *)desc + size_of_desc);*/
+      return malloc(size);
 }
 
 /***********************************************************************
@@ -107,14 +108,15 @@
 *  To free this block the routine glp_free (not free!) must be used. */
 
 void *glp_calloc(int n, int size)
-{     if (n < 1)
+{     /*if (n < 1)
          xerror("glp_calloc: n = %d; invalid parameter\n", n);
       if (size < 1)
          xerror("glp_calloc: size = %d; invalid parameter\n", size);
       if (n > INT_MAX / size)
          xerror("glp_calloc: n = %d; size = %d; array too big\n", n,
             size);
-      return xmalloc(n * size);
+      return xmalloc(n * size);*/
+      return calloc(n, size);
 }
 
 /***********************************************************************
@@ -132,7 +134,7 @@
 *  was previuosly allocated by the routine glp_malloc or glp_calloc. */
 
 void glp_free(void *ptr)
-{     ENV *env = get_env_ptr();
+{     /*ENV *env = get_env_ptr();
       MEM *desc;
       int size_of_desc = align_datasize(sizeof(MEM));
       if (ptr == NULL)
@@ -155,7 +157,8 @@
       env->mem_total = xlsub(env->mem_total, xlset(desc->size));
       memset(desc, '?', size_of_desc);
       free(desc);
-      return;
+      return;*/
+      free(ptr);
 }
 
 /***********************************************************************
@@ -173,11 +176,13 @@
 *  dynamic allocation (in GLPK routines) to limit megabytes. */
 
 void glp_mem_limit(int limit)
-{     ENV *env = get_env_ptr();
+{     /*ENV *env = get_env_ptr();
       if (limit < 0)
          xerror("glp_mem_limit: limit = %d; invalid parameter\n",
             limit);
-      env->mem_limit = xlmul(xlset(limit), xlset(1 << 20));
+      env->mem_limit = xlmul(xlset(limit), xlset(1 << 20));*/
+      printf("glp_mem_limit: not implemented in this version of glpk.");
+      printf(" Thread safety.\n");
       return;
 }
 
@@ -214,11 +219,13 @@
 
 void glp_mem_usage(int *count, int *cpeak, glp_long *total,
       glp_long *tpeak)
-{     ENV *env = get_env_ptr();
+{     /*ENV *env = get_env_ptr();
       if (count != NULL) *count = env->mem_count;
       if (cpeak != NULL) *cpeak = env->mem_cpeak;
       if (total != NULL) *total = env->mem_total;
-      if (tpeak != NULL) *tpeak = env->mem_tpeak;
+      if (tpeak != NULL) *tpeak = env->mem_tpeak;*/
+      printf("glp_mem_usage: not implemented in this version of glpk.");
+      printf(" Thread safety.\n");
       return;
 }
 

Attachment: glpk-4.44.ThreadReady.patch
Description: glpk-4.44.ThreadReady.patch

Attachment: glpenv05.c
Description: glpenv05.c


reply via email to

[Prev in Thread] Current Thread [Next in Thread]