diff options
Diffstat (limited to 'indra/llcommon/llmemory.cpp')
-rw-r--r-- | indra/llcommon/llmemory.cpp | 373 |
1 files changed, 85 insertions, 288 deletions
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 079f2b3258..a502d1a7eb 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -2,30 +2,25 @@ * @file llmemory.cpp * @brief Very special memory allocation/deallocation stuff here * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,18 +31,13 @@ # include <psapi.h> #elif defined(LL_DARWIN) # include <sys/types.h> -# include <sys/sysctl.h> # include <mach/task.h> -# include <mach/vm_map.h> # include <mach/mach_init.h> -# include <mach/vm_region.h> -# include <mach/mach_port.h> -#elif defined(LL_LINUX) +#elif LL_LINUX || LL_SOLARIS # include <unistd.h> #endif #include "llmemory.h" -#include "llmemtype.h" //---------------------------------------------------------------------------- @@ -77,162 +67,6 @@ void LLMemory::freeReserve() reserveMem = NULL; } - -//---------------------------------------------------------------------------- - -//static -#if MEM_TRACK_TYPE -S32 LLMemType::sCurDepth = 0; -S32 LLMemType::sCurType = LLMemType::MTYPE_INIT; -S32 LLMemType::sType[LLMemType::MTYPE_MAX_DEPTH]; -S32 LLMemType::sMemCount[LLMemType::MTYPE_NUM_TYPES] = { 0 }; -S32 LLMemType::sMaxMemCount[LLMemType::MTYPE_NUM_TYPES] = { 0 }; -S32 LLMemType::sNewCount[LLMemType::MTYPE_NUM_TYPES] = { 0 }; -S32 LLMemType::sOverheadMem = 0; - -const char* LLMemType::sTypeDesc[LLMemType::MTYPE_NUM_TYPES] = -{ - "INIT", - "STARTUP", - "MAIN", - - "IMAGEBASE", - "IMAGERAW", - "IMAGEFORMATTED", - - "APPFMTIMAGE", - "APPRAWIMAGE", - "APPAUXRAWIMAGE", - - "DRAWABLE", - "OBJECT", - "PIPELINE", - "AVATAR", - "PARTICLES", - "REGIONS", - "INVENTORY", - "ANIMATION", - "NETWORK", - "PHYSICS", - "INTERESTLIST", - - "SCRIPT", - "SCRIPT_RUN", - "SCRIPT_BYTECODE", - - "IO_PUMP", - "IO_TCP", - "IO_BUFFER", - "IO_HTTP_SERVER" - "IO_SD_SERVER", - "IO_SD_CLIENT", - "IO_URL_REQUEST", - - "TEMP1", - "TEMP2", - "TEMP3", - "TEMP4", - "TEMP5", - "TEMP6", - "TEMP7", - "TEMP8", - "TEMP9" -}; - -#endif -S32 LLMemType::sTotalMem = 0; -S32 LLMemType::sMaxTotalMem = 0; - -//static -void LLMemType::printMem() -{ - S32 misc_mem = sTotalMem; -#if MEM_TRACK_TYPE - for (S32 i=0; i<MTYPE_NUM_TYPES; i++) - { - if (sMemCount[i]) - { - llinfos << llformat("MEM: % 20s %03d MB (%03d MB) in %06d News",sTypeDesc[i],sMemCount[i]>>20,sMaxMemCount[i]>>20, sNewCount[i]) << llendl; - } - misc_mem -= sMemCount[i]; - } -#endif - llinfos << llformat("MEM: % 20s %03d MB","MISC",misc_mem>>20) << llendl; - llinfos << llformat("MEM: % 20s %03d MB (Max=%d MB)","TOTAL",sTotalMem>>20,sMaxTotalMem>>20) << llendl; -} - -#if MEM_TRACK_MEM - -void* ll_allocate (size_t size) -{ - if (size == 0) - { - llwarns << "Null allocation" << llendl; - } - - size = (size+3)&~3; - S32 alloc_size = size + 4; -#if MEM_TRACK_TYPE - alloc_size += 4; -#endif - char* p = (char*)malloc(alloc_size); - if (p == NULL) - { - LLMemory::freeReserve(); - llerrs << "Out of memory Error" << llendl; - } - LLMemType::sTotalMem += size; - LLMemType::sMaxTotalMem = llmax(LLMemType::sTotalMem, LLMemType::sMaxTotalMem); - LLMemType::sOverheadMem += 4; - *(size_t*)p = size; - p += 4; -#if MEM_TRACK_TYPE - if (LLMemType::sCurType < 0 || LLMemType::sCurType >= LLMemType::MTYPE_NUM_TYPES) - { - llerrs << "Memory Type Error: new" << llendl; - } - LLMemType::sOverheadMem += 4; - *(S32*)p = LLMemType::sCurType; - p += 4; - LLMemType::sMemCount[LLMemType::sCurType] += size; - if (LLMemType::sMemCount[LLMemType::sCurType] > LLMemType::sMaxMemCount[LLMemType::sCurType]) - { - LLMemType::sMaxMemCount[LLMemType::sCurType] = LLMemType::sMemCount[LLMemType::sCurType]; - } - LLMemType::sNewCount[LLMemType::sCurType]++; -#endif - return (void*)p; -} - -void ll_release (void *pin) -{ - if (!pin) - { - return; - } - char* p = (char*)pin; -#if MEM_TRACK_TYPE - p -= 4; - S32 type = *(S32*)p; - if (type < 0 || type >= LLMemType::MTYPE_NUM_TYPES) - { - llerrs << "Memory Type Error: delete" << llendl; - } -#endif - p -= 4; - S32 size = *(size_t*)p; - LLMemType::sOverheadMem -= 4; -#if MEM_TRACK_TYPE - LLMemType::sMemCount[type] -= size; - LLMemType::sOverheadMem -= 4; - LLMemType::sNewCount[type]--; -#endif - LLMemType::sTotalMem -= size; - free(p); -} - -#else - void* ll_allocate (size_t size) { if (size == 0) @@ -253,52 +87,11 @@ void ll_release (void *p) free(p); } -#endif - -#if MEM_TRACK_MEM - -void* operator new (size_t size) -{ - return ll_allocate(size); -} - -void* operator new[] (size_t size) -{ - return ll_allocate(size); -} - -void operator delete (void *p) -{ - ll_release(p); -} - -void operator delete[] (void *p) -{ - ll_release(p); -} - -#endif - -//---------------------------------------------------------------------------- - -LLRefCount::LLRefCount() : - mRef(0) -{ -} - -LLRefCount::~LLRefCount() -{ - if (mRef != 0) - { - llerrs << "deleting non-zero reference" << llendl; - } -} - //---------------------------------------------------------------------------- #if defined(LL_WINDOWS) -U64 getCurrentRSS() +U64 LLMemory::getCurrentRSS() { HANDLE self = GetCurrentProcess(); PROCESS_MEMORY_COUNTERS counters; @@ -314,77 +107,53 @@ U64 getCurrentRSS() #elif defined(LL_DARWIN) -static U32 getPageSize() -{ - int ctl[2] = { CTL_HW, HW_PAGESIZE }; - int page_size; - size_t size = sizeof(page_size); - - if (sysctl(ctl, 2, &page_size, &size, NULL, 0) == -1) - { - llwarns << "Couldn't get page size" << llendl; - return 0; - } else { - return page_size; +/* + The API used here is not capable of dealing with 64-bit memory sizes, but is available before 10.4. + + Once we start requiring 10.4, we can use the updated API, which looks like this: + + task_basic_info_64_data_t basicInfo; + mach_msg_type_number_t basicInfoCount = TASK_BASIC_INFO_64_COUNT; + if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS) + + Of course, this doesn't gain us anything unless we start building the viewer as a 64-bit executable, since that's the only way + for our memory allocation to exceed 2^32. +*/ + +// if (sysctl(ctl, 2, &page_size, &size, NULL, 0) == -1) +// { +// llwarns << "Couldn't get page size" << llendl; +// return 0; +// } else { +// return page_size; +// } +// } + +U64 LLMemory::getCurrentRSS() +{ + U64 residentSize = 0; + task_basic_info_data_t basicInfo; + mach_msg_type_number_t basicInfoCount = TASK_BASIC_INFO_COUNT; + if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS) + { + residentSize = basicInfo.resident_size; + + // If we ever wanted it, the process virtual size is also available as: + // virtualSize = basicInfo.virtual_size; + +// llinfos << "resident size is " << residentSize << llendl; } -} - -U64 getCurrentRSS() -{ - task_t task = mach_task_self(); - vm_address_t addr = VM_MIN_ADDRESS; - vm_size_t size = 0; - U64 residentPages = 0; - - while (true) + else { - mach_msg_type_number_t bcount = VM_REGION_BASIC_INFO_COUNT; - vm_region_basic_info binfo; - mach_port_t bobj; - kern_return_t ret; - - addr += size; - - ret = vm_region(task, &addr, &size, VM_REGION_BASIC_INFO, - (vm_region_info_t) &binfo, &bcount, &bobj); - - if (ret != KERN_SUCCESS) - { - break; - } - - if (bobj != MACH_PORT_NULL) - { - mach_port_deallocate(task, bobj); - } - - mach_msg_type_number_t ecount = VM_REGION_EXTENDED_INFO_COUNT; - vm_region_extended_info einfo; - mach_port_t eobj; - - ret = vm_region(task, &addr, &size, VM_REGION_EXTENDED_INFO, - (vm_region_info_t) &einfo, &ecount, &eobj); - - if (ret != KERN_SUCCESS) - { - llwarns << "vm_region failed" << llendl; - return 0; - } - - if (eobj != MACH_PORT_NULL) - { - mach_port_deallocate(task, eobj); - } - - residentPages += einfo.pages_resident; + llwarns << "task_info failed" << llendl; } - return residentPages * getPageSize(); + return residentSize; } #elif defined(LL_LINUX) -U64 getCurrentRSS() +U64 LLMemory::getCurrentRSS() { static const char statPath[] = "/proc/self/stat"; LLFILE *fp = LLFile::fopen(statPath, "r"); @@ -416,9 +185,37 @@ bail: return rss; } +#elif LL_SOLARIS +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#define _STRUCTURED_PROC 1 +#include <sys/procfs.h> + +U64 LLMemory::getCurrentRSS() +{ + char path [LL_MAX_PATH]; /* Flawfinder: ignore */ + + sprintf(path, "/proc/%d/psinfo", (int)getpid()); + int proc_fd = -1; + if((proc_fd = open(path, O_RDONLY)) == -1){ + llwarns << "LLmemory::getCurrentRSS() unable to open " << path << ". Returning 0 RSS!" << llendl; + return 0; + } + psinfo_t proc_psinfo; + if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){ + llwarns << "LLmemory::getCurrentRSS() Unable to read from " << path << ". Returning 0 RSS!" << llendl; + close(proc_fd); + return 0; + } + + close(proc_fd); + + return((U64)proc_psinfo.pr_rssize * 1024); +} #else -U64 getCurrentRSS() +U64 LLMemory::getCurrentRSS() { return 0; } |