On Tue, Jul 09, 2013 at 12:50:00PM +0200, Laszlo Ersek wrote: > On 07/09/13 11:26, Gary Ching-Pang Lin wrote: > > Per gmtime manpage, tm_mon is the number of months since January > > while MonthNo is the month of the year, so tm_mon should be MonthNo-1. > > > > Also, tm_mday is the day of the month, and DayNo is the number of > > days since the first day of the month. Assigning DayNo+1 to tm_mday > > to fix the definition. > > > > Contributed-under: TianoCore Contribution Agreement 1.0 > > Signed-off-by: Gary Ching-Pang Lin <g...@suse.com> > > --- > > CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c > > b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c > > index 805e6b4..15be4ef 100644 > > --- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c > > +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c > > @@ -154,8 +154,8 @@ struct tm * gmtime (const time_t *timer) > > } > > } > > > > - GmTime->tm_mon = (int) MonthNo; > > - GmTime->tm_mday = (int) DayNo; > > + GmTime->tm_mon = (int) MonthNo - 1; > > + GmTime->tm_mday = (int) DayNo + 1; > > > > GmTime->tm_isdst = 0; > > GmTime->tm_gmtoff = 0; > > > > "DayNo" is the number of whole days passed since the Epoch. > > In the gmtime() function, the first loop subtracts whole years. At the > end of the loop, DayNo may be zero (eg. 01-Jan-1971). After the loop, > "DayNo" contains the number of whole days passed in the new year. > > The second loop wants to find out the number of whole months passed in > the new year, and the number of remaining days. Again, the number of > days remaining in the month could be 0 in theory (eg. for 01-Feb-1970). > > for (MonthNo = 12; MonthNo > 1; MonthNo--) { > if (DayNo > CumulativeDays[IsLeap(Year)][MonthNo]) { > DayNo = (UINT16) (DayNo - (UINT16) > (CumulativeDays[IsLeap(Year)][MonthNo])); > break; > } > } > > For 01-Feb-1970, DayNo == 31 before the second loop. In the second loop, > for MonthNo==2, CumulativeDays[0][2] == 31, hence we don't break out, > and MonthNo is decreased to 1. Thereafter the controlling expression > stops the loop (with MonthNo==1, DayNo==31): > > should be pre-patch post-patch > tm_mon 1 1 0 > tm_mday 1 31 32 > > I think both pre-patch and post-patch results are wrong (although the > post-patch version is correct "quantitatively", as Feb 1st is in fact > the 32nd day of January). > > The thing to fix (in addition to the patch) is the relational operator > in the loop: if the number of our remaining *whole* days is greater than > *or equal to* the cumulative days up to and including MonthNo, then > month MonthNo itself has passed too. (Note that MonthNo==12 corresponds > to November.) > > When the second loop, modified thus, terminates, MonthNo==1 implies that > *stricly less* than 31 days have passed in the new year, hence we're > still in January. DayNo keeps its meaning (and MonthNo==1 && DayNo==0 > corresponds to Jan 1st). > Ah, right! The modified condition fixed the case I missed. Thanks for pointing it out, Laszlo :)
Gary Lin > I think the patch is a step in the right direction but incomplete; I > suggest: > > diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c > b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c > index 805e6b4..6422d61 100644 > --- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c > +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c > @@ -148,14 +148,14 @@ struct tm * gmtime (const time_t *timer) > GmTime->tm_yday = (int) DayNo; > > for (MonthNo = 12; MonthNo > 1; MonthNo--) { > - if (DayNo > CumulativeDays[IsLeap(Year)][MonthNo]) { > + if (DayNo >= CumulativeDays[IsLeap(Year)][MonthNo]) { > DayNo = (UINT16) (DayNo - (UINT16) > (CumulativeDays[IsLeap(Year)][MonthNo])); > break; > } > } > > - GmTime->tm_mon = (int) MonthNo; > - GmTime->tm_mday = (int) DayNo; > + GmTime->tm_mon = (int) MonthNo - 1; > + GmTime->tm_mday = (int) DayNo + 1; > > GmTime->tm_isdst = 0; > GmTime->tm_gmtoff = 0; > > This is identical to your patch for all days except for Feb 1st, Mar > 1st, ... Dec 1st, where my suggested version returns DayNo==0 > (-->tm_mday==1), and the next month relative to yours. > > Laszlo > ------------------------------------------------------------------------------ See everything from the browser to the database with AppDynamics Get end-to-end visibility with application monitoring from AppDynamics Isolate bottlenecks and diagnose root cause in seconds. Start your free trial of AppDynamics Pro today! http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel