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; }
glpk-4.44.ThreadReady.patch
Description: glpk-4.44.ThreadReady.patch
glpenv05.c
Description: glpenv05.c
_______________________________________________ Help-glpk mailing list [email protected] http://lists.gnu.org/mailman/listinfo/help-glpk
