#150565 - Noda - Thu Feb 07, 2008 6:29 am
hello!
After having heard of some people experiencing problems while readinf files using libfat while playing a streamed mp3 (also using libfat), I made some tests.
And it appears that it's working quite randomly :s The mp3 read buffer is refilled on the VBL interrupt. I think that may be the source of the problem, as while doing some reading/writing in the program, the reading migh be interrupted on VBL and another read is started to refill the buffer.
I even went to completely corrupt my card (DSX) during my tests :(
So anyone have suggestion, maybe confirmation for this problem?
PS: found also another annoying bug in libfat: I open a file in rb+ mode, read 4 bytes then immediately after try to write 16 bytes. The 16 bytes written are then offseted in the file by 1024 bytes instead of 4!! If I close/reopen the file after the read, everything is fine...
#150566 - Lazy1 - Thu Feb 07, 2008 7:42 am
Yes, I can confirm that disk I/O during an interrupt can cause data corruption.
What you can do is wrap all your open/read/write functions so you can disable interrupts before the call and re-enable them after.
#150567 - Noda - Thu Feb 07, 2008 8:21 am
Ouch, that's a serious issue then :/ When interrupts are disabled, any IRQ will be still throwed after they are enabled again or are they ignored?
Even in the first case, it may be an issue, as VBL-timed things like display refresh would not like being delayed... :(
Isn't there a way to make the libfat IRQ safe, or it's something too much complicated to be bothered with? (Chism?)
#150570 - simonjhall - Thu Feb 07, 2008 12:04 pm
I do file access in a function called through a timer interrupt and I've never had problems...well I don't think I have anyway!
I do know however that libfat is not thread-safe, so that's one thing you need to be aware of when using it in interrupts (assuming you're using it in other threads too).
To catch stuff like this I have locks around all my file access to ensure that I never get into situations like this. This is also essential when you're reading into slot-2 memory which may or may not need to be disabled during disk access.
Btw you're not using nested interrupts, right?
_________________
Big thanks to everyone who donated for Quake2
#150571 - PypeBros - Thu Feb 07, 2008 12:11 pm
Personnally, i wouldn't do any "disk" I/O in a timer or VBL interrupt... I'd rather just use the VBL to test wether more data are needed and read data in the "main" loop if this has been indicated to be required by the VBL handler.
That seems preferable to the wrapping of all "main" I/O access with disabling of interrupts.
_________________
SEDS: Sprite Edition on DS :: modplayer
#150576 - Noda - Thu Feb 07, 2008 5:38 pm
simon> no, the interrupt are not nested. do you do file access ONLY on interrupt or in interupt + main loop? using it only on interrupt should be safe...
pypebros> the libfat access I do in VBL is the buffer refill function for the mp3 decoder, and is very time critical, so putting it in an interrupt is the best solution here.
Even on simple code I can make the libfat crashing the DS filesystem:
- Launch an mp3 on the arm7 (refill buffer is done on arm9, on VBL IRQ)
- After that, try to read / write some data and here it is.
Can this be card-dependant (due to the dldi driver) or is it really a libfat problem?
#150579 - simonjhall - Thu Feb 07, 2008 8:05 pm
I do both file reading in both the main thread and in the timer interrupt. However I know that they're never gonna both happen at the same time so maybe that's why I've not had a problem.
Some dldi drivers do (did?) use dma though, which I can attribute problems to. esp when it comes to locking/unlocking slot-2 memory...
_________________
Big thanks to everyone who donated for Quake2
#150583 - Dwedit - Thu Feb 07, 2008 9:15 pm
Wait... Wasn't one of the big changes to libfat (when it changed from gba_nds_fat) supposed to be support for re-enterence and multithreading?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#150618 - Noda - Fri Feb 08, 2008 5:50 pm
Dwedit wrote: |
Wait... Wasn't one of the big changes to libfat (when it changed from gba_nds_fat) supposed to be support for re-enterence and multithreading? |
I thought so... :(
#150643 - chishm - Sat Feb 09, 2008 6:46 am
Dwedit wrote: |
Wait... Wasn't one of the big changes to libfat (when it changed from gba_nds_fat) supposed to be support for re-enterence and multithreading? |
It is re-entrant in the sense that you can perform more than one directory operation without it affecting other directory operations. For instance, in GBA_NDS_FAT, if you were scanning a directory for files and you opened a file between two successive filename read operations, the second filename read would be of the file after the one just opened, not the one after the previously read one.
Multi-threading support and interrupt safety is not easily doable for any I/O operation on the DS. I'd need to queue I/O operations so that they don't interfere, but this would reduce the responsiveness such that there'd be no point in even reading during an interrupt instead of the main loop.
If you really must get data through quickly, read it into a large buffer in your main loop then copy it to the audio buffer as needed in the interrupt, or just use a bigger buffer to begin with.
Noda:
The write occurring 1024 into the file may be caused by newlib. Try using open/read/write/close instead of fopen/fread/fwrite/fclose and see if the problem remains.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#150645 - Dwedit - Sat Feb 09, 2008 8:38 am
Is it possible to make a generic "queueing" DLDI driver, which itself will accept a DLDI patch?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#150667 - pas - Sun Feb 10, 2008 1:13 am
Dwedit wrote: |
Is it possible to make a generic "queueing" DLDI driver, which itself will accept a DLDI patch? |
ask chishim he should be able to answer this kind of question with ease cause he invented it.
_________________
Starcraft DS ?