Determining free(available) memory in MV linux

HI
I'm a rookie in C programming and I'm working in Monta Vista Linux. I have to write a program that displays free memory. I have memtester(allready written by someone else) and now I have to type how much amount of memory tester will test and I want that memtester finds out himself how much of free memory is available in the system to test and tests it.

I tried by opening /proc/meminfo and locate the number of free memory, but when I would open a program to determine free memory free memory number would change probably and data wouldn't be real.
Please I need any suggestion of you experts how to determine amount of free memory that will be tested with program.
Have a nice Day

Matt

My first suggestion is: get a copy of the source for the free utility - it is part of coreutils for Linux.

Second - this is probably a difficult exercise for a beginner. Consider using
a call to free -m inside a system() call in C.

HI
If I compare numbers on what free -m displays or what is the number on meminfo, they are different
free -m
total used free shared buffers cached
Mem: 492 23 469 0 1 14
-/+ buffers/cache: 7 485
Swap: 0 0 0

meminfo:
total: used: free: shared: buffers: cached:
Mem: 516644864 25026560 491618304 0 1560576 15425536
Swap: 0 0 0
MemTotal: 504536 kB
MemFree: 480096 kB
MemShared: 0 kB
Buffers: 1524 kB
Cached: 15064 kB
SwapCached: 0 kB
Active: 5556 kB
Inactive: 12048 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 504536 kB
LowFree: 480096 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Committed_AS: 1156 kB
VmallocTotal: 491512 kB
VmallocUsed: 596 kB
VmallocChunk: 490916 kB

What if I would somehow get the number of free memory and store it somewhere. Then memtester reads the number from stored place and checks that much amount of memory that number(should be in MB) is writen in stored place. Please help
Have a nice Day

Matt

HI
Is maybe some function available something like getfreemem() or something that would display or..........
I don't know - I just have to have number of MB that is available on system and that is reachable from other program like a parameter to the second program that orders to memtester to check exactly that amount of memory.
Have a nice Day

Matt

example:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

double get_meminfo(void)
{
	double retval=0;
	char tmp[256]={0x0};
	/* note= add a path to meminfo like /usr/bin/meminfo 
	   to match where meminfo lives on your system */
	FILE *shellcommand=popen("meminfo","r");
	while(fgets(tmp,sizeof(tmp),shellcommand)!=NULL)
	{
		if(memcmp(tmp,"Mem:",4)==0)
		{
			int	wordcount=0;
			char *delimiter=" ";
			char *p=strtok(tmp,delimiter);
			while(*p)
			{
				wordcount++;
				if(wordcount==3) retval=atof(p);
			}
		}
	}
	pclose(shellcommand);
	return retval;
}

int	main(int argc, char	*argv[])
{
	double freemem=get_meminfo();
	
	printf("free memory=%f\n", freemem);
	return 0;
}

I've noticed that meminfo does not display real values - function free -m does. If I insert to memtester the same value that I got from free -m memtester works normally, but when I put only 1MB higher number memtester terminates - not enough memory(so that means the function in shell free -m displays real free memory data). Question now is how to enter the shell function from C to save and display data from free -m?
Have a nice Day

Matt

HI
I've tried your program but I have got premission denied:

sh: /proc/meminfo: Permission denied
free memory=0.000000

When you wrote the path "meminfo", I entered whole path "/proc/meminfo"
But that is not the question now as meminfo does not display real data.

Have a nice Day

Matt

I don't understand.

  1. find a way to get what you using the command line.
  2. copy the command that you like EXACTLY into the space between the quotes
popen(" put your command here ","r");

You will have to get the correct column, if you know shell script you can have your one command return just exactly what you need.

We don't know what you want, free reports free space in Kb, not individual bytes.
You Linux my behave differently - I don't know. You decide what suits you, then plug it in.

HI
Sorry, maybe I wrote hardly to understand what I want.
I need to receive data from function free -m(m is for Megabytes) of free memory on the system in MB(I just need the number). I need then that number to be like one parameter that memtester wants. So memtester can get somehow the number of free memory in MB and so it knows amount of memory to test. Now I have to manually insert number of tested ram or have manually change it in the txt file with included parameters, so I would like that program himself finds out the amount to test(and that is the max possible and the number of max possible free ram can be seen if you type free -m)
So I need to get somehow the number that free -m displays and memtester should read this number to know how many MB of ram to test.
I run memtester like this:
./memtester 890 1

