Well, I wasn't planning to dive into this until after MTP... but here I am (at least today) several hours into the USB serial issue.
Indeed checking availableForWrite() or disabling the usb_serial_write() timeout code makes things work much better. But wow, the performance on Windows is horrible. With Teensy 4.1 overclocked at 816 MHz, my Linux desktop consistently sustains about 644K lines/sec. My Macbook Air manages a consistent 632K. The overall speed appears to be CPU limited on the Teensy side, probably by Serial.print(number). Serial.printf() is much slower. Transmitting fixed strings is much faster, but requires other ways of measuring than simply printing the benchmark.
But Windows varies wildly from high points around 120K-150K lines/sec to frequent slowdowns at half that speed or less, and sometimes stalls where it wasn't able to send anything to the PC for a few seconds! Remember, this is the speed observed from the Teensy side. Windows Task Manager showing pretty consistent 30% CPU usage and no unusual amount of memory used. I don't understand how Windows can perform this badly when so much CPU power is going unused.
Then after running for 15 min or more, Windows seems to fall into a pattern of short bursts at normal to sometimes even nearly Mac / Linux speed (again, as observed from the Teensy side) with long times of reporting 1 lines/sec. My best guess at this point is we're filling up a huge buffer on the Windows side and then waiting a long time before its gets drained low enough for data transfer to resume.
My beliefs at this point...
1: Something is going very wrong on the Teensy side for the unresponsive host timeout case. I had previously thought this to be a Windows bug, but now I'm not sure. It probably is something wrong on the Teensy side that only manifests when talking to Windows. This very likely could be the source of corrupted data. Maybe?
2: I don't understand how the Windows performance can be so bad, but wow, it's terrible!
3: Looks like teensy_serialmon might have another stall condition. I've hit it only a few times with hours of high speed printing from usb_serial_print_speed.ino. When it happens, sending any character causes data flow to resume. I'm pretty sure it's getting hung in WIN32 MsgWaitForMultipleObjects(), but why I have no idea yet. It's a very rare problem which only seems to happens after many hundreds of millions of lines.
FWIW, here is usb_serial_print_speed.ino with availableForWrite added. @Defragster - can you run this and tell me if you see any data corruption?
...
Edit: here's the sort of performance I'm seeing.
...
Running that code seeing about 75K lps consistently with TyComm {not over 90K} - then some few minutes and 'SPLASH' of a full screen of garbage.
Moving to teensy_serialmon: Cycles typically between ~(75K to 155K) lps
> drops to 1 lps on (rare) occasion. Rare under 50M cnts, then more often as it neared/passed 100M
>> over 100M cnts seeing cycling of 1 lps (for 1-3 sec and pulse to 180K lps)
>> FIRST STALL at : count=122247991, lines/sec=1 : Recovery? - No :: Until I hit 'Send' { repro again at ~128M cnts }
> not caught garbage yet
> see only sub second GUI pauses that are rare
RE: points
1: odd that garbage shown on PC often appears as 'PC internal data' - but maybe not always
2: Terrible indeed! Even when Hterm does amazingly well, it is only short term and not repeatable
3: First stall above ended when 'Send' was hit
Somewhere in history back I observed/reported that
Send can work to WAKE the Teensy/PC I/O - but
only (it seemed) when Teensy had not exhausted/queued ALL USB buffers for output? This was found using .availableForWrite() restriction on the code to not abuse all buffers for send.
Third Stall at '163M' trying to copy failed as selection not possible - and in trying the window went blank.
> hitting Send resumed at 165M
Now pulsing 1 lps to 200+ (highest seen ~250K lps)
> Stalled at : count=171142869, lines/sec=241346, output Resumed with 'Send'
This pulsing seems to be a cycle and no garbage yet observed.
Note: This is a beta Win 11 machine
It was sitting at : count=215933094, lines/sec=1
and 'Send' again allowed it to pick up where it left off with no counting while stuck in the : while( Serial.availableForWrite() < 50 ) {}
Ran to here and restarted on send:
count=376697100, lines/sec=154282
Then again to here - with Send restarting: {still no garbage observed}
count=411624674, lines/sec=163562