source: npl/mediabox/lcdproc_edwin/src/clients/lcdproc/mem.c @ c5c522c

gcc484ntopperl-5.22
Last change on this file since c5c522c was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 12.1 KB
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <string.h>
4#ifdef IRIX
5#include <strings.h>
6#endif
7#include <unistd.h>
8#include <fcntl.h>
9#include <dirent.h>
10
11#include "../../shared/sockets.h"
12#include "../../shared/LL.h"
13
14#include "main.h"
15#include "mode.h"
16#include "mem.h"
17
18struct meminfo { int total, cache, buffers, free, shared; };
19
20int meminfo_fd = 0;
21
22static void get_mem_info(struct meminfo *result);
23
24static void get_mem_info(struct meminfo *result)
25{
26//  int i, res; char *bufptr;
27
28  reread(meminfo_fd, "get_meminfo:");
29  result[0].total   = getentry("MemTotal:", buffer);
30  result[0].free    = getentry("MemFree:", buffer);
31  result[0].shared  = getentry("MemShared:", buffer);
32  result[0].buffers = getentry("Buffers:", buffer);
33  result[0].cache   = getentry("Cached:", buffer);
34  result[1].total   = getentry("SwapTotal:", buffer);
35  result[1].free    = getentry("SwapFree:", buffer);
36}
37
38
39int mem_init()
40{
41   if(!meminfo_fd)
42   {
43      meminfo_fd = open("/proc/meminfo",O_RDONLY);
44   }
45
46   return 0;
47}
48
49int mem_close()
50{
51   if(meminfo_fd)
52      meminfo_fd = open("/proc/meminfo",O_RDONLY);
53
54   meminfo_fd = 0;
55   
56   return 0;
57}
58
59
60/////////////////////////////////////////////////////////////////////////
61// Mem Screen displays info about memory and swap usage...
62//
63int mem_screen(int rep, int display)
64{
65  int n;
66  struct meminfo mem[2];
67  static int first = 1;
68  static int which_title=0;
69  float value;
70 
71  if(first)
72  {
73     first = 0;
74
75     sock_send_string(sock, "screen_add M\n");
76     sprintf(buffer, "screen_set M name {Memory & Swap: %s}\n", host);
77     sock_send_string(sock, buffer);
78
79     if(lcd_hgt >= 4)
80     {
81        sock_send_string(sock, "widget_add M title title\n");
82        sock_send_string(sock, "widget_set M title { MEM -==- SWAP}\n");
83        sock_send_string(sock, "widget_add M totl string\n");
84        sock_send_string(sock, "widget_add M used string\n");
85        sock_send_string(sock, "widget_set M totl 9 2 Totl\n");
86        sock_send_string(sock, "widget_set M used 9 3 Free\n");
87        sock_send_string(sock, "widget_add M EF string\n");
88        sock_send_string(sock, "widget_set M EF 1 4 {E       F  E       F}\n");
89        sock_send_string(sock, "widget_add M memused string\n");
90        sock_send_string(sock, "widget_add M swapused string\n");
91        //sock_send_string(sock, "widget_set M memgauge 2 4 0\n");
92        //sock_send_string(sock, "widget_set M swapgauge 13 4 0\n");
93     }
94     else
95     {
96        sock_send_string(sock, "widget_add M m string\n");
97        sock_send_string(sock, "widget_add M s string\n");
98        if(lcd_wid >= 20)
99        {
100           sock_send_string(sock, "widget_set M m 1 1 {M     [       ]}\n");
101           sock_send_string(sock, "widget_set M s 1 2 {S     [       ]}\n");
102        }
103        else
104        {
105           sock_send_string(sock, "widget_set M m 1 1 {M     [   ]}\n");
106           sock_send_string(sock, "widget_set M s 1 2 {S     [   ]}\n");
107        }
108        sock_send_string(sock, "widget_add M mem% string\n");
109        sock_send_string(sock, "widget_add M swap% string\n");
110        sock_send_string(sock, "widget_set M mem% 16 1 { 0.0%}\n");
111        sock_send_string(sock, "widget_set M swap% 16 2 { 0.0%}\n");
112       
113        //sock_send_string(sock, "widget_set M memgauge 8 1 0\n");
114        //sock_send_string(sock, "widget_set M swapgauge 8 2 0\n");
115     }
116
117     sock_send_string(sock, "widget_add M memtotl string\n");
118     sock_send_string(sock, "widget_add M swaptotl string\n");
119     
120     sock_send_string(sock, "widget_add M memgauge hbar\n");
121     sock_send_string(sock, "widget_add M swapgauge hbar\n");
122     
123     //sock_send_string(sock, "\n");
124  }
125
126
127  get_mem_info(mem);
128
129 
130  // flip the title back and forth...
131  if(lcd_hgt >= 4)
132  {
133     if(which_title & 4)
134     {
135        sprintf(buffer, "widget_set M title {%s}\n", host);
136        sock_send_string(sock, buffer);
137     }
138     else sock_send_string(sock, "widget_set M title { MEM -==- SWAP}\n");
139     which_title = (which_title + 1)&7;
140
141
142     // Total memory
143     sprintf(tmp, "widget_set M memtotl 1 2 {%6dk}\n", mem[0].total);
144     if(display) sock_send_string(sock, tmp);
145
146     // Free memory (plus buffers and cache)
147     sprintf(tmp, "widget_set M memused 1 3 {%6dk}\n",
148             mem[0].free + mem[0].buffers + mem[0].cache);
149     if(display) sock_send_string(sock, tmp);
150
151     // Total swap
152     sprintf(tmp, "widget_set M swaptotl 14 2 {%6dk}\n", mem[1].total);
153     if(display) sock_send_string(sock, tmp);
154
155     // Free swap
156     sprintf(tmp, "widget_set M swapused 14 3 {%6dk}\n", mem[1].free);
157     if(display) sock_send_string(sock, tmp);
158
159
160     // Free memory graph
161     n = (int)(35.0 -
162               ((float)mem[0].free + (float)mem[0].buffers + (float)mem[0].cache)
163               / (float)mem[0].total
164               * 35.0);
165     sprintf(tmp, "widget_set M memgauge 2 4 %i\n", n);
166     if(display) sock_send_string(sock, tmp);
167     
168     // Free swap graph
169     n = (int)(35.0 -
170               (float)mem[1].free / (float)mem[1].total
171               * 35.0);
172     sprintf(tmp, "widget_set M swapgauge 13 4 %i\n", n);
173     if(display) sock_send_string(sock, tmp);
174  }
175  else
176  {
177     // Total memory
178     sprintf(tmp, "widget_set M memtotl 2 1 {%4dM}\n",
179             (int)(mem[0].total / 1024.0));
180     if(display) sock_send_string(sock, tmp);
181
182     // Total swap
183     sprintf(tmp, "widget_set M swaptotl 2 2 {%4dM}\n",
184             (int)(mem[1].total / 1024.0));
185     if(display) sock_send_string(sock, tmp);
186
187
188     // Free memory graph
189     value = ((float)mem[0].free + (float)mem[0].buffers + (float)mem[0].cache)
190        / (float)mem[0].total;
191     value = 1.0 - value;
192     n = (int)((lcd_cellwid * (float)(lcd_wid-13))*(value));
193     sprintf(tmp, "widget_set M memgauge 8 1 %i\n", n);
194     if(display) sock_send_string(sock, tmp);
195
196     value *= 100.0;
197     if (value >= 99.9) { sprintf(buffer, "100%%"); }
198     else { sprintf(buffer, "%4.1f%%", value); }
199     sprintf(tmp, "widget_set M mem%% %i 1 {%s}\n", lcd_wid-4, buffer);
200     if(display) sock_send_string(sock, tmp);
201
202     // Free swap graph
203     value = ((float)mem[1].free / (float)mem[1].total);
204     value = 1.0 - value;
205     n = (int)((lcd_cellwid * (float)(lcd_wid-13))*(value));
206     sprintf(tmp, "widget_set M swapgauge 8 2 %i\n", n);
207     if(display) sock_send_string(sock, tmp);
208
209     value *= 100.0;
210     if (value >= 99.9) { sprintf(buffer, "100%%"); }
211     else { sprintf(buffer, "%4.1f%%", value); }
212     sprintf(tmp, "widget_set M swap%% %i 2 {%s}\n", lcd_wid-4, buffer);
213     if(display) sock_send_string(sock, tmp);
214
215
216  }
217 
218
219
220  return 0;
221} // End mem_screen()
222
223
224
225typedef struct proc_mem_info
226{
227      char name[16];  // Is this really long enough?
228      // Size isn't used any more...
229      // Totl stores the "size" of the program now...
230      int size, totl;
231      int number;
232} proc_mem_info;
233
234
235static int sort_procs(void *a, void *b)
236{
237   proc_mem_info *one, *two;
238   
239   if(!a) return 0;
240   if(!b) return 0;
241
242   one = (proc_mem_info *)a;
243   two = (proc_mem_info *)b;
244
245   return (two->totl > one->totl);
246}
247
248   
249int mem_top_screen(int rep, int display)
250{
251   // Much of this code was ripped from "gmemusage"
252   char buf[128];   
253
254   DIR *proc;
255   FILE *StatusFile;
256   struct dirent * procdir;
257   
258   char procName[16];
259   int
260      procSize ,
261      procRSS ,
262      procData ,
263      procStk ,
264      procExe ;
265   const char
266      *NameLine = "Name:" ,
267      *VmSizeLine = "VmSize:" ,
268      *VmRSSLine = "VmRSS" ,
269      *VmDataLine = "VmData" ,
270      *VmStkLine = "VmStk" ,
271      *VmExeLine = "VmExe" ;
272   const int
273      NameLineLen = strlen ( NameLine ) ,
274      VmSizeLineLen = strlen ( VmSizeLine ) ,
275      VmDataLineLen = strlen ( VmDataLine ) ,
276      VmStkLineLen = strlen ( VmStkLine ) ,
277      VmExeLineLen = strlen ( VmExeLine ) ,
278      VmRSSLineLen = strlen ( VmRSSLine ) ;
279
280   
281   int threshold = 400, unique;
282   int i;
283   proc_mem_info *p;
284   LL * procs;
285   static int first = 1;
286
287   if(first)
288   {
289      first = 0;
290
291      sock_send_string(sock, "screen_add S\n");
292      sprintf(buffer, "screen_set S name {Top Memory Use: %s}\n", host);
293      sock_send_string(sock, buffer);
294      sock_send_string(sock, "widget_add S title title\n");
295      sprintf(buffer, "widget_set S title {TOP MEM: %s}\n", host);
296      sock_send_string(sock, buffer);
297      sock_send_string(sock, "widget_add S f frame\n");
298      if(lcd_hgt >= 4)
299         sock_send_string(sock, "widget_set S f 1 2 20 4 20 5 v 8\n");
300      else
301         sock_send_string(sock, "widget_set S f 1 2 20 2 20 5 v 16\n");
302      for(i=1; i<=5; i++)
303      {
304         sprintf(buffer, "widget_add S %i string -in f\n", i);
305         sock_send_string(sock, buffer);
306      }
307      sock_send_string(sock, "widget_set S 1 1 1 Checking...\n");
308   }
309   
310
311   procs = LL_new();
312   if(!procs)
313   {
314      fprintf(stderr, "mem_top_screen: Error allocating list\n");
315      return -1;
316   }
317
318   
319   if ( ( proc = opendir ( "/proc" ) ) == NULL )
320   {
321      fprintf ( stderr , "mem_top_screen: unable to open /proc" ) ;
322      perror ( "" ) ;
323      return -1;
324   }
325
326   while ( (procdir = readdir ( proc )) )
327   {
328      if ( !index ( "1234567890" , procdir -> d_name [0] ) )
329      {
330         continue ;
331      }
332      sprintf ( buf , "/proc/%s/status" , procdir -> d_name ) ;
333      if ( ( StatusFile = fopen ( buf , "r" ) ) == NULL )
334      {
335         // Not a serious error; process has finished before we could
336         // examine it:
337         //fprintf ( stderr , "mem_top_screen: cannot open %s for reading" ,
338         //          buf ) ;
339         //perror ( "" ) ;
340         continue ;
341      }
342      procRSS = procSize = procData = procStk = procExe = 0 ;
343      while ( fgets ( buf , sizeof ( buf ) , StatusFile ) )
344      {
345         if ( !strncmp ( buf , NameLine , NameLineLen ) )
346         {
347            /* Name: procName */
348            sscanf ( buf , "%*s %s" , procName ) ;
349         }
350         else if ( !strncmp ( buf , VmSizeLine , VmSizeLineLen ) )
351         {
352            /* VmSize: procSize kB */
353            sscanf ( buf , "%*s %d" , &procSize ) ;
354         }
355         else if ( !strncmp ( buf , VmRSSLine , VmRSSLineLen ) )
356         {
357            /* VmRSS: procRSS kB */
358            sscanf ( buf , "%*s %d" , &procRSS ) ;
359         }
360         else if ( !strncmp ( buf , VmDataLine , VmDataLineLen ) )
361         {
362            /* VmData: procData kB */
363            sscanf ( buf , "%*s %d" , &procData ) ;
364         }
365         else if ( !strncmp ( buf , VmStkLine , VmStkLineLen ) )
366         {
367            /* VmStk: procStk kB */
368            sscanf ( buf , "%*s %d" , &procStk ) ;
369         }
370         else if ( !strncmp ( buf , VmExeLine , VmExeLineLen ) )
371         {
372            /* VmExe: procExe kB */
373            sscanf ( buf , "%*s %d" , &procExe ) ;
374         }
375      }
376      fclose ( StatusFile ) ;
377      if(procSize > threshold)
378      {
379         // Figure out if it's sharing any memory...
380         unique = 1;
381         LL_Rewind(procs);
382         do {
383            p = LL_Get(procs);
384            if(p)
385            {
386               if(0 == strcmp(p->name, procName))
387               {
388                  unique = 0;
389                  p->number ++;
390                  p->totl += procData + procStk + procExe;
391               }
392            }
393         } while(LL_Next(procs) == 0);
394
395         // If this is the first one by this name...
396         if(unique)
397         {
398            p = malloc(sizeof(proc_mem_info));
399            if(!p)
400            {
401               fprintf(stderr,
402                       "mem_top_screen: Error allocating process entry\n");
403               goto end;  // Ack!  I hate goto's!
404            }
405            strcpy(p->name, procName);
406            p->size = procSize;
407            p->totl = procData + procStk + procExe;
408            p->number = 1;
409            // TODO:  Check for errors here?
410            LL_Push(procs, (void *)p);
411         }
412      }
413         
414   }
415   closedir ( proc ) ;
416
417
418   // Now, print some info...
419   LL_Rewind(procs);
420   LL_Sort(procs, sort_procs);
421   LL_Rewind(procs);
422   for(i=1; i<=5; i++)
423   {
424      p = LL_Get(procs);
425      if(p)
426      {
427         //printf("Mem hog: %s: %ik\n", p->name, p->size);
428         if(p->number > 1)
429            sprintf(buffer, "widget_set S %i 1 %i {%i%6ik %s(%i)}\n", i, i, i,
430                    p->totl, p->name, p->number);
431         else
432            sprintf(buffer, "widget_set S %i 1 %i {%i%6ik %s}\n", i, i, i,
433                    p->totl, p->name);
434         if(display) sock_send_string(sock, buffer);
435      }
436      else
437      {
438         //printf("Mem hog: none?\n");
439         sprintf(buffer, "widget_set S %i 1 %i {}\n", i, i);
440         if(display) sock_send_string(sock, buffer);
441      }
442
443      LL_Next(procs);
444   }
445
446   
447   
448
449  end:   // Ack!  I hate using labels! 
450   // Now clean it all up...
451   LL_Rewind(procs);
452   do {
453      p = (proc_mem_info *)LL_Get(procs);
454      if(p)
455      {
456         //printf("Proc: %6ik %s\n", p->size, p->name);
457         free(p);
458      }
459   } while(LL_Next(procs) == 0);
460   LL_Destroy(procs);
461
462
463   return 0;
464   
465} // End mem_top_screen()
466
Note: See TracBrowser for help on using the repository browser.