So it runs memtester, the first number means how much ram and the second how many times should it be checked....
So every time I run memtester, memtester should look somewhere for the amount of free memory to test...
Have a nice Day

Matt

You can run memtester this way:

./memtester `free -om | grep 'Mem:' | awk '{print $4}'`  1

free -om | grep 'Mem:' | awk '{print $4}'` gets free memory in MB.

HI
You really are an expert it works if I do like you said
I just need to check what is wrong with my menu program because if I run memtester with this code from menu, the computer displays:
Pagesize is 4096
pagesizemask is 0xfffff000
bytes < pagesize -- memory argument too large?

This displayed code is from memtester
/*

  • memtester version 4
    *
  • Very simple but very effective user-space memory tester.
  • Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
  • Version 2 by Charles Cazabon <memtest@discworld.dyndns.org>
  • Version 3 not publicly released.
  • Version 4 rewrite:
  • Copyright (C) 2005 Charles Cazabon <memtest@discworld.dyndns.org>
  • Licensed under the terms of the GNU General Public License version 2 (only).
  • See the file COPYING for details.
    *
    */

#define __version__ "4.0.5"

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>

#include "types.h"
#include "sizes.h"
#include "tests.h"

#define EXIT_FAIL_NONSTARTER 0x01
#define EXIT_FAIL_ADDRESSLINES 0x02
#define EXIT_FAIL_OTHERTEST 0x04

struct test tests[] = {
{ "Random Value", test_random_value },
{ "Compare XOR", test_xor_comparison },
{ "Compare SUB", test_sub_comparison },
{ "Compare MUL", test_mul_comparison },
{ "Compare DIV",test_div_comparison },
{ "Compare OR", test_or_comparison },
{ "Compare AND", test_and_comparison },
{ "Sequential Increment", test_seqinc_comparison },
{ "Solid Bits", test_solidbits_comparison },
{ "Block Sequential", test_blockseq_comparison },
{ "Checkerboard", test_checkerboard_comparison },
{ "Bit Spread", test_bitspread_comparison },
{ "Bit Flip", test_bitflip_comparison },
{ "Walking Ones", test_walkbits1_comparison },
{ "Walking Zeroes", test_walkbits0_comparison },
{ NULL, NULL }
};

#ifdef _SC_VERSION
void check_posix_system(void) {
if (sysconf(_SC_VERSION) < 198808L) {
fprintf(stderr, "A POSIX system is required. Don't be surprised if "
"this craps out.\n");
fprintf(stderr, "_SC_VERSION is %lu\n", sysconf(_SC_VERSION));
}
}
#else
#define check_posix_system()
#endif

#ifdef _SC_PAGE_SIZE
int memtester_pagesize(void) {
int pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1) {
perror("get page size failed");
exit(EXIT_FAIL_NONSTARTER);
}
printf("pagesize is %ld\n", pagesize);
return pagesize;
}
#else
int memtester_pagesize(void) {
printf("sysconf(_SC_PAGE_SIZE) not supported; using pagesize of 8192\n");
return 8192;
}
#endif

int main(int argc, char **argv) {
ul loops, loop, i;
size_t pagesize, wantmb, wantbytes, wantbytes_orig, bufsize, halflen, count;
ptrdiff_t pagesizemask;
void volatile *buf, *aligned;
ulv *bufa, *bufb;
int do_mlock = 1, done_mem = 0;
int exit_code = 0;

printf\("memtester version " \_\_version__ " \(%d-bit\)\\n", UL_LEN\);
printf\("Copyright \(C\) 2005 Charles Cazabon.\\n"\);
printf\("Licensed under the GNU General Public License version 2 \(only\).\\n"\);
printf\("\\n"\);
check\_posix_system\(\);
pagesize = memtester_pagesize\(\);
pagesizemask = \(ptrdiff_t\) ~\(pagesize - 1\);
printf\("pagesizemask is 0x%tx\\n", pagesizemask\);

if \(argc &lt; 2\) \{
    fprintf\(stderr, "need memory argument, in MB\\n"\);
    exit\(EXIT\_FAIL_NONSTARTER\);
\}
wantmb = \(size_t\) strtoul\(argv[1], NULL, 0\);
wantbytes_orig = wantbytes = \(size_t\) \(wantmb &lt;&lt; 20\);
if \(wantbytes &lt; pagesize\) \{
    fprintf\(stderr, "bytes &lt; pagesize -- memory argument too large?\\n"\);
    exit\(EXIT\_FAIL_NONSTARTER\);
\}

if \(argc &lt; 3\) \{
    loops = 0;
\} else \{
    loops = strtoul\(argv[2], NULL, 0\);
\}

printf\("want %lluMB \(%llu bytes\)\\n", \(ull\) wantmb, \(ull\) wantbytes\);
buf = NULL;

while \(!done_mem\) \{
    while \(!buf && wantbytes\) \{
        buf = \(void volatile *\) malloc\(wantbytes\);
        if \(!buf\) wantbytes -= pagesize;
    \}
    bufsize = wantbytes;
    printf\("got  %lluMB \(%llu bytes\)", \(ull\) wantbytes &gt;&gt; 20,
        \(ull\) wantbytes\);
    fflush\(stdout\);
    if \(do_mlock\) \{
        printf\(", trying mlock ..."\);
        fflush\(stdout\);
        if \(\(size_t\) buf % pagesize\) \{
            /* printf\("aligning to page\\n"\); */
            aligned = \(void volatile *\) \(\(size_t\) buf & pagesizemask\);
            bufsize -= \(\(size_t\) aligned - \(size_t\) buf\);
        \} else \{
            aligned = buf;
        \}
        /* Try memlock */
        if \(mlock\(\(void *\) aligned, bufsize\) &lt; 0\) \{
            switch\(errno\) \{
                case ENOMEM:
                    printf\("too many pages, reducing...\\n"\);
                    free\(\(void *\) buf\);
                    buf = NULL;
                    wantbytes -= pagesize;
                    break;
                case EPERM:
                    printf\("insufficient permission.\\n"\);
                    printf\("Trying again, unlocked:\\n"\);
                    do_mlock = 0;
                    free\(\(void *\) buf\);
                    buf = NULL;
                    wantbytes = wantbytes_orig;
                    break;
                default:
                    printf\("failed for unknown reason.\\n"\);
                    do_mlock = 0;
                    done_mem = 1;
            \}
        \} else \{
            printf\("locked.\\n"\);
            done_mem = 1;
        \}
    \} else \{ 
        done_mem = 1;
        printf\("\\n"\); 
    \}
\}

if \(!do_mlock\) fprintf\(stderr, "Continuing with unlocked memory; testing "
    "will be slower and less reliable.\\n"\);

halflen = bufsize / 2;
count = halflen / sizeof\(ul\);
bufa = \(ulv *\) aligned;
bufb = \(ulv *\) \(\(size_t\) aligned \+ halflen\);

for\(loop=1; \(\(!loops\) || loop &lt;= loops\); loop\+\+\) \{
    printf\("Loop %lu", loop\);
    if \(loops\) \{
        printf\("/%lu", loops\);
    \}
    printf\(":\\n"\);
    printf\("  %-20s: ", "Stuck Address"\);
    fflush\(stdout\);
    if \(!test\_stuck_address\(aligned, bufsize / sizeof\(ul\)\)\) \{
         printf\("ok\\n"\);
    \} else \{
        exit_code |= EXIT\_FAIL_ADDRESSLINES;
    \}
    for \(i=0;;i\+\+\) \{
        if \(!tests[i].name\) break;
        printf\("  %-20s: ", tests[i].name\);
        if \(!tests[i].fp\(bufa, bufb, count\)\) \{
            printf\("ok\\n"\);
        \} else \{
            exit_code |= EXIT\_FAIL_OTHERTEST;
        \}
        fflush\(stdout\);
    \}
    printf\("\\n"\);
    fflush\(stdout\);
\}
if \(do_mlock\) munlock\(\(void *\) aligned, bufsize\);
printf\("Done.\\n"\);
fflush\(stdout\);
exit\(exit_code\);

}

HI
Jim thanks for everything - I owe you a beer if you come to Slovenia(if you know where that is)
I solved everything - could you just explain the row you wrote:
./memtester `free -om | grep 'Mem:' | awk '{print $4}'` 1

Have a nice Day

Matej Ostovic