aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llsys.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/llsys.cpp204
1 files changed, 159 insertions, 45 deletions
diff --git a/linden/indra/llcommon/llsys.cpp b/linden/indra/llcommon/llsys.cpp
index 48f2474..25749e1 100644
--- a/linden/indra/llcommon/llsys.cpp
+++ b/linden/indra/llcommon/llsys.cpp
@@ -31,9 +31,13 @@
31#include "llsys.h" 31#include "llsys.h"
32 32
33#include <iostream> 33#include <iostream>
34#include <zlib/zlib.h> 34#ifdef LL_STANDALONE
35# include <zlib.h>
36#else
37# include "zlib/zlib.h"
38#endif
35 39
36#include "processor.h" 40#include "llprocessor.h"
37 41
38#if LL_WINDOWS 42#if LL_WINDOWS
39# define WIN32_LEAN_AND_MEAN 43# define WIN32_LEAN_AND_MEAN
@@ -44,6 +48,8 @@
44# include <sys/utsname.h> 48# include <sys/utsname.h>
45#elif LL_LINUX 49#elif LL_LINUX
46# include <sys/utsname.h> 50# include <sys/utsname.h>
51# include <unistd.h>
52# include <sys/sysinfo.h>
47const char MEMINFO_FILE[] = "/proc/meminfo"; 53const char MEMINFO_FILE[] = "/proc/meminfo";
48const char CPUINFO_FILE[] = "/proc/cpuinfo"; 54const char CPUINFO_FILE[] = "/proc/cpuinfo";
49#endif 55#endif
@@ -182,7 +188,7 @@ LLOSInfo::LLOSInfo() :
182 } 188 }
183#else 189#else
184 struct utsname un; 190 struct utsname un;
185 if(0==uname(&un)) 191 if(uname(&un) != -1)
186 { 192 {
187 mOSString.append(un.sysname); 193 mOSString.append(un.sysname);
188 mOSString.append(" "); 194 mOSString.append(" ");
@@ -252,13 +258,12 @@ U32 LLOSInfo::getProcessVirtualSizeKB()
252#if LL_WINDOWS 258#if LL_WINDOWS
253#endif 259#endif
254#if LL_LINUX 260#if LL_LINUX
255 FILE* status_filep = LLFile::fopen("/proc/self/status", "r"); /* Flawfinder: ignore */ 261 FILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
256 S32 numRead = 0; 262 S32 numRead = 0;
257 char buff[STATUS_SIZE]; /* Flawfinder: ignore */ 263 char buff[STATUS_SIZE]; /* Flawfinder: ignore */
258 bzero(buff, STATUS_SIZE);
259 264
260 rewind(status_filep); 265 size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep);
261 fread(buff, 1, STATUS_SIZE-2, status_filep); 266 buff[nbytes] = '\0';
262 267
263 // All these guys return numbers in KB 268 // All these guys return numbers in KB
264 char *memp = strstr(buff, "VmSize:"); 269 char *memp = strstr(buff, "VmSize:");
@@ -267,6 +272,24 @@ U32 LLOSInfo::getProcessVirtualSizeKB()
267 numRead += sscanf(memp, "%*s %u", &virtual_size); 272 numRead += sscanf(memp, "%*s %u", &virtual_size);
268 } 273 }
269 fclose(status_filep); 274 fclose(status_filep);
275#elif LL_SOLARIS
276 char proc_ps[LL_MAX_PATH];
277 sprintf(proc_ps, "/proc/%d/psinfo", (int)getpid());
278 int proc_fd = -1;
279 if((proc_fd = open(proc_ps, O_RDONLY)) == -1){
280 llwarns << "unable to open " << proc_ps << llendl;
281 return 0;
282 }
283 psinfo_t proc_psinfo;
284 if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
285 llwarns << "Unable to read " << proc_ps << llendl;
286 close(proc_fd);
287 return 0;
288 }
289
290 close(proc_fd);
291
292 virtual_size = proc_psinfo.pr_size;
270#endif 293#endif
271 return virtual_size; 294 return virtual_size;
272} 295}
@@ -278,15 +301,14 @@ U32 LLOSInfo::getProcessResidentSizeKB()
278#if LL_WINDOWS 301#if LL_WINDOWS
279#endif 302#endif
280#if LL_LINUX 303#if LL_LINUX
281 FILE* status_filep = LLFile::fopen("/proc/self/status", "r"); /* Flawfinder: ignore */ 304 FILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
282 if (status_filep != NULL) 305 if (status_filep != NULL)
283 { 306 {
284 S32 numRead = 0; 307 S32 numRead = 0;
285 char buff[STATUS_SIZE]; /* Flawfinder: ignore */ 308 char buff[STATUS_SIZE]; /* Flawfinder: ignore */
286 bzero(buff, STATUS_SIZE);
287 309
288 rewind(status_filep); 310 size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep);
289 fread(buff, 1, STATUS_SIZE-2, status_filep); 311 buff[nbytes] = '\0';
290 312
291 // All these guys return numbers in KB 313 // All these guys return numbers in KB
292 char *memp = strstr(buff, "VmRSS:"); 314 char *memp = strstr(buff, "VmRSS:");
@@ -296,47 +318,126 @@ U32 LLOSInfo::getProcessResidentSizeKB()
296 } 318 }
297 fclose(status_filep); 319 fclose(status_filep);
298 } 320 }
321#elif LL_SOLARIS
322 char proc_ps[LL_MAX_PATH];
323 sprintf(proc_ps, "/proc/%d/psinfo", (int)getpid());
324 int proc_fd = -1;
325 if((proc_fd = open(proc_ps, O_RDONLY)) == -1){
326 llwarns << "unable to open " << proc_ps << llendl;
327 return 0;
328 }
329 psinfo_t proc_psinfo;
330 if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
331 llwarns << "Unable to read " << proc_ps << llendl;
332 close(proc_fd);
333 return 0;
334 }
335
336 close(proc_fd);
337
338 resident_size = proc_psinfo.pr_rssize;
299#endif 339#endif
300 return resident_size; 340 return resident_size;
301} 341}
302 342
303LLCPUInfo::LLCPUInfo() 343LLCPUInfo::LLCPUInfo()
304{ 344{
345 std::ostringstream out;
305 CProcessor proc; 346 CProcessor proc;
306 const ProcessorInfo* info = proc.GetCPUInfo(); 347 const ProcessorInfo* info = proc.GetCPUInfo();
307 mHasSSE = (info->_Ext.SSE_StreamingSIMD_Extensions != 0); 348 // proc.WriteInfoTextFile("procInfo.txt");
308 mHasSSE2 = (info->_Ext.SSE2_StreamingSIMD2_Extensions != 0); 349 mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions;
350 mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions;
351 mHasAltivec = info->_Ext.Altivec_Extensions;
309 mCPUMhz = (S32)(proc.GetCPUFrequency(50)/1000000.0); 352 mCPUMhz = (S32)(proc.GetCPUFrequency(50)/1000000.0);
310 mFamily.assign( info->strFamily ); 353 mFamily.assign( info->strFamily );
354 mCPUString = "Unknown";
355
356#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS
357 out << proc.strCPUName;
358 if (200 < mCPUMhz && mCPUMhz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check
359 {
360 out << " (" << mCPUMhz << " MHz)";
361 }
362 mCPUString = out.str();
363
364#elif LL_LINUX
365 std::map< LLString, LLString > cpuinfo;
366 FILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb");
367 if(cpuinfo_fp)
368 {
369 char line[MAX_STRING];
370 memset(line, 0, MAX_STRING);
371 while(fgets(line, MAX_STRING, cpuinfo_fp))
372 {
373 // /proc/cpuinfo on Linux looks like:
374 // name\t*: value\n
375 char* tabspot = strchr( line, '\t' );
376 if (tabspot == NULL)
377 continue;
378 char* colspot = strchr( tabspot, ':' );
379 if (colspot == NULL)
380 continue;
381 char* spacespot = strchr( colspot, ' ' );
382 if (spacespot == NULL)
383 continue;
384 char* nlspot = strchr( line, '\n' );
385 if (nlspot == NULL)
386 nlspot = line + strlen( line ); // Fallback to terminating NUL
387 std::string linename( line, tabspot );
388 LLString llinename(linename);
389 LLString::toLower(llinename);
390 std::string lineval( spacespot + 1, nlspot );
391 cpuinfo[ llinename ] = lineval;
392 }
393 fclose(cpuinfo_fp);
394 }
395# if LL_X86
396 LLString flags = " " + cpuinfo["flags"] + " ";
397 LLString::toLower(flags);
398 mHasSSE = ( flags.find( " sse " ) != std::string::npos );
399 mHasSSE2 = ( flags.find( " sse2 " ) != std::string::npos );
400
401 F64 mhz;
402 if (LLString::convertToF64(cpuinfo["cpu mhz"], mhz)
403 && 200.0 < mhz && mhz < 10000.0)
404 {
405 mCPUMhz = (S32)llrint(mhz);
406 }
407 if (!cpuinfo["model name"].empty())
408 mCPUString = cpuinfo["model name"];
409# endif // LL_X86
410#endif // LL_LINUX
311} 411}
312 412
413bool LLCPUInfo::hasAltivec() const
414{
415 return mHasAltivec;
416}
313 417
314std::string LLCPUInfo::getCPUString() const 418bool LLCPUInfo::hasSSE() const
315{ 419{
316#if LL_WINDOWS || LL_DARWIN 420 return mHasSSE;
317 std::ostringstream out; 421}
318 422
319 CProcessor proc; 423bool LLCPUInfo::hasSSE2() const
320 (void) proc.GetCPUInfo(); 424{
321 out << proc.strCPUName << " "; 425 return mHasSSE2;
322 426}
323 F32 freq = (F32)(proc.GetCPUFrequency(50) / 1000000.0);
324 427
325 // cpu speed is often way wrong, do a sanity check 428S32 LLCPUInfo::getMhz() const
326 if (200.f < freq && freq < 10000.f) 429{
327 { 430 return mCPUMhz;
328 out << "(" << (S32)(freq) << " MHz)"; 431}
329 }
330 432
331 return out.str(); 433std::string LLCPUInfo::getCPUString() const
332#else 434{
333 return "Can't get terse CPU information"; 435 return mCPUString;
334#endif
335} 436}
336 437
337void LLCPUInfo::stream(std::ostream& s) const 438void LLCPUInfo::stream(std::ostream& s) const
338{ 439{
339#if LL_WINDOWS || LL_DARWIN 440#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS
340 // gather machine information. 441 // gather machine information.
341 char proc_buf[CPUINFO_BUFFER_SIZE]; /* Flawfinder: ignore */ 442 char proc_buf[CPUINFO_BUFFER_SIZE]; /* Flawfinder: ignore */
342 CProcessor proc; 443 CProcessor proc;
@@ -346,38 +447,41 @@ void LLCPUInfo::stream(std::ostream& s) const
346 } 447 }
347 else 448 else
348 { 449 {
349 s << "Unable to collect processor info"; 450 s << "Unable to collect processor information" << std::endl;
350 } 451 }
351#else 452#else
352 // *NOTE: This works on linux. What will it do on other systems? 453 // *NOTE: This works on linux. What will it do on other systems?
353 FILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "r"); /* Flawfinder: ignore */ 454 FILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb");
354 if(cpuinfo) 455 if(cpuinfo)
355 { 456 {
356 char line[MAX_STRING]; /* Flawfinder: ignore */ 457 char line[MAX_STRING];
357 memset(line, 0, MAX_STRING); 458 memset(line, 0, MAX_STRING);
358 while(fgets(line, MAX_STRING, cpuinfo)) 459 while(fgets(line, MAX_STRING, cpuinfo))
359 { 460 {
360 line[strlen(line)-1] = ' '; /*Flawfinder: ignore*/ 461 line[strlen(line)-1] = ' ';
361 s << line; 462 s << line;
362 } 463 }
363 fclose(cpuinfo); 464 fclose(cpuinfo);
465 s << std::endl;
364 } 466 }
365 else 467 else
366 { 468 {
367 s << "Unable to collect memory information"; 469 s << "Unable to collect processor information" << std::endl;
368 } 470 }
369#endif 471#endif
472 // These are interesting as they reflect our internal view of the
473 // CPU's attributes regardless of platform
474 s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
475 s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
476 s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
477 s << "->mCPUMhz: " << mCPUMhz << std::endl;
478 s << "->mCPUString: " << mCPUString << std::endl;
370} 479}
371 480
372LLMemoryInfo::LLMemoryInfo() 481LLMemoryInfo::LLMemoryInfo()
373{ 482{
374} 483}
375 484
376#if LL_LINUX
377#include <unistd.h>
378#include <sys/sysinfo.h>
379#endif
380
381U32 LLMemoryInfo::getPhysicalMemory() const 485U32 LLMemoryInfo::getPhysicalMemory() const
382{ 486{
383#if LL_WINDOWS 487#if LL_WINDOWS
@@ -399,7 +503,8 @@ U32 LLMemoryInfo::getPhysicalMemory() const
399#elif LL_LINUX 503#elif LL_LINUX
400 504
401 return getpagesize() * get_phys_pages(); 505 return getpagesize() * get_phys_pages();
402 506#elif LL_SOLARIS
507 return getpagesize() * sysconf(_SC_PHYS_PAGES);
403#else 508#else
404 return 0; 509 return 0;
405 510
@@ -433,10 +538,15 @@ void LLMemoryInfo::stream(std::ostream& s) const
433 { 538 {
434 s << "Unable to collect memory information"; 539 s << "Unable to collect memory information";
435 } 540 }
436 541#elif LL_SOLARIS
542 U64 phys = 0;
543
544 phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
545
546 s << "Total Physical Kb: " << phys << std::endl;
437#else 547#else
438 // *NOTE: This works on linux. What will it do on other systems? 548 // *NOTE: This works on linux. What will it do on other systems?
439 FILE* meminfo = LLFile::fopen(MEMINFO_FILE,"r"); /* Flawfinder: ignore */ 549 FILE* meminfo = LLFile::fopen(MEMINFO_FILE,"rb");
440 if(meminfo) 550 if(meminfo)
441 { 551 {
442 char line[MAX_STRING]; /* Flawfinder: ignore */ 552 char line[MAX_STRING]; /* Flawfinder: ignore */
@@ -491,7 +601,11 @@ BOOL gunzip_file(const char *srcfile, const char *dstfile)
491 do 601 do
492 { 602 {
493 bytes = gzread(src, buffer, UNCOMPRESS_BUFFER_SIZE); 603 bytes = gzread(src, buffer, UNCOMPRESS_BUFFER_SIZE);
494 fwrite(buffer, sizeof(U8), bytes, dst); 604 size_t nwrit = fwrite(buffer, sizeof(U8), bytes, dst);
605 if (nwrit < (size_t) bytes)
606 {
607 llerrs << "Short write on " << tmpfile << llendl;
608 }
495 } while(gzeof(src) == 0); 609 } while(gzeof(src) == 0);
496 fclose(dst); 610 fclose(dst);
497 dst = NULL; 611 dst = NULL;