Better getfreememory on linux
[scilab.git] / scilab / modules / core / src / c / getmemory.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2005 - INRIA - Allan CORNET
4  * 
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at    
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 /* References
14 @sa http://nixdoc.net/man-pages/Tru64/man2/getsysinfo.2.html
15 @sa http://www.opensource.apple.com/darwinsource/projects/other/gccfast-1621.1/libiberty/physmem.c
16 @sa http://lists.gnu.org/archive/html/bug-gnulib/2003-08/msg00102.html
17 */
18 #include "getmemory.h"
19 #include <stdio.h>
20
21 #define kooctet 1024
22
23 int getfreememory()
24 {
25
26 #if defined(_MSC_VER)
27   {
28     MEMORYSTATUS stat;
29     GlobalMemoryStatus (&stat);
30     return (int)(stat.dwAvailPhys/kooctet);
31   }
32 #elif defined(hpux)
33  {
34    struct pst_static pst;
35   /*        pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0);
36         memorysizeKO=(pst.psd_free)/kooctet;*/
37   return 0;
38  }
39 #elif defined(__APPLE__) 
40       {
41         vm_statistics_data_t page_info;
42         vm_size_t pagesize;
43         mach_msg_type_number_t count;
44         kern_return_t kret;
45     
46         pagesize = 0;
47         kret = host_page_size (mach_host_self(), &pagesize);
48         count = HOST_VM_INFO_COUNT;
49     
50         kret = host_statistics (mach_host_self(), HOST_VM_INFO,(host_info_t)&page_info, &count);
51         return page_info.free_count*pagesize / 1024;
52       }
53 #elif HAVE_TABLE && defined TBL_VMSTATS
54    { /* This works on Tru64 UNIX V4/5.  */
55      struct tbl_vmstats vmstats;
56
57      if (table (TBL_VMSTATS, 0, &vmstats, 1, sizeof (vmstats)) == 1)
58        {
59          double pages = vmstats.free_count;
60          double pagesize = vmstats.pagesize;
61
62          if (0 <= pages && 0 <= pagesize)
63            return pages * pagesize;
64          else
65            return 0;
66        }
67    }
68 #elif defined(__linux__)
69   {
70     char field[9]  = {0};
71     long long data =  0;
72     char unit[4]   = {0};
73     
74     long long free    = -1,
75               buffers = -1,
76               cached  = -1;
77     
78     FILE *fp = fopen("/proc/meminfo", "r");
79     if(fp != NULL)
80     {
81       /* Read Cached, Buffers and MemFree from /proc/meminfo */
82       while(fscanf(fp, "%8s %lld %3s\n", field, &data, unit) != EOF)
83       {
84         if(!strncmp("MemFree:", field, 8))
85           free = data;
86         else if(!strncmp("Buffers:", field, 8))
87           buffers = data;
88         else if(!strncmp("Cached:", field, 8))
89           cached = data;
90       }
91       fclose(fp);
92       
93       /* Read successful, convert unit and return the result */
94       if(buffers >= 0 && cached >= 0 && free >= 0)
95       {
96         free += cached + buffers;
97         switch(unit[0])
98         {
99           case 'g':
100           case 'G':
101             free *= kooctet;
102           case 'm':
103           case 'M':
104             free *= kooctet;
105             break;
106           case 'o':
107           case 'O':
108             free /= kooctet;
109         }
110         return (int)free;
111       }
112     }
113     
114     /* Strange, /proc not mounted ? new and unknown format ?
115        fall back to inaccurate sysconf() */
116     return (sysconf(_SC_AVPHYS_PAGES)*sysconf(_SC_PAGESIZE))/kooctet;
117   }
118 #else
119   /* BSD, Solaris and others assumed*/
120   return (sysconf(_SC_AVPHYS_PAGES)*sysconf(_SC_PAGESIZE))/kooctet;
121 #endif
122 }
123 /*--------------------------------------------------------------------------*/ 
124 int getmemorysize()
125 {
126 #if defined(_MSC_VER)
127   {
128     MEMORYSTATUS stat;
129     GlobalMemoryStatus (&stat);
130     return (int)(stat.dwTotalPhys/kooctet);
131   }
132 #elif defined(hpux)
133   {
134     struct pst_static pst;
135     pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0);
136     return (int)((pst.physical_memory)/kooctet);
137   }
138 #elif defined(__APPLE__) 
139   {
140     size_t len;
141     int total;
142     int mib[2];
143
144     mib[0] = CTL_HW;
145     mib[1] = HW_PHYSMEM;
146     len = sizeof (total);
147  
148     sysctl(mib, 2, &total, &len, NULL, 0);
149     return  total/1024;
150   }
151 #elif HAVE_GETSYSINFO && defined GSI_PHYSMEM
152    { /* This works on Tru64 UNIX V4/5.  */
153      int physmem;
154
155      if (getsysinfo (GSI_PHYSMEM, (caddr_t) &physmem, sizeof (physmem),
156                     NULL, NULL, NULL) == 1)
157        {
158         double kbytes = physmem;
159
160         if (0 <= kbytes)
161           return kbytes * 1024.0;
162         else
163           return 0;
164        }
165    }
166 #else
167   /* Linux ,Solaris and others */
168   return (sysconf(_SC_PHYS_PAGES)*sysconf(_SC_PAGESIZE))/kooctet;
169 #endif
170 }
171 /*--------------------------------------------------------------------------*/