Commits

Anonymous committed cfbcbf6

improved and enabled memory manager, also introduced shared library constructors and destructors. These seem to work with GCC, needs
testing with SunCC and needs implementation with MSVC.

  • Participants
  • Parent commits 0244d50

Comments (0)

Files changed (4)

 #include <mm_malloc.h>
 #endif
 
+#include "grayflex.h"
+
 /* blocks of memory we like to keep around for later re-use */
 mm_block m4ri_mmc_cache[M4RI_MMC_NBLOCKS];
 
   else return newthing;
 }
 
-void m4ri_mm_free(void *condemned) { 
+void m4ri_mm_free(void *condemned, ...) { 
 #ifdef HAVE_MM_MALLOC
   _mm_free(condemned); 
 #else
     return 1;
   }
 }
+
+#if defined(__GNUC__)
+void __attribute__ ((constructor)) m4ri_init()
+#else
+void m4ri_init()
+#endif
+{
+  m4ri_build_all_codes();
+}
+#if defined(__SUNCC__)
+#pragma init(m4ri_init)
+#endif
+
+#if defined(__GNUC__)
+void __attribute__ ((destructor)) m4ri_fini()
+#else
+void m4ri_fini()
+#endif
+{
+  m4ri_mmc_cleanup();
+  m4ri_destroy_all_codes();
+}
+#if defined(__SUNCC__)
+#pragma fini(m4ri_fini)
+#endif
 
 BIT m4ri_coin_flip();
 
+/***** Initialization *****/
+
+/**
+ * Initialize global data structures for the M4RI library. 
+ *
+ * On Linux/Solaris this is called automatically when the shared
+ * library is loaded, but it doesn't harm if it is called twice.
+ */
+
+#if defined(__GNUC__)
+void __attribute__ ((constructor)) m4ri_init();
+#else
+void m4ri_init();
+#endif
+
+/**
+ * De-initialize global data structures from the M4RI library. 
+ *
+ * On Linux/Solaris this is called automatically when the shared
+ * library is unloaded, but it doesn't harm if it is called twice.
+ */
+
+#if defined(__GNUC__)
+void __attribute__ ((destructor)) m4ri_fini();
+#else
+void m4ri_fini();
+#endif
+
 /***** Memory Management *****/
 
 /**
  * \todo Allow user to register free function.
  */
 
-void m4ri_mm_free(void *condemned);
+void m4ri_mm_free(void *condemned, ...);
 
 /**
  * Number of blocks that are cached.
  */
 
 static inline void m4ri_mmc_free(void *condemned, size_t size) {
+  static size_t j = 0;
   mm_block *mm = m4ri_mmc_handle();
   if (size < M4RI_MMC_THRESHOLD) {
     size_t i;
         return;
       }
     }
+    m4ri_mm_free(mm[j].data);
+    mm[j].size = size;
+    mm[j].data = condemned;
+    j = (j+1) % M4RI_MMC_NBLOCKS;
+    return;
   }
   m4ri_mm_free(condemned);
 }

src/packedmatrix.c

   packedmatrix *newmatrix;
   size_t i;
 
-  newmatrix=(packedmatrix *)m4ri_mm_malloc(sizeof(packedmatrix));
+  newmatrix=(packedmatrix *)m4ri_mmc_malloc(sizeof(packedmatrix));
   newmatrix->width=DIV_CEIL(c,RADIX);
 
 #ifdef HAVE_SSE2
   newmatrix->ncols=c;
   newmatrix->nrows=r;
   newmatrix->offset = 0;
-  newmatrix->values=(word *)m4ri_mm_calloc( (newmatrix->width)*r, sizeof(word) );
+  newmatrix->values=(word *)m4ri_mmc_calloc( (newmatrix->width)*r, sizeof(word) );
 
-  newmatrix->rowswap=(size_t *)m4ri_mm_malloc( r * sizeof(size_t) );
+  newmatrix->rowswap=(size_t *)m4ri_mmc_malloc( r * sizeof(size_t) );
 
   /* Rowswap does not contain the rowswap index i but the correct
    * offset in the values table. Rowswap is exclusively used to access
 
 packedmatrix *mzd_init_window (const packedmatrix *m, size_t lowr, size_t lowc, size_t highr, size_t highc) {
   size_t nrows, ncols, i, offset; 
-  packedmatrix *window = (packedmatrix *)m4ri_mm_malloc(sizeof(packedmatrix));
+  packedmatrix *window = (packedmatrix *)m4ri_mmc_malloc(sizeof(packedmatrix));
   nrows = MIN(highr - lowr, m->nrows - lowr);
   ncols = highc - lowc;
   
   
   window->values = m->values;
 
-  window->rowswap = (size_t *)m4ri_mm_malloc( nrows * sizeof(size_t));
+  window->rowswap = (size_t *)m4ri_mmc_malloc( nrows * sizeof(size_t));
   for(i=0; i<nrows; i++) {
     window->rowswap[i] = m->rowswap[lowr + i] + offset;
   }
 }
 
 void mzd_free( packedmatrix *condemned) {
-  m4ri_mm_free(condemned->values);
-  m4ri_mm_free(condemned->rowswap);
-  m4ri_mm_free(condemned);
+  m4ri_mmc_free(condemned->values, condemned->width*condemned->nrows*sizeof(word));
+  m4ri_mmc_free(condemned->rowswap, condemned->nrows * sizeof(size_t));
+  m4ri_mmc_free(condemned, sizeof(packedmatrix));
 }
 
 void mzd_free_window( packedmatrix *condemned) {
-  m4ri_mm_free(condemned->rowswap);
-  m4ri_mm_free(condemned);
+  m4ri_mmc_free(condemned->rowswap, condemned->nrows * sizeof(size_t));
+  m4ri_mmc_free(condemned, sizeof(packedmatrix));
 }
 
 void mzd_free_permutation_window (permutation* condemned){
   }
 #ifdef HAVE_OPENMP
   /* this one isn't optimal */
-  return _mzd_mul_mp_even(C, A, B, cutoff);
+  C = _mzd_mul_mp_even(C, A, B, cutoff);
 #else
-  return _mzd_mul_even(C, A, B, cutoff);
+  C = _mzd_mul_even(C, A, B, cutoff);
 #endif  
+  return C;
 }
 
 packedmatrix *_mzd_addmul_even(packedmatrix *C, packedmatrix *A, packedmatrix *B, int cutoff) {
     m4ri_die("mzd_addmul: C (%d x %d) has wrong dimensions, expected (%d x %d)\n",
 	     C->nrows, C->ncols, A->nrows, B->ncols);
   }
-  return _mzd_addmul(C, A, B, cutoff);
+  C = _mzd_addmul(C, A, B, cutoff);
+  return C;
 }