1. CarloWood
  2. M4RI

Commits

Martin Albrecht  committed b0589ec

thread safe-ness + refined lib constructor/destructor

  • Participants
  • Parent commits cfbcbf6
  • Branches default

Comments (0)

Files changed (4)

File src/grayflex.h

View file
 /**
  * \brief Generates global code book. 
  *
- * This code \em must be run before any Gray code related functions
- * are called.
+ * This function is called automatically when the shared library is
+ * loaded.
  *
  * \warning Not thread safe!
  */
 /**
  * Frees memory from the global code book.
  *
+ * This function is called automatically when the shared library is
+ * unloaded.
+ *
  * \warning Not thread safe!
  */
 

File src/misc.c

View file
 mm_block m4ri_mmc_cache[M4RI_MMC_NBLOCKS];
 
 void m4ri_die(char *errormessage, ...) {
-  /*This function prints the error message and raises SIGABRT.*/
-
   va_list lst;
   va_start(lst, errormessage);
   vfprintf(stderr, errormessage, lst);
 
 
 void *m4ri_mm_calloc( int count, int size ) {
-  /* this function calls calloc with the given inputs, 
-     but dies with an error message if a NULL is returned */
-
 #ifdef HAVE_MM_MALLOC
   void *newthing = _mm_malloc(count*size, 16);
 #else
   }
 #ifdef HAVE_MM_MALLOC
   char *b = (char*)newthing;
-/*   int i; */
-/*   for(i=0; i< count*size; i++) { */
-/*     b[i] = 0; */
-/*   } */
   memset(b, 0, count*size);
 #endif
   return newthing;
   }
 }
 
-#if defined(__GNUC__)
+#ifdef __GNUC__
 void __attribute__ ((constructor)) m4ri_init()
 #else
 void m4ri_init()
 {
   m4ri_build_all_codes();
 }
-#if defined(__SUNCC__)
+#ifdef __SUNCC__
 #pragma init(m4ri_init)
 #endif
 
-#if defined(__GNUC__)
+#ifdef __GNUC__
 void __attribute__ ((destructor)) m4ri_fini()
 #else
 void m4ri_fini()
   m4ri_mmc_cleanup();
   m4ri_destroy_all_codes();
 }
-#if defined(__SUNCC__)
+#ifdef __SUNCC__
 #pragma fini(m4ri_fini)
 #endif
+
+#ifdef _MSC_VER
+BOOL WINAPI DllMain(
+                    HINSTANCE hinstDLL,  // handle to DLL module
+                    DWORD fdwReason,     // reason for calling function
+                    LPVOID lpReserved )  // reserved
+{
+    // Perform actions based on the reason for calling.
+  switch( fdwReason ) 
+    { 
+    case DLL_PROCESS_ATTACH:
+      m4ri_build_all_codes();
+       break;
+      
+    case DLL_THREAD_ATTACH:
+      // Do thread-specific initialization.
+      break;
+      
+    case DLL_THREAD_DETACH:
+      // Do thread-specific cleanup.
+      break;
+      
+    case DLL_PROCESS_DETACH:
+      m4ri_mmc_cleanup();
+      m4ri_destroy_all_codes();
+      break;
+    }
+  return TRUE;  // Successful DLL_PROCESS_ATTACH.
+}
+#endif

File src/misc.h

View file
  * Allocate size zeroes bytes.
  *
  * \param size Number of bytes.
+ *
+ * \warning Not thread safe.
  */
 
 static inline void *m4ri_mmc_calloc(size_t size, size_t count) {
  *
  * \param condemned Pointer to memory.
  * \param size Number of bytes.
+ *
+ * \warning Not thread safe.
  */
 
 static inline void m4ri_mmc_free(void *condemned, size_t size) {
 
 /**
  * Cleans up the cache.
+ *
+ * This function is called automatically when the shared library is
+ * loaded.
+ *
+ * \warning Not thread safe.
  */
 
 static inline void m4ri_mmc_cleanup() {

File src/packedmatrix.c

View file
   packedmatrix *newmatrix;
   size_t i;
 
+#ifdef HAVE_OPENMP
+#pragma omp critical
+{
+#endif
   newmatrix=(packedmatrix *)m4ri_mmc_malloc(sizeof(packedmatrix));
+#ifdef HAVE_OPENMP
+ }
+#endif
+
   newmatrix->width=DIV_CEIL(c,RADIX);
 
 #ifdef HAVE_SSE2
   newmatrix->ncols=c;
   newmatrix->nrows=r;
   newmatrix->offset = 0;
+#ifdef HAVE_OPENMP
+#pragma omp critical
+{
+#endif
   newmatrix->values=(word *)m4ri_mmc_calloc( (newmatrix->width)*r, sizeof(word) );
+#ifdef HAVE_OPENMP
+ }
+#endif
 
+#ifdef HAVE_OPENMP
+#pragma omp critical
+{
+#endif
   newmatrix->rowswap=(size_t *)m4ri_mmc_malloc( r * sizeof(size_t) );
+#ifdef HAVE_OPENMP
+ }
+#endif
 
   /* 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_mmc_malloc(sizeof(packedmatrix));
+  packedmatrix *window;
+#ifdef HAVE_OPENMP
+#pragma omp critical
+{
+#endif
+  window = (packedmatrix *)m4ri_mmc_malloc(sizeof(packedmatrix));
+#ifdef HAVE_OPENMP
+}
+#endif
   nrows = MIN(highr - lowr, m->nrows - lowr);
   ncols = highc - lowc;
   
   
   window->values = m->values;
 
+#ifdef HAVE_OPENMP
+#pragma omp critical
+{
+#endif
   window->rowswap = (size_t *)m4ri_mmc_malloc( nrows * sizeof(size_t));
+#ifdef HAVE_OPENMP
+}
+#endif
   for(i=0; i<nrows; i++) {
     window->rowswap[i] = m->rowswap[lowr + i] + offset;
   }
 }
 
 void mzd_free( packedmatrix *condemned) {
+#ifdef HAVE_OPENMP
+#pragma omp critical
+{
+#endif
   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));
+#ifdef HAVE_OPENMP
+}
+#endif
 }
 
 void mzd_free_window( packedmatrix *condemned) {
+#ifdef HAVE_OPENMP
+#pragma omp critical
+{
+#endif
   m4ri_mmc_free(condemned->rowswap, condemned->nrows * sizeof(size_t));
   m4ri_mmc_free(condemned, sizeof(packedmatrix));
+#ifdef HAVE_OPENMP
+}
+#endif
 }
 
 void mzd_free_permutation_window (permutation* condemned){