+#ifndef WIN32
+#include <sys/sysinfo.h>
+#endif
+
+//================================================================================
+/*!
+ * \brief Raise an exception if free memory (ram+swap) too low
+ * \param doNotRaise - if true, suppres exception, just return free memory size
+ * \retval int - amount of available memory in MB or negative number in failure case
+ */
+//================================================================================
+
+int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
+{
+#ifndef WIN32
+ struct sysinfo si;
+ int err = sysinfo( &si );
+ if ( err )
+ return -1;
+
+ static int limit = -1;
+ if ( limit < 0 ) {
+ int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
+ if (status >= 0 ) {
+ limit = WEXITSTATUS(status);
+ }
+ if ( limit < 20 )
+ limit = 20;
+ else
+ limit = int( limit * 1.5 );
+#ifdef _DEBUG_
+ cout << "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" << endl;
+#endif
+ }
+
+ const unsigned long Mbyte = 1024 * 1024;
+ // compute separately to avoid overflow
+ int freeMb =
+ ( si.freeram * si.mem_unit ) / Mbyte +
+ ( si.freeswap * si.mem_unit ) / Mbyte;
+
+ if ( freeMb > limit )
+ return freeMb - limit;
+
+ if ( doNotRaise )
+ return 0;
+#ifdef _DEBUG_
+ cout<<"SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" << endl;
+#endif
+ throw std::bad_alloc();
+#else
+ return -1;
+#endif
+}
+