Closed
Bug 308587
Opened 19 years ago
Closed 19 years ago
PR_GetPhysicalMemorySize returns garbage on systems with more than 2GB RAM
Categories
(NSPR :: NSPR, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
4.6.1
People
(Reporter: darin.moz, Assigned: darin.moz)
References
Details
(Keywords: fixed1.8)
Attachments
(1 file, 2 obsolete files)
3.20 KB,
patch
|
wtc
:
review+
asa
:
approval1.8b5+
|
Details | Diff | Splinter Review |
PR_GetPhysicalMemorySize returns garbage on systems with more than 2GB RAM I observed this with 32-bit x86-linux on a machine with 3GB RAM. PR_GetPhysicalMemorySize returns 18446744072724996096. The problem is with this code: long pageSize = sysconf(_SC_PAGESIZE); long pageCount = sysconf(_SC_PHYS_PAGES); LL_I2L(bytes, pageSize * pageCount); sizeof(long) is 4, so on my system "pageSize * pageCount" is a negative value. LL_I2L casts the negative value to a PRInt64, which ends up producing the bogus value. This bug ends up causing Firefox to think that it has a zero-sized memory cache on my system, which obviously degrades performance. I'll attach a candidate patch shortly.
Assignee | ||
Comment 1•19 years ago
|
||
Here's a simple patch that solves the problem. It's interesting that LL_UI2L is actually identical to LL_I2L, so it is not enough to change the macro. I need the cast to force the correct result. I decided to change the macro for clarity only.
Attachment #196105 -
Flags: review?(wtchang)
Assignee | ||
Comment 2•19 years ago
|
||
I think it is crucial that this fix go into Firefox 1.5.
Status: NEW → ASSIGNED
Flags: blocking1.8b5?
Target Milestone: --- → 4.6.1
Comment 3•19 years ago
|
||
Comment on attachment 196105 [details] [diff] [review] v1 patch > #if defined(LINUX) || defined(SOLARIS) > > long pageSize = sysconf(_SC_PAGESIZE); > long pageCount = sysconf(_SC_PHYS_PAGES); >- LL_I2L(bytes, pageSize * pageCount); >+ LL_UI2L(bytes, (unsigned long) pageSize * pageCount); > > #elif defined(HPUX) I think it's better to declare pageSize and pageCount as PRUint64: PRUint64 pageSize, pageCount; LL_I2L(pageSize, sysconf(_SC_PAGESIZE)); LL_I2L(pageCount, sysconf(_SC_PHYS_PAGES)); LL_MUL(bytes, pageSize, pageCount); This is for the case of a 32-bit OS running on a system with more than 4GB RAM. Could you test this?
Attachment #196105 -
Flags: review?(wtchang)
Assignee | ||
Comment 4•19 years ago
|
||
Yeah, I like that better. I will try it now.
Assignee | ||
Comment 5•19 years ago
|
||
Wan-Teh: Yeah, that patch works fine. However, on platforms that do not have a native 64-bit integer type, we would end up evaluating sysconf twice per LL_I2L invocation. So, temporary |long| variables are warranted.
Comment 6•19 years ago
|
||
Sigh. You can just use regular arithmetic operators to write that code. PRUint64 pageSize = sysconf(_SC_PAGESIZE); PRUint64 pageCount = sysconf(_SC_PHYS_PAGES); bytes = pageSize * pageCount; It's 2005 now. No need to use the LL_ macros.
Comment 7•19 years ago
|
||
I agree with Wan-Teh. We should not support compilers that don't offer a long long type anymore. I believe there are already several places in NSS which break those compilers, and no one has been complaining.
Comment 9•19 years ago
|
||
Comment on attachment 196105 [details] [diff] [review] v1 patch We should also review the implementations for the other platforms to see if they have the same overflow problem. The code for HPUX also multiplies two 32-bit numbers (in 32-bit HP-UX), so it needs to be fixed the same way. (The type of info.physical_memory and info.page_size is _T_LONG_T, which is either int32_t or int64_t depending on whether the HP-UX OS is 32-bit or 64-bit.) The code for other platforms looks fine. In the code for AIX, we have LL_MUL(bytes, kbytes, 1024); It is wrong to use a constant in the LL_MUL macro. timeless: please name a compiler you need to support that doesn't have a 64-bit integer type (which doesn't need to be called "long long"). All the compilers NSPR support today have a 64-bit integer type. Our portability guidelines need to be reviewed from time to time, and I think it is safe to say goodbye to the LL_ macros now.
Assignee | ||
Comment 10•19 years ago
|
||
Wan-Teh: Ok, I'll take a crack at putting together a better patch shortly.
Assignee | ||
Comment 11•19 years ago
|
||
Let me know if you want a more minimal patch. I just decided to remove the LL_ macros from all #ifdef'd sections.
Attachment #196105 -
Attachment is obsolete: true
Attachment #196269 -
Flags: review?(wtchang)
Comment 12•19 years ago
|
||
Comment on attachment 196269 [details] [diff] [review] v2 patch You missed this LL_ macro: > PRUint64 bytes = LL_ZERO; In the following two changes: >- LL_I2L(bytes, pageSize * pageCount); >+ bytes = (PRUint64) pageSize * pageCount; and >- LL_I2L(bytes, info.physical_memory * info.page_size); >+ bytes = (PRUint64) info.physical_memory * info.page_size; I assume the (PRUint64) applies to the first operand rather than the product (i.e., the typecast binds more tightly than the * operator), and you rely on the automatic promotion of the second operand to PRUint64. Correct?
Assignee | ||
Comment 13•19 years ago
|
||
> You missed this LL_ macro: > > > PRUint64 bytes = LL_ZERO; Yeah, that was intentional. I only changed code inside the #ifdef's, but I'll go ahead and change that as well. > I assume the (PRUint64) applies to the first operand rather > than the product (i.e., the typecast binds more tightly than > the * operator), and you rely on the automatic promotion of > the second operand to PRUint64. Correct? Yes, exactly. If you prefer, I will make the casting more explicit.
Assignee | ||
Comment 14•19 years ago
|
||
BTW, I tested this patch on Linux-x86 (3 GB RAM), OSX-ppc (1 GB RAM), and WinXP (1 GB RAM).
Attachment #196269 -
Attachment is obsolete: true
Attachment #196273 -
Flags: review?(wtchang)
Assignee | ||
Updated•19 years ago
|
Attachment #196269 -
Flags: review?(wtchang)
Updated•19 years ago
|
Attachment #196273 -
Flags: review?(wtchang) → review+
Updated•19 years ago
|
Flags: blocking1.8b5? → blocking1.8b5+
Assignee | ||
Comment 15•19 years ago
|
||
Comment on attachment 196273 [details] [diff] [review] v2.1 patch I think we should fix this for Firefox 1.5
Attachment #196273 -
Flags: approval1.8b5?
Assignee | ||
Comment 16•19 years ago
|
||
fixed on NSPR trunk and NSPRPUB_PRE_4_2_CLIENT_BRANCH. I assume that we will want to also land this on the following branches: MOZILLA_1_8_BRANCH and NSPR_4_6_BRANCH. I will await explicit approval before doing so.
Comment 17•19 years ago
|
||
Yes, MOZILLA_1_8_BRANCH and NSPR_4_6_BRANCH should be kept in sync for as long as possible.
Updated•19 years ago
|
Attachment #196273 -
Flags: approval1.8b5? → approval1.8b5+
Assignee | ||
Comment 18•19 years ago
|
||
fixed1.8, fixed-nspr4.6
You need to log in
before you can comment on or make changes to this bug.
Description
•