diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llcommon/llsys.cpp | 204 |
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> | ||
47 | const char MEMINFO_FILE[] = "/proc/meminfo"; | 53 | const char MEMINFO_FILE[] = "/proc/meminfo"; |
48 | const char CPUINFO_FILE[] = "/proc/cpuinfo"; | 54 | const 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 | ||
303 | LLCPUInfo::LLCPUInfo() | 343 | LLCPUInfo::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 | ||
413 | bool LLCPUInfo::hasAltivec() const | ||
414 | { | ||
415 | return mHasAltivec; | ||
416 | } | ||
313 | 417 | ||
314 | std::string LLCPUInfo::getCPUString() const | 418 | bool LLCPUInfo::hasSSE() const |
315 | { | 419 | { |
316 | #if LL_WINDOWS || LL_DARWIN | 420 | return mHasSSE; |
317 | std::ostringstream out; | 421 | } |
318 | 422 | ||
319 | CProcessor proc; | 423 | bool 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 | 428 | S32 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(); | 433 | std::string LLCPUInfo::getCPUString() const |
332 | #else | 434 | { |
333 | return "Can't get terse CPU information"; | 435 | return mCPUString; |
334 | #endif | ||
335 | } | 436 | } |
336 | 437 | ||
337 | void LLCPUInfo::stream(std::ostream& s) const | 438 | void 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 | ||
372 | LLMemoryInfo::LLMemoryInfo() | 481 | LLMemoryInfo::LLMemoryInfo() |
373 | { | 482 | { |
374 | } | 483 | } |
375 | 484 | ||
376 | #if LL_LINUX | ||
377 | #include <unistd.h> | ||
378 | #include <sys/sysinfo.h> | ||
379 | #endif | ||
380 | |||
381 | U32 LLMemoryInfo::getPhysicalMemory() const | 485 | U32 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; |