From 9d5c01d6b1be65933398f936acb6ce10030cce3a Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Wed, 30 May 2007 22:12:41 -0400
Subject: [PATCH] Restore FPU Control Word after mesh generation.

---
 src/predicates.cpp | 11 +++++++++++
 src/tetgen.cpp     |  1 +
 src/tetgen.h       |  1 +
 src/triangle.c     | 24 +++++++++++++++++++-----
 4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/src/predicates.cpp b/src/predicates.cpp
index ea9bf49..af15ce1 100644
--- a/src/predicates.cpp
+++ b/src/predicates.cpp
@@ -664,6 +664,8 @@ float uniformfloatrand()
 /*                                                                           */
 /*****************************************************************************/
 
+static int previous_cword;
+
 REAL exactinit()
 {
   REAL half;
@@ -680,7 +682,9 @@ REAL exactinit()
   _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */
 #endif /* not SINGLE */
 #endif /* CPU86 */
+
 #ifdef LINUX
+  _FPU_GETCW(previous_cword);
 #ifdef SINGLE
   /*  cword = 4223; */
   cword = 4210;                 /* set FPU control word for single precision */
@@ -729,6 +733,13 @@ REAL exactinit()
   return epsilon; /* Added by H. Si 30 Juli, 2004. */
 }
 
+void exactdeinit()
+{
+#ifdef LINUX
+  _FPU_SETCW(previous_cword);
+#endif /* LINUX */
+}
+
 /*****************************************************************************/
 /*                                                                           */
 /*  grow_expansion()   Add a scalar to an expansion.                         */
diff --git a/src/tetgen.cpp b/src/tetgen.cpp
index 1b0c805..15c7870 100644
--- a/src/tetgen.cpp
+++ b/src/tetgen.cpp
@@ -31526,6 +31526,7 @@ void tetrahedralize(tetgenbehavior *b, tetgenio *in, tetgenio *out,
   if (bgmesh) {
     delete m.bgm;
   }
+  exactdeinit();
 }
 
 #ifndef TETLIBRARY
diff --git a/src/tetgen.h b/src/tetgen.h
index d0aa42e..9e00656 100644
--- a/src/tetgen.h
+++ b/src/tetgen.h
@@ -539,6 +539,7 @@ class tetgenbehavior {
 ///////////////////////////////////////////////////////////////////////////////
 
 REAL exactinit();
+void exactdeinit();
 REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd);
 REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe);
 
diff --git a/src/triangle.c b/src/triangle.c
index 8ea99e7..5a0c349 100644
--- a/src/triangle.c
+++ b/src/triangle.c
@@ -266,6 +266,8 @@
 /*   Floating-Point Arithmetic and Fast Robust Geometric Predicates" (also   */
 /*   available as Section 6.6 of my dissertation).                           */
 
+void exactdeinit(void);
+
 /* #define CPU86 */
 /* #define LINUX */
 
@@ -316,7 +318,7 @@
 /*   compiler is smarter, feel free to replace the "int" with "void".        */
 /*   Not that it matters.                                                    */
 
-#define VOID int
+// #define VOID int
 
 /* Two constants for algorithms based on random sampling.  Both constants    */
 /*   have been chosen empirically to optimize their respective algorithms.   */
@@ -1353,7 +1355,7 @@ int minus1mod3[3] = {2, 0, 1};
 
 #ifdef EXTERNAL_TEST
 
-int triunsuitable();
+//int triunsuitable(void);
 
 #else /* not EXTERNAL_TEST */
 
@@ -3261,7 +3263,7 @@ void info()
 /*                                                                           */
 /*****************************************************************************/
 
-void internalerror()
+void internalerror(void)
 {
   printf("  Please report this bug to jrs@cs.berkeley.edu\n");
   printf("  Include the message above, your input data set, and the exact\n");
@@ -4637,6 +4639,7 @@ struct behavior *b;
     }
   }
 #endif /* not CDT_ONLY */
+  exactdeinit();
 }
 
 /**                                                                         **/
@@ -4880,7 +4883,9 @@ struct osub *newsubseg;
 /*                                                                           */
 /*****************************************************************************/
 
-void exactinit()
+static int previous_cword;
+
+void exactinit(void)
 {
   REAL half;
   REAL check, lastcheck;
@@ -4897,6 +4902,7 @@ void exactinit()
 #endif /* not SINGLE */
 #endif /* CPU86 */
 #ifdef LINUX
+  _FPU_GETCW(previous_cword);
 #ifdef SINGLE
   /*  cword = 4223; */
   cword = 4210;                 /* set FPU control word for single precision */
@@ -4939,6 +4945,14 @@ void exactinit()
   o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
 }
 
+void exactdeinit()
+{
+#ifdef LINUX
+  _FPU_SETCW(previous_cword);
+#endif /* LINUX */
+}
+
+
 /*****************************************************************************/
 /*                                                                           */
 /*  fast_expansion_sum_zeroelim()   Sum two expansions, eliminating zero     */
@@ -13200,7 +13214,7 @@ struct behavior *b;
 
 #ifndef CDT_ONLY
 
-void precisionerror()
+void precisionerror(void)
 {
   printf("Try increasing the area criterion and/or reducing the minimum\n");
   printf("  allowable angle so that tiny triangles are not created.\n");
-- 
GitLab