0022627: Change OCCT memory management defaults
[occt.git] / src / OSD / OSD.cxx
1
2 #include <OSD.ixx>
3
4 #include <stdio.h>
5 #include <math.h>
6 #if HAVE_IEEEFP_H
7 # include <ieeefp.h>
8 #endif
9 #if !defined(HAVE_FINITE) && defined(isfinite)
10 # define finite isfinite
11 #endif
12
13 static Standard_Integer DecimalPoint = 0 ;
14
15 static void GetDecimalPoint() {
16   float F1 = (float ) 1.1 ;
17   char str[5] ;
18
19   sprintf(str,"%.1f",F1) ;
20                              //  printf("%s\n",str) ;
21   DecimalPoint = str[1] ;
22 }
23
24 // Convert Real to CString in format e with 16 significant digits.
25 // The decimal point character is always a period.
26 // The conversion is independant from current locale database
27
28 Standard_Boolean OSD::RealToCString(const Standard_Real aReal,
29                                     Standard_PCharacter& aString)
30 {
31   char *p, *q ;
32   
33   // Get the local decimal point character 
34
35   if (!DecimalPoint)
36     GetDecimalPoint() ;
37
38   // Substitute it
39
40 //  if (sprintf(aString,"%.15le",aReal)  <= 0)
41   if (sprintf(aString,"%.17e",aReal)  <= 0) //BUC60808
42     return Standard_False ;
43
44   if ((p = strchr(aString,DecimalPoint)))
45     *p = '.' ;
46
47   // Suppress "e+00" and unsignificant 0's 
48
49   if ((p = strchr(aString,'e'))) {
50     if (!strcmp(p,"e+00"))
51       *p = 0 ;
52     for (q = p-1 ; *q == '0' ; q--) ;
53     if (q != p-1) {
54       if (*q != '.') q++ ;
55       while (*p)
56         *q++ = *p++ ;
57       *q = 0 ;
58     }
59   }
60   return Standard_True ;
61 }
62
63 // Make the RealToCString reciprocal conversion.
64
65 Standard_Boolean OSD::CStringToReal(const Standard_CString aString,
66                                     Standard_Real& aReal)
67 {
68   const char *p;
69   char *endptr ;
70  
71
72   // Get the local decimal point character 
73
74   if (!DecimalPoint)
75     GetDecimalPoint() ;
76
77   const char *str = aString;
78   char buff[1024];  
79   //if((p = strchr(aString,'.')))
80   if(DecimalPoint != '.' && (p = strchr(aString,'.'))&& ((p-aString) < 1000) )
81   {
82     strncpy(buff, aString, 1000);
83     buff[p-aString] = DecimalPoint ;
84     str = buff;
85   }
86   aReal = strtod(str,&endptr) ;
87   if (*endptr)
88     return Standard_False ;
89   return Standard_True;
90 }
91
92 //=======================================================================
93 //function : OSDSecSleep
94 //purpose  : Cause the process to sleep during a amount of seconds 
95 //=======================================================================
96
97 #ifdef WNT
98 # include <Windows.h>
99 #if !defined(__CYGWIN32__) && !defined(__MINGW32__)
100 # include <Mapiwin.h>
101 #endif
102 # define _DEXPLEN                    11
103 # define _IEEE                        1
104 # define DMAXEXP                     ((1 << _DEXPLEN - 1) - 1 + _IEEE)
105 # define finite                      _finite
106 # define SLEEP(NSEC)                 Sleep(1000*(NSEC))
107 #else
108 # define SLEEP(NSEC)                 sleep(NSEC)
109 #endif
110
111 #ifdef HAVE_VALUES_H
112 //# include <values.h>
113 #endif
114
115 #ifdef HAVE_UNISTD_H
116 # include <unistd.h>
117 #endif
118
119 void OSD::SecSleep(const Standard_Integer aDelay)
120 {
121   SLEEP(aDelay);
122 }
123
124 //=======================================================================
125 //function : MilliSecSleep
126 //purpose  : Cause the process to sleep during a amount of milliseconds  
127 //=======================================================================
128
129 #ifdef WNT
130
131 void OSD::MilliSecSleep(const Standard_Integer aDelay)
132 {
133   Sleep(aDelay) ;
134 }
135
136 #else
137
138 #ifdef HAVE_SYS_TIME_H
139 # include <sys/time.h>
140 #endif
141
142 void OSD::MilliSecSleep(const Standard_Integer aDelay)
143 {
144   int fdn ;
145   struct timeval timeout ;
146
147   timeout.tv_sec = aDelay / 1000 ;
148   timeout.tv_usec = (aDelay % 1000) * 1000 ;
149
150   fdn = select(0,NULL,NULL,NULL,&timeout) ;
151 }
152
153 #endif
154
155 //=======================================================================
156 //function : IsDivisible
157 //purpose  : 
158 //=======================================================================
159
160 Standard_Boolean OSD::IsDivisible(const Standard_Real theDividend,const Standard_Real theDivisor)
161 {
162   if ( theDivisor == 0. || ! finite(theDividend) ) return Standard_False;
163   //
164   // you may divide by infinity
165   //
166   if (! finite(theDivisor)) return Standard_True;
167 #ifdef DEB
168 //   Standard_Integer aExp1,  aExp2;
169 //   Standard_Real aMant1 = frexp(theDividend, &aExp1);
170 //   Standard_Real aMant2 = frexp(theDivisor, &aExp2);
171 #endif
172 // Code de :KL:dev:ref :
173 //  return ((aExp1-aExp2 < DMAXEXP) ||        // exponent of the result
174 //        (aExp1-aExp2 == DMAXEXP && aMant1 < aMant2)) ;
175
176 // Code de :KAS:C30 :
177   return Standard_True;
178
179
180 // this is unacceptable return for Linux because of (temporary?) undefined  aExp1 and aExp2.
181 // Testing both over and underflow should be (:KL:dev ) :
182
183 //  return ((aExp1-aExp2 < DMAXEXP) && (aExp1-aExp2 > DMINEXP) ||
184 //        (aExp1-aExp2 == DMAXEXP && aMant1 < aMant2) ||
185 //        (aExp1-aExp2 == DMINEXP && aMant1 > aMant2)) ;
186 }
187
188 //=======================================================================
189 //function : GetExponent
190 //purpose  : 
191 //=======================================================================
192
193 //Standard_Integer OSD::GetExponent(const Standard_Real aReal)
194 Standard_Integer OSD::GetExponent(const Standard_Real )
195 {
196 // Code de :KAS:C30 :
197
198   cout << "Function OSD::GetExponent() not yet implemented." << endl;
199   return 0 ;
200
201 // Code de :KL:dev:ref :
202
203 //  Standard_Integer Exp ;
204
205 ////  Standard_Real Mant = frexp(aReal, &Exp) ;
206 //  frexp(aReal, &Exp) ;
207 //  return Exp ;
208 }
209
210 //=======================================================================
211 //function : GetMantissa
212 //purpose  : 
213 //=======================================================================
214
215 //Standard_Real OSD::GetMantissa(const Standard_Real aReal)
216 Standard_Real OSD::GetMantissa(const Standard_Real )
217 {
218 // Code de :KAS:C30 :
219   cout << "Function OSD::GetMantissa() not yet implemented." << endl;
220   return 0 ;
221
222 // Code de :KL:dev:ref :
223
224 //  Standard_Integer Exp ;
225 //  return frexp(aReal, &Exp) ;
226 }
227
228 //=======================================================================
229 // Code de :KAS:C30 :
230 //=======================================================================
231 Standard_Integer OSD::AvailableMemory()
232 {
233   cout << "Function OSD::AvailableMemory() not yet implemented." << endl;
234   return 0 ;
235 }
236
237 // Code de :KL:dev:ref ??????????????? :
238 #if 0
239 //=======================================================================
240 //function : AvailableMemory
241 //purpose  : 
242 //=======================================================================
243 #include <stdlib.h>
244 #include <stdio.h>
245 #include <malloc.h>
246
247 # if defined(SUN) || defined(__sun) || defined(SOLARIS)
248 #  define SIZE_MAX  0x7fffffff
249 # elif defined(__osf__)  || defined(DECOSF1)        
250 #  define SIZE_MAX  0x10000000000 
251 # elif defined(WNT)
252 #  define SIZE_MAX 0x7ffdefff
253 # else
254 #  define SIZE_MAX  0xffffffff
255 # endif
256
257 Standard_Integer OSD::AvailableMemory()
258 {
259   size_t min = 1024 ;
260   size_t max = SIZE_MAX ;
261   size_t middle = SIZE_MAX ;
262   void * addr ;
263   int nballoc = 0 ;
264   int nbfree = 0 ;
265
266   while (min + 1024 < max) {
267     if ((addr =  malloc (middle))== (void *)-1) {
268       perror("OSD::AvailableMemory()_malloc error :") ;
269       return 0 ;
270     }
271     nballoc++ ;
272     if (addr == 0)
273       max = middle ;
274     else {
275       free(addr) ;
276       nbfree++ ;
277       min = middle ;
278     }
279     middle = min + ((max - min ) >> 6) * 63 ;
280   }
281   return min >> 10 ;
282 }
283
284 #endif