Anpassung des E17 Mem Moduls

kashee Opeiah

FreeBSD rockz
Hallo,
ich habe mir vorgenommen den Enlightenment Port mal zu aktualisieren.
Dazu wollte ich auch einige Module wieder lauffähig machen.
Das Mem Modul, welche den Speicherverbrauch anzeigen soll, enthält schon eine Anpassung an FreeBSD. Leider werden die Zahlen nicht mehr korrekt angezeigt sobald man mehr als 2048 MB Arbeitsspeicher hat. Die Zahlen werden bei als Negative Werte angezeigt. Das bedeutet für mich das der Zahlenbereich der Variable nicht ausreichend ist.

Meine C Kenntnisse, sind jedoch nur soweit das ich Grundlegende Sachen erkennen. Funktionen, Variablen ...
Jetzt wäre meine Frage ob sich ein paar Leute finden würden, die sich für eine Anpassung finden würden.

Bei Mem wäre es die Anpassung der Dateitypen und eventuell den Aufruf von Sysctl anzupassen. Für mein Verständniss ruft die Funktion

Code:
static int
_mem_cb_check (void *data)
{
  Instance *inst;
  Edje_Message_Float msg;
  int real, swap, total_real, total_swap;
  char real_str[100];
  char swap_str[100];

  inst = data;
  _mem_get_values (inst->ci, &real, &swap, &total_real, &total_swap);

  if (!inst->ci->show_percent)
    {
      snprintf (real_str, sizeof (real_str), "Real: %d/%d MB", (real / 1024),
		(total_real / 1024));
      if ( total_swap ) { 
          snprintf (swap_str, sizeof (swap_str), "Swap: %d/%d MB", (swap / 1024),
            (total_swap / 1024));
      }
    }
  else
    {
      double tr;

      tr = (((double) real / (double) total_real) * 100);
      snprintf (real_str, sizeof (real_str), "Real: %1.2f%%", tr);
      if ( total_swap ) { 
          tr = (((double) swap / (double) total_swap) * 100);
          snprintf (swap_str, sizeof (swap_str), "Swap: %1.2f%%", tr);
      }
    }
  edje_object_part_text_set (inst->mem_obj, "real_label", real_str);
  if ( total_swap ) { 
      edje_object_part_text_set (inst->mem_obj, "swap_label", swap_str);
  } else {
      edje_object_part_text_set (inst->mem_obj, "swap_label", "");
  }

  double tr = ((double) real / (double) total_real);
  msg.val = tr;
  edje_object_message_send (inst->mem_obj, EDJE_MESSAGE_FLOAT, 1, &msg);

  if ( total_swap ) { 
      double ts = ((double) swap / (double) total_swap);
      msg.val = ts;
      edje_object_message_send (inst->mem_obj, EDJE_MESSAGE_FLOAT, 2, &msg);
  }

  return 1;
}
aus e_mod_main.c

die Funktion _mem_get_values aus mach_freebsd.c aus
Code:
#include <e.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <err.h>

#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/user.h>

#include "e_mod_main.h"

[COLOR="#ff0000"]#define GETSYSCTL(name, var)    getsysctl(name, &(var), sizeof (var))[/COLOR]

static int
getsysctl (char *name, void *ptr, [COLOR="#ff0000"]size_t len[/COLOR])
{
  [COLOR="#ff0000"]size_t nlen = len[/COLOR];
  if (sysctlbyname (name, ptr, &nlen, NULL, 0) == -1)
    {
      return (1);
    }

  [COLOR="#ff0000"]if (nlen != len)[/COLOR]
    {
      return (1);
    }

  return (0);
}

static int
swapinfo (int *total, int *used)
{
  int pagesize = getpagesize ();
  [COLOR="#ff0000"]size_t mibsize[/COLOR], size;
  struct xswdev xsw;
  int mib[16], n;
  int tmp_total, tmp_used;

  *total = 0;
  *used = 0;

  mibsize = sizeof mib / sizeof mib[0];
  if (sysctlnametomib ("vm.swap_info", mib, &mibsize) == -1)
    {
      warn ("sysctlnametomib()");
      return 1;
    }

  for (n = 0;; n++)
    {
      mib[mibsize] = n;
      size = sizeof xsw;
      if (sysctl (mib, mibsize + 1, &xsw, &size, NULL, 0) == -1)
	break;

      if (xsw.xsw_version != XSWDEV_VERSION)
	{
	  warnx ("xswdev version mismatch");
	  return 1;
	}

      tmp_total = (long long) xsw.xsw_nblks * pagesize;
      tmp_used = (long long) xsw.xsw_used * pagesize;
      *total += tmp_total;
      *used += tmp_used;
    }
  if (errno != ENOENT)
    warn ("sysctl()");

  return 0;
}

void
_mem_get_values (ci, phys_used, sw_used, phys_total, sw_total)
     Config_Item *ci;
     int *phys_used;
     int *sw_used;
     int *phys_total;
     int *sw_total;
{
  int total_pages, inactive_pages, free_pages;

  int pagesize = getpagesize ();

  if (GETSYSCTL ("vm.stats.vm.v_page_count", total_pages))
    {
      warnx ("can't read sysctl \"vm.stats.vm.v_page_count\"");
      return;
    }

  if (GETSYSCTL ("vm.stats.vm.v_free_count", free_pages))
    {
      warnx ("can't read sysctl \"vm.stats.vm.v_free_count\"");
      return;
    }

  if (GETSYSCTL ("vm.stats.vm.v_inactive_count", inactive_pages))
    {
      warnx ("can't read sysctl \"vm.stats.vm.v_inactive_count\"");
      return;
    }

  *phys_total = (total_pages * pagesize) [COLOR="Red"]>> 10[/COLOR];
  *phys_used = ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;

  if ((swapinfo (sw_total, sw_used)) != 0)
    {
      *sw_total = 0;
      *sw_used = 0;
    }
}

Die Sachen in Rot sind mir dabei total unklar.

Ich würde auch für den gesammten Physikalisch Speicher "hw.physmem" nehmen. Jedoch muss laut: http://forums.freebsd.org/archive/index.php/t-1102.html da die Dateitypen auf int64_t geändert werden. Bloß ist mir das viel zu hoch :zitter:

Würde mich jemand Unterstützen?

Mfg Kashee Opeiah
 
Eigentlich sollte size_t schon passen, dachte ich zumindest. Wenn ich mich erinnere ist size_t ein unsigned integer mit Pointer-Größe, also genau das, was man braucht.
 
Hi Kamikaze,
der Fehler der im Anhang zusehen ist kommt bei mir, auf 5 verschiedenen PCs probiert. Auch ist es so, das sobald der momentan benötigte Speicher über 2030 MB geht zeigt die anzeige nur noch einen - Wert.

Bei mir ist vm.stats.vm.v_page_count = 876506
pagesize = 4096
totalmemory = 876506*4096 = 3590168576
Der Datentyp ist ja int, und der ist doch in C bis 2.147.483.647? ein uint würde gehen, hat aber seine Grenzen auch schnell erreicht :-(
 

Anhänge

  • mem.webp
    mem.webp
    2,1 KB · Aufrufe: 270
Zurück
Oben