[newRPL] Filesystem related date/time issues
08-15-2016, 12:13 PM (This post was last modified: 08-15-2016 04:49 PM by matthiaspaul.)
Post: #4
 matthiaspaul Senior Member Posts: 385 Joined: Jan 2015
RE: [newRPL] Filesystem related date/time issues
Hi Claudio.
(08-15-2016 02:44 AM)Claudio L. Wrote:  The year 2k problem is a non-issue on the calc, it was sorted out in a chip revision long before the 50g came out in 2006 (EDIT: should read: long before the 49G+ came out in 2003). The RTC assumes the 2 digits are 20xx, unless I misunderstood the Samsung docs.
Strangely enough, however, I saw some code for this chip (family) where 99 was special-cased for 1999 (but perhaps that was for an older chip revision, I don't know). It wouldn't matter much if the chip wouldn't be responsible for the calculation of the length of February and (probably also) the day-of-week. I didn't read this up in the reference manuals yet...

(08-15-2016 02:44 AM)Claudio L. Wrote:
(08-14-2016 11:06 PM)matthiaspaul Wrote:
Code:
              tm_mday:5, // day of the month 1-31 (0=day not set)              // DBG 2016-08-12 MPL: Is there a particular reason why the              // month entry is defined as a 0-based value, while the FAT dir              // entry and the RTC register are 1-based? The FAT dir entry              // allows for special value of 0 for "undefined", something we              // cannot fully cope with at present
The only reason is POSIX:
http://pubs.opengroup.org/onlinepubs/969...ime.h.html
I just took the struct tm and made it more compact.
I see. There were two reasons for that comment. I saw special -1 adjustments for it in three places (in the original unfolded code, that is), which could have been replaced by possibly fewer +1 adjustments on the other end. More important, for both entries, day and month, the FAT filesystem actually defines a value of 0 as valid to indicate "not set". Most code examples I have seen would display this with the date or month set to 0 (most often as "1980-00-00"), while others use it to suppress the display/usage of that value. The hardwired -1 in your code makes the month value underflow under that condition, which basically lumps this special case together with invalid month values beyond December. It very much depends on the higher level code if it would cope with this correctly or not.

(08-15-2016 02:44 AM)Claudio L. Wrote:
(08-14-2016 11:06 PM)matthiaspaul Wrote:  https://sourceforge.net/p/newrpl/sources...datetime.c
Code:
       // DBG 2016-08-12 MPL: Is one loop cycle enough for rollover       // to be reliably propagated in RTC hardware? I've seen other code actually       // looping until seconds become > 0 (which can cause delays up to 1 sec, though).
I don't see why more than one loop would be needed. The Samsung docs don't imply anywhere that more than one loop could be needed, this is the only reference to the issue:
Quote:...there is no problem, but, if the value is 0 sec., the year, month, date, hour, and minute may be changed to 2060 (Year), 1 (Month), 1 (Date), 0 (Hour) and 0 (Minute) because of the one second deviation that was mentioned. In this case, the user should re-read from BCDYEAR to BCDSEC if BCDSEC is zero.
So far, I have zero experience with this Samsung chip, so I don't know either.

I don't know if the Samsung chip ever had this issue (probably not), but interpreting Samsung's advise above very strictly, it could well mean that the whole bunch of regs should be reread *until* BCDSEC is not (no longer, that is) zero. On the other hand, their explanation regarding that "one second deviation that was mentioned" and the "there is no problem" indicate no such issue.

It's well possible (probably!) that the Samsung RTC registers are latched internally so that this is really a non-issue. However, in the past I have seen more than one RTC where the registers were not latched and the rollover took some time to be propagated internally - with such chips chances were that you still caught the old transient (year etc.) values on subsequent reads for some while and had to wait for the actual change to happen (complicated code) or just waited some arbitrary, but long enough time.

(Being somewhat shocked I saw code for that very Samsung chip doing just this, waiting for up to a whole second reading out the RTC. I don't have the link handy any more, though. I have also seen examples performing only one loop at max, though, so that former example might have been down to either "careless coding" or "working around some issue", I don't know. That's why I brought this up to our attention here.)

(08-15-2016 02:44 AM)Claudio L. Wrote:
(08-14-2016 11:06 PM)matthiaspaul Wrote:  https://sourceforge.net/p/newrpl/sources...ritetime.c
Code:
 // CHG 2016-08-13 MPL: Combined FSGetWriteTime(), FSGetCreatTime(), FSGetAccessDate() to avoid redundancy and save code
These are very simple functions that the compiler usually auto-inlines into the calling function. Combining them might prevent auto-inlining from working.
Actually, I hope for the compiler to do that (well, folding code rather than inlining - speed is not really an issue here, size is) otherwise this coding style would be quite "expensive" on an embedded system.

(My experience with the not so stellar optimization performance of GCC-based compilers stems from other platforms, though.)

I was tempted to introduce some dirty pointer indexing two bytes in front of the 16-bit lastaccess entry (and later just throw away/overwrite the bogus time value) building on the symmetry with the cases for the two 32-bit entries. That would remove all those special cases and considerably shrink the code - probably quite beyond to what the compiler could do. However, the easiest way to achieve this would be by some rearrangements in the FS_FILE struct so that negative indexing could be avoided, but I didn't want to touch that at this time.

Speaking about compiler optimization, without that added "volatile" there was some risk that a highly-optimizing compiler would have thrown out the RTC readout loop. After all, the compiler has no indication that the read values could ever change, so they only had to be read once (before the loop), and given the fact that flag is not used elsewhere in the code, the remaining loop reading out seconds twice could have been treated as just a short delay without external sideeffects, which then could be replaced by a single read of seconds as well. That "volatile" makes sure that the rollover case is actually treated specially regardless of the compiler's performance and configuration.

(08-15-2016 02:44 AM)Claudio L. Wrote:  Regarding the sanitization of date/time: the file system does nothing with these values, so invalid dates don't disturb its operation. I think the user code that uses these dates/times is better positioned to decide what to do with an invalid date than the file system layer (which would just mark as invalid and discard everything), so it's better not to touch them.
For example, a program might be looking for all files on a certain year, then doesn't care if the month is invalid as long as the year is good. Other program could be sorting files by date, and needs all fields to be valid. That same program could prefer to list a month 13 after the other files that year (and month 14 would go after 13 and before 15), while if we force it to zero to indicate invalid month, it would have to list it first (and there's no difference between month 13, 14 or 15).
That's right, and could be adjusted to use another special value to indicate "invalid". The reason why I proposed to use 0 is because that's what is actually used on disk by the FAT filesystem to indicate "month not set" or "day not set" (see the other comment above).

I don't think it would be a good idea to propagate invalid values (except for one "neutral" value) up to the frontend (RPL), as users are expecting "mathematical correctness" here (perhaps even doing some calendar calculations on it and just relying on that the values are either well-formatted or clearly indicated as invalid). They probably don't expect date functions to return impossibly high days and months (even if that would happen only in case the filesystem stores invalid entries - ensuring that it hasn't, is, I think, outside a user's responsibility and scope).

Being able to search for "month 13 or 14" might make sense on a lower level - for a lower level API function, perhaps. However, I'm not sure if that would still hold true on a calculator. Are you expecting people to write CHKDSK-like tools to be used on the calc?

(Sidenote: Except for the two special values of 0 for months and days, the only invalid values I have ever encountered in practise on FAT volumes were hour = 24, minute = 60 and second/2 = 30 as well as invalid days in February (but still not larger than 31.
However, given the space constraints in directory entries, I was, at the expense of disturbing the date info on unaware systems, experimenting with how to possibly use these invalidly high values to detect and encode additional file-related information in an advanced but mostly backward compatible FAT32 variant as (free) exFAT alternative (actually a framework of multiple optional features/properties) in a way that keeps implementation overhead at a minimum even on "legacy" and in embedded systems. That certainly does not need to be supported in newRPL, but that's why I don't assume any meaningful date or time related information in invalidly high date and time values.)
Quote:Another advantage of not sanitizing is that the conversion is reversible: if you read an invalid creation date writing it back with the same tm struct would recover the same invalid date, preserving whatever was on disk.
That's a very good point.

I was living under the impression, though, that routines such as fsupdatedirentry() (discussed in the original thread) would deal with the raw 16-bit and 32-bit values as stored in the FS_FILE struct, not with the somewhat "higher level" tm struct as used by FSGetWriteTime(), FSGetCreatTime(), FSGetAccessDate(). Either way, regarding easier reversibility, then perhaps the -1 month alignment for POSIX should be abandoned, as you would have to revert that as well otherwise. This would also free the value 0 for "not set". Does some already existing high-level code depend on that POSIX alignment?

Greetings,

Matthias

--
"Programs are poems for computers."
 « Next Oldest | Next Newest »

 Messages In This Thread [newRPL] Filesystem related date/time issues - matthiaspaul - 08-14-2016, 11:06 PM RE: [newRPL] Filesystem related date/time issues - hth - 08-14-2016, 11:59 PM RE: [newRPL] Filesystem related date/time issues - Claudio L. - 08-15-2016, 02:44 AM RE: [newRPL] Filesystem related date/time issues - matthiaspaul - 08-15-2016 12:13 PM RE: [newRPL] Filesystem related date/time issues - Claudio L. - 08-15-2016, 02:51 PM RE: [newRPL] Filesystem related date/time issues - matthiaspaul - 10-18-2016, 09:36 PM RE: [newRPL] Filesystem related date/time issues - Claudio L. - 10-19-2016, 03:08 AM RE: [newRPL] Filesystem related date/time issues - matthiaspaul - 09-17-2016, 11:49 PM RE: [newRPL] Filesystem related date/time issues - Claudio L. - 09-18-2016, 03:36 AM RE: [newRPL] Filesystem related date/time issues - matthiaspaul - 09-11-2016, 10:51 PM RE: [newRPL] Filesystem related date/time issues - Claudio L. - 09-12-2016, 01:38 PM RE: [newRPL] Filesystem related date/time issues - matthiaspaul - 09-21-2016, 07:43 PM RE: [newRPL] Filesystem related date/time issues - Claudio L. - 09-22-2016, 08:13 PM

User(s) browsing this thread: 1 Guest(s)