[maemo-commits] [maemo-commits] r18670 - in projects/haf/trunk/libosso: debian src
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Tue Jun 9 09:52:04 EEST 2009
- Previous message: [maemo-commits] r18669 - in projects/haf/trunk/libosso: debian src
- Next message: [maemo-commits] r18671 - in projects/haf/trunk/hildon-thumbnail: . daemon/plugins
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: kihamala Date: 2009-06-09 09:51:57 +0300 (Tue, 09 Jun 2009) New Revision: 18670 Modified: projects/haf/trunk/libosso/debian/changelog projects/haf/trunk/libosso/src/osso-mem.c projects/haf/trunk/libosso/src/osso-mem.h Log: applied Leonid's patch for fast memory functions Modified: projects/haf/trunk/libosso/debian/changelog =================================================================== --- projects/haf/trunk/libosso/debian/changelog 2009-06-09 06:05:27 UTC (rev 18669) +++ projects/haf/trunk/libosso/debian/changelog 2009-06-09 06:51:57 UTC (rev 18670) @@ -1,6 +1,7 @@ libosso (2.21-1~unreleased) unstable; urgency=low * Fixes: NB#121151 - libosso coverity findings + * Fixes: NB#120686 - fast functions to get amount of memory required -- Kimmo Hämäläinen <kimmo.hamalainen at nokia.com> Tue, 9 Jun 2009 08:48:36 +0300 Modified: projects/haf/trunk/libosso/src/osso-mem.c =================================================================== --- projects/haf/trunk/libosso/src/osso-mem.c 2009-06-09 06:05:27 UTC (rev 18669) +++ projects/haf/trunk/libosso/src/osso-mem.c 2009-06-09 06:51:57 UTC (rev 18670) @@ -3,7 +3,7 @@ * * This file is part of libosso * - * Copyright (C) 2005-2006 Nokia Corporation. All rights reserved. + * Copyright (C) 2005-2009 Nokia Corporation. All rights reserved. * * Contact: Leonid Moiseichuk <leonid.moiseichuk at nokia.com> * @@ -27,6 +27,7 @@ * ========================================================================= */ #include <osso-log.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -35,6 +36,7 @@ #include <pthread.h> #include <string.h> #include <inttypes.h> +#include <time.h> #include "osso-mem.h" @@ -114,8 +116,8 @@ * ========================================================================= */ /* For lowmem_ functions system limits */ +static size_t sys_avail_ram = NSIZE; static size_t sys_avail_memory = NSIZE; -static size_t sys_avail_ram = NSIZE; static size_t sys_deny_limit = NSIZE; static size_t sys_lowmem_limit = NSIZE; @@ -148,7 +150,7 @@ static size_t get_file_value(const char* filename) { - FILE* fp = fopen(filename, "rt"); + FILE* fp = fopen(filename, "r"); if (fp) { @@ -183,7 +185,7 @@ * ------------------------------------------------------------------------- */ static unsigned load_meminfo(size_t *vals, unsigned size) { - FILE* meminfo = fopen("/proc/meminfo", "rt"); + FILE* meminfo = fopen("/proc/meminfo", "r"); if ( meminfo ) { @@ -222,6 +224,15 @@ } /* load_meminfo */ /* ------------------------------------------------------------------------- * + * get_free_pages - gets the free pages from /proc. + * Returns NSIZE if file is not available or value is invalid. + * ------------------------------------------------------------------------- */ +static size_t get_free_pages(void) +{ + return get_file_value("/proc/sys/vm/lowmem_free_pages"); +} /* get_free_pages */ + +/* ------------------------------------------------------------------------- * * setup_sys_values - loads the values from /proc files or obtain its from * system andand setup sys_XXX variables. * WARNING: we expect than sys_XXX variables are not changed during runtime. @@ -232,16 +243,18 @@ const size_t pagesize = sysconf(_SC_PAGESIZE); /* Load amount of allowed pages */ const size_t allowed_pages = get_file_value("/proc/sys/vm/lowmem_allowed_pages"); + /* One field Total should be loaded from meminfo */ + size_t total = 0; /* ID_MEMTOTAL goes first */ + const int counter = load_meminfo(&total, 1); + /* Setup available amount of RAM, if no meminfo available set 64MB */ + sys_avail_ram = (counter && total ? total : (64 << 10)); + /* Check the availability of values */ if (NSIZE == allowed_pages) { - /* Unfortunately, lowmem_ is not available yet (scratchbox?) */ - size_t total = 0; /* ID_MEMTOTAL goes first */ - const int counter = load_meminfo(&total, 1); - - /* Setup available amount of RAM, if no meminfo available set 64MB */ - sys_avail_memory = (counter && total ? total : (64 << 10)); + /* Setup available amount of memory */ + sys_avail_memory = sys_avail_ram; } else { @@ -257,11 +270,19 @@ sys_deny_limit = DIVIDE(sys_avail_memory * sys_deny_limit, 100); if (NSIZE == sys_lowmem_limit) + { + sys_avail_ram = sys_deny_limit; sys_lowmem_limit = sys_deny_limit; + } else + { + /* Calibrate amount avaliable RAM and memory using sys_lowmem_limit percentage */ + sys_avail_ram = DIVIDE(sys_avail_ram * sys_lowmem_limit, 100); sys_lowmem_limit = DIVIDE(sys_avail_memory * sys_lowmem_limit, 100); + } /* Moving from KB to bytes */ + sys_avail_ram <<= 10; sys_avail_memory <<= 10; sys_deny_limit <<= 10; sys_lowmem_limit <<= 10; @@ -326,7 +347,10 @@ /* ------------------------------------------------------------------------- * * osso_mem_get_usage -- returns memory usage for current system in - * osso_mem_usage_t structure. + * osso_mem_usage_t structure. This function uses cached information + * internally because every call is expensive for system. Please use + * osso_mem_get_usage_now if you ready to pay for performance penalty. + * * parameters: * usage - parameters to be updated. * returns: @@ -334,6 +358,60 @@ * ------------------------------------------------------------------------- */ int osso_mem_get_usage(osso_mem_usage_t* usage) { + /* Cached values */ + static time_t cache_stamp; + static size_t cache_pfree; + static osso_mem_usage_t cache_usage; + /* Current values */ + time_t stamp; + size_t pfree; + int error; + + /* Check parameter */ + if ( !usage ) + return -1; + + /* We should use cached information if calls comes in one second */ + stamp = time(NULL); + if (stamp == cache_stamp) + { + memcpy(usage, &cache_usage, sizeof(*usage)); + return 0; + } + + /* We should use cached information if amount of free pages not changed */ + pfree = get_free_pages(); + if (pfree == cache_pfree) + { + cache_stamp = stamp; + memcpy(usage, &cache_usage, sizeof(*usage)); + return 0; + } + + /* Finally we have to load a new value from /proc/meminfo */ + error = osso_mem_get_usage_now(usage); + if ( !error ) + { + cache_stamp = stamp; + cache_pfree = pfree; + memcpy(&cache_usage, usage, sizeof(cache_usage)); + } + + return error; +} /* osso_mem_get_usage */ + +/* ------------------------------------------------------------------------- * + * osso_mem_get_usage_now -- returns memory usage for current system in + * osso_mem_usage_t structure.This function is very expensive for system. + * Please use osso_mem_get_usage if you can. + * + * parameters: + * usage - parameters to be updated. + * returns: + * 0 if values loaded successfuly OR negative error code. + * ------------------------------------------------------------------------- */ +int osso_mem_get_usage_now(osso_mem_usage_t* usage) +{ /* Local variables */ size_t vals[MAX_MEMINFO_LABELS]; @@ -351,13 +429,8 @@ if (NSIZE == sys_avail_memory) setup_sys_values(); - /* Discover memory information using loaded numbers */ usage->total = vals[ID_MEMTOTAL] + vals[ID_SWAPTOTAL]; - - if (NSIZE == sys_avail_ram) - sys_avail_ram = vals[ID_MEMTOTAL] << 10; - usage->free = vals[ID_MEMFREE] + vals[ID_BUFFERS] + vals[ID_CACHED] + vals[ID_SWAPFREE]; @@ -381,23 +454,48 @@ /* We have succeed */ return 0; -} /* osso_mem_get_usage */ +} /* osso_mem_get_usage_now */ + + /* ------------------------------------------------------------------------- * * Returns the total allocated RAM in system according to - * /proc/sys/vm/lowmem_* files. + * /proc/sys/vm/lowmem_* files. If system has swap available only RAM + * should be counted. * * WARNING: Assumes 97% of memory can be allocated if no limits set (kernel) * hardcoded threshold. * ------------------------------------------------------------------------- */ size_t osso_mem_get_avail_ram(void) { - if(NSIZE == sys_avail_memory) + if(NSIZE == sys_avail_ram) setup_sys_values(); - return sys_avail_memory; + return sys_avail_ram; } /* osso_mem_get_avail_ram */ /* ------------------------------------------------------------------------- * + * Returns amount of currently available memory in system below high memory + * usage watermark. If system has swap available it also counted. + * ------------------------------------------------------------------------- */ +size_t osso_mem_get_free(void) +{ + static size_t pg_high; + static size_t pg_size; + const size_t pg_free = get_free_pages(); + + if ( !pg_high ) + { + pg_high = get_file_value("/proc/sys/vm/lowmem_notify_high_pages"); + pg_size = sysconf(_SC_PAGESIZE); + } + + if (NSIZE == pg_high || NSIZE == pg_free) + return osso_mem_get_avail_ram(); + else + return (pg_free > pg_high ? (pg_free - pg_high) * pg_size: 0); +} /* osso_mem_get_free */ + +/* ------------------------------------------------------------------------- * * Returns deny limit (in bytes, the total allocated RAM in system) * according to /proc/sys/vm/lowmem_* settings. * @@ -534,7 +632,21 @@ } /* osso_mem_saw_disable */ +/* ------------------------------------------------------------------------- * + * osso_mem_score_adjust - adjust out of memory handling by set + * /proc/self/oom_adj to most system-friendly value (15) + * + * Returns: 0 on success, negative on error + * ------------------------------------------------------------------------- */ +int osso_mem_score_adjust(void) +{ + int fd = open("/proc/self/oom_adj", O_WRONLY); + int rs = (fd >= 0 && 2 == write(fd, "15", 2) ? 0 : -1); + close(fd); + return rs; +} /* osso_mem_score_adjust */ + /* ========================================================================= * * main function, just for testing purposes. * ========================================================================= */ @@ -552,8 +664,9 @@ const size_t insane = 60 << 20; void* ptr; - printf("\n1. UNIT_TEST MEMUSAGE \n"); + printf("\n* osso_mem_score_adjust() called to update oom_adj: %d\n", osso_mem_score_adjust()); + printf("\n* unit testing for osso_mem_get_usage\n"); /* Load all values from meminfo file */ if (0 == osso_mem_get_usage(&usage)) { @@ -564,15 +677,22 @@ printf ("unable to load values from /proc/meminfo file\n"); return -1; } + /* Make a sleeps and another calls */ + usleep(1 * 1000 * 1000); + osso_mem_get_usage(&usage); + usleep(2 * 1000 * 1000); + osso_mem_get_usage(&usage); + usleep(3 * 1000 * 1000); + osso_mem_get_usage(&usage); - printf("\n2. Testing lowmem\n"); + printf("\n* Testing lowmem\n"); printf("Lowmem limits: LOW=%u bytes, DENY=%u bytes\n", osso_mem_get_lowmem_limit(), osso_mem_get_deny_limit() ); - printf("\n3. Testing SAW\n"); + printf("\n* Testing SAW\n"); ptr = malloc( insane ); printf("Without SAW, allocating %u bytes: %s\n",insane, ptr ? "Succeeded": "Failed" ); @@ -596,10 +716,13 @@ printf("With SAW, allocating %u bytes: %s\n", insane, ptr ? "Succeeded" : "Failed"); if ( osso_mem_in_lowmem_state() ) - printf("\n4. Low memory situation is reached\n"); + printf("\n* Low memory situation is reached\n"); else - printf("\n4. Low memory situation is not reached\n"); + printf("\n* Low memory situation is not reached\n"); + printf("\n* RAM available %u\n", osso_mem_get_avail_ram()); + printf("\n* free memory available %u\n", osso_mem_get_free()); + if(ptr) free(ptr); Modified: projects/haf/trunk/libosso/src/osso-mem.h =================================================================== --- projects/haf/trunk/libosso/src/osso-mem.h 2009-06-09 06:05:27 UTC (rev 18669) +++ projects/haf/trunk/libosso/src/osso-mem.h 2009-06-09 06:51:57 UTC (rev 18670) @@ -3,7 +3,7 @@ * * This file is part of libosso * - * Copyright (C) 2005-2006 Nokia Corporation. All rights reserved. + * Copyright (C) 2005-2009 Nokia Corporation. All rights reserved. * * Contact: Leonid Moiseichuk <leonid.moiseichuk at nokia.com> * @@ -64,39 +64,57 @@ * ========================================================================= */ /* ------------------------------------------------------------------------- * - * osso_mem_get_usage -- returns memory usage for current system in - * osso_mem_usage_t structure. + * osso_mem_get_usage -- returns current memory usage in the system in a + * osso_mem_usage_t structure. This function uses cached information + * internally because every call is expensive for the system. Please use + * osso_mem_get_usage_now if you are ready to pay the performance penalty. + * * parameters: * usage - parameters to be updated. * returns: - * 0 if values loaded successfuly OR negative error code. + * 0 if values loaded successfully OR negative error code. * ------------------------------------------------------------------------- */ int osso_mem_get_usage(osso_mem_usage_t* usage); /* ------------------------------------------------------------------------- * - * Returns the total allocated RAM in system according to - * /proc/sys/vm/lowmem_* files. + * osso_mem_get_usage_now -- returns current memory usage in the system in a + * osso_mem_usage_t structure. This function is very expensive for the system. + * Please use osso_mem_get_usage if you can. * - * WARNING: Assumes 97% of memory can be allocated if no limits set (kernel) - * hardcoded threshold. + * parameters: + * usage - parameters to be updated. + * returns: + * 0 if values loaded successfuly OR negative error code. * ------------------------------------------------------------------------- */ +int osso_mem_get_usage_now(osso_mem_usage_t* usage); + +/* ------------------------------------------------------------------------- * + * Returns the total allocated RAM in the system according to + * /proc/sys/vm/lowmem_* files. The return value concerns only RAM, not swap. + * + * WARNING: Assumes that 97% of the free RAM can be allocated. + * ------------------------------------------------------------------------- */ size_t osso_mem_get_avail_ram(void); /* ------------------------------------------------------------------------- * - * Returns deny limit (in bytes, the total allocated RAM in system) + * Returns the amount of currently free memory in the system below the high + * memory usage watermark. If the system has swap available, it is also counted. + * ------------------------------------------------------------------------- */ +size_t osso_mem_get_free(void); + +/* ------------------------------------------------------------------------- * + * Returns the deny limit (in bytes, the total allocated RAM in system) * according to /proc/sys/vm/lowmem_* settings. * - * WARNING: Assumes 97% of memory can be allocated if no limits set (kernel) - * hardcoded threshold. + * WARNING: Assumes that 97% of the free RAM can be allocated. * ------------------------------------------------------------------------- */ size_t osso_mem_get_deny_limit(void); /* ------------------------------------------------------------------------- * - * Returns low memory (lowmem_high_limit, the total allocated RAM in system) + * Returns the low memory (lowmem_high_limit, the total allocated RAM in system) * according to /proc/sys/vm/lowmem_* settings. * - * WARNING: Assumes 97% of memory can be allocated if no limits set (kernel) - * hardcoded threshold. + * WARNING: Assumes that 97% of the free RAM can be allocated. * ------------------------------------------------------------------------- */ size_t osso_mem_get_lowmem_limit(void); @@ -109,20 +127,20 @@ /* ------------------------------------------------------------------------- * * osso_mem_saw_enable - enables Simple Allocation Watchdog. - * 1. Calculates the possible growth of process' heap based on the - * current heap stats, adjusted to the threshold - * 2. sets up the hook on malloc function; if the particular allocatuion - * whose size is bigger than watchblock_sz could violate the limit, - * oom_func with user-specified context is called and malloc returns 0 + * 1. Calculates the possible growth of the process' heap based on the + * current heap stats, adjusted to the threshold. + * 2. Sets up the hook on malloc function; if the particular allocation, + * whose size is bigger than watchblock_sz, could violate the limit, + * oom_func with user-specified context is called and malloc returns 0. * * Parameters: - * - threshold - amount of memory used in system. If you pass 0 than maximum + * - threshold - amount of memory used in system. If you pass 0, then maximum * available should be set (according to lowmem_high_limit) - * - watchblock - if allocation size more than specified the amount of - * available memory must be tested. If 0 passed this parameter should be - * set to page size. - * - oom_func - this function shall be called if we reach high memory - * consumption (OOM level), specified by threshold or NULL malloc occurs. + * - watchblock - if allocation size is more than this, the amount of + * available memory is (re)checked. If 0 is passed, this parameter will be + * set to the page size. + * - oom_func - this function will be called if we reach high memory + * consumption (OOM level), the threshold level, or if malloc returns NULL. * May be NULL. * - context - additional parameter that shall be passed into oom_func. * @@ -130,7 +148,7 @@ * * Note: can be safely called several times. * - * WARNING: if SAW can not be installed the old one will be active. + * WARNING: if SAW can not be installed, the old one will be active. * ------------------------------------------------------------------------- */ int osso_mem_saw_enable(size_t threshold, size_t watchblock, @@ -140,10 +158,18 @@ /* ------------------------------------------------------------------------- * * osso_mem_saw_disable - disables Simple Allocation Watchdog and restore - * default malloc hook. If no watchdog setup do nothing. + * the default malloc hook. If no watchdog was set up, do nothing. * ------------------------------------------------------------------------- */ void osso_mem_saw_disable(void); +/* ------------------------------------------------------------------------- * + * osso_mem_out_adjust - adjust out of memory handling by setting + * /proc/self/oom_adj to the most system-friendly value (15) + * + * Returns: 0 on success, negative on error + * ------------------------------------------------------------------------- */ +int osso_mem_score_adjust(void); + #ifdef __cplusplus } #endif
- Previous message: [maemo-commits] r18669 - in projects/haf/trunk/libosso: debian src
- Next message: [maemo-commits] r18671 - in projects/haf/trunk/hildon-thumbnail: . daemon/plugins
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]