https://www.youtube.com/watch?v=XAzUoizwnXM
i dint watched it whole but it comes to my mind that those socket communication indeed should be probably made using fopen/fread/fwrite/fgetc/fputc
i was doing only basics of socket programming anver liked it and
remember almost nothing - it is becouse i dont liek stupid things
and those sockets looks stupid
i guess using this fopen it would be much better..
whot would you need i assume you need to fopen connection to distant machine..not sure if it should be one the same for read write or two
one for read and one for write..then i think the network card should
have buffer whete there is stacked incoming data, same for outcoming
data,a nd thats all as to basics probably..no hanging controll no
additional threads..just like working with files
whough additional soft could be written too, based on thai but it should
be sane thing something based like with working with files (knowing
those files are ram files and are contents of incoming and outcoming buffer
thise sockets todajy i dont remember but in my vague mameory it feels
like shit
feel free to comment on this topic if you want
fir pisze:
https://www.youtube.com/watch?v=XAzUoizwnXMmaybe someone who has some experience with socked programming know how
i dint watched it whole but it comes to my mind that those socket
communication indeed should be probably made using
fopen/fread/fwrite/fgetc/fputc
i was doing only basics of socket programming anver liked it and
remember almost nothing - it is becouse i dont liek stupid things
and those sockets looks stupid
i guess using this fopen it would be much better..
whot would you need i assume you need to fopen connection to distant
machine..not sure if it should be one the same for read write or two
one for read and one for write..then i think the network card should
have buffer whete there is stacked incoming data, same for outcoming
data,a nd thats all as to basics probably..no hanging controll no
additional threads..just like working with files
whough additional soft could be written too, based on thai but it
should be sane thing something based like with working with files
(knowing those files are ram files and are contents of incoming and
outcoming buffer
thise sockets todajy i dont remember but in my vague mameory it feels
like shit
feel free to comment on this topic if you want
the basic communication would look like using this fopen scheme
main()
{
-a-a FILE* f = fopen("1.2.3.4:555");
-a fprintf(f, "hello there\n"); fflush(f);
-a for(int i=0; i<100; i++)
-a {
-a-a-a static char buf[4096];
-a-a-a if(fgets(buf, sizeof(buf), f))
-a-a-a-a-a-a printf("incoming: %s", buf);
-a-a-a Sleep(100); //wait 100 ms
-a }
}
something like that?
i dint watched it whole but it comes to my mind that those socket communication indeed should be probably made using fopen/fread/fwrite/fgetc/fputc
Sleep(100); //wait 100 ms
On Mon, 8 Jun 2026 18:16:10 +0200, fir wrote:
Sleep(100); //wait 100 ms
ThatrCOs usually a dumb thing to do. ItrCOs either too slow if something comes in/goes out more quickly, or too much overhead if communication
is slower than that. And it just gets worse if yourCOre trying to juggle multiple connections (as a server commonly does).
Try using this <https://manpages.debian.org/poll(2)>, at least ...
Lawrence DrCOOliveiro pisze:
On Mon, 8 Jun 2026 18:16:10 +0200, fir wrote:
-a-a-a-a-a Sleep(100); //wait 100 ms
ThatrCOs usually a dumb thing to do. ItrCOs either too slow if something
comes in/goes out more quickly, or too much overhead if communication
is slower than that. And it just gets worse if yourCOre trying to juggle
multiple connections (as a server commonly does).
Try using this <https://manpages.debian.org/poll(2)>, at least ...
i will answer more mabe later coz i had some health crisis and if i do i cant cofus
but the topic is sorta interesting to me possibly worth getting in few
hours or days
as to "this is domb thing" i dont think so - this topic is about architectural simplicity against winsock mess and this is nice
architectural simplicity
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
-ai dont know and i would need to check it but as far as i understood network card recives incoming data and stores it in its own buffer
(its (afait) outside of cpu work, and buffer has some size so maybe if
you put this sleep as 1 mmilisecond that the buffer of network card
will not be overfloved... how todays ntwork speeds are - it is more than
say i GB/s? with 1 ms sleep the incoming data would be 1 MB at this
speed so its not too much
ofc thw application do other things than only waiting, it also my update frame time (10 -20 ms)-a but still that simple scenario could work imo
interesting thing is hovevevr if this network card has its own ram how
its stores t in more detail (which i dont know) but logically it is
probably some ram buffer which may be indeed treated as an open file
and read by fgets/fread etc
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can scale gracefully to tens or even hundreds of thousands of simultaneous peer connections.
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can scale gracefully to tens or even hundreds of thousands of simultaneous peer connections.
On Tue, 6/9/2026 5:10 AM, Lawrence DrCOOliveiro wrote:
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can scale
gracefully to tens or even hundreds of thousands of simultaneous peer
connections.
This isn't particularly a good place to get Windows internals details.
You can use Sysinternals Process Explorer, run it as administrator,
and it has a tick counter for processes, such that you can "measure"
how many CPU clock cycles are used per update of the PE readout.
Most of the svchost, for example, DON'T USE ANY CYCLES AT ALL.
A select few svchost are cycle-pigs, and during Windows Update for example, you can see one of the svchost is railed. Which is to be expected.
It's very busy. it has a thousand packages to evaluate.
I have a power meter on the machine (on the AC plug). I will
now measure Windows desktop idle power, then boot some Linux
and compare. Windows is on a 4TB SSD. The four Linux share a 1TB SSD,
making the test a bit easier to run.
(All DEs set to the same screen resolution)
Windows 11 Home - 1920x1080 33.9W Idle
LMDE7 (cinnamon DE) 40.3W Idle
Linux Mint 223 Mate 45.7W Idle
Linux Mint 223 XFCE 46.4W Idle
Devuan 6 (cinnamon DE w.Nvidia) 34.7W Idle
Only Devuan 6 with the non-systemd init system and running X11, comes close to Windows 11.
Paul
Lawrence DrCOOliveiro pisze:
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:this standard techniques are not necesarelly much good imo...ans sleep
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can scale
gracefully to tens or even hundreds of thousands of simultaneous peer
connections.
is architecturally simple and not bad imo
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
On 09/06/2026 11:34, fir wrote:
Lawrence DrCOOliveiro pisze:
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:this standard techniques are not necesarelly much good imo...ans sleep
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can scale
gracefully to tens or even hundreds of thousands of simultaneous peer
connections.
is architecturally simple and not bad imo
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
Yes.-a A simple loop with sleep and then checking for new input is not scalable when you are doing lots of them at once, such as for a web server.-a But it is perfectly good for small, simple systems or during testing and developing, and saves a lot of effort compared to using
poll(), select(), or other such solutions.-a It usually doesn't matter if the extra wakeups and checks use a couple of percent of cpu time.-a (It
does matter, of course, when you have hundreds or thousands of such
loops on a server.)
David Brown pisze:
On 09/06/2026 11:34, fir wrote:
Lawrence DrCOOliveiro pisze:
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:this standard techniques are not necesarelly much good imo...ans
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can scale
gracefully to tens or even hundreds of thousands of simultaneous peer
connections.
sleep is architecturally simple and not bad imo
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
Yes.-a A simple loop with sleep and then checking for new input is not
scalable when you are doing lots of them at once, such as for a web
server.-a But it is perfectly good for small, simple systems or during
testing and developing, and saves a lot of effort compared to using
poll(), select(), or other such solutions.-a It usually doesn't matter
if the extra wakeups and checks use a couple of percent of cpu time.
(It does matter, of course, when you have hundreds or thousands of
such loops on a server.)
im not thinkin on the server..i am talking on most simple architecture
for reading/writing data via network especially one that can be build
arounf fopen/fclose and those functions used to read write to files
at least tcp conection seen can be totally done like that fopen(
connection) fgets, fputs, fclose() though loop and sleep also need to be invvolved
fir pisze:
David Brown pisze:as to servers though i dont think the situation would be quite different
On 09/06/2026 11:34, fir wrote:
Lawrence DrCOOliveiro pisze:
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:this standard techniques are not necesarelly much good imo...ans
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every >>>>>> or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can scale >>>>> gracefully to tens or even hundreds of thousands of simultaneous peer >>>>> connections.
sleep is architecturally simple and not bad imo
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
Yes.-a A simple loop with sleep and then checking for new input is not
scalable when you are doing lots of them at once, such as for a web
server.-a But it is perfectly good for small, simple systems or during
testing and developing, and saves a lot of effort compared to using
poll(), select(), or other such solutions.-a It usually doesn't matter
if the extra wakeups and checks use a couple of percent of cpu time.
(It does matter, of course, when you have hundreds or thousands of
such loops on a server.)
im not thinkin on the server..i am talking on most simple architecture
for reading/writing data via network especially one that can be build
arounf fopen/fclose and those functions used to read write to files
at least tcp conection seen can be totally done like that fopen(
connection) fgets, fputs, fclose() though loop and sleep also need to
be invvolved
you got
-afor(;;)
-a{
-a-a-a-a fread(..., f);
-a-a-a-a //do something
-a-a-a-a fwrite(..., f);
-a-a-a-a sleep(1);
-a}
when you got many conections there is no more loops and sleeps just more
f's in a loop
and as server has its limit it must be some entry compter that
redirects connections to servers if you have hundreds of them
no? so it seems not much more complex
i must rethink hovever how exactly it would look like when two
computers who communicates (and which are like working
in 50-100 fps mode indeed communicate (but maybe i will do it later)
On Mon, 8 Jun 2026 18:16:10 +0200, fir wrote:
Sleep(100); //wait 100 ms
ThatrCOs usually a dumb thing to do. ItrCOs either too slow if something comes in/goes out more quickly, or too much overhead if communication
is slower than that. And it just gets worse if yourCOre trying to juggle multiple connections (as a server commonly does).
Try using this <https://manpages.debian.org/poll(2)>, at least ...
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can scale gracefully to tens or even hundreds of thousands of simultaneous peer connections.
https://www.youtube.com/watch?v=XAzUoizwnXM
i dint watched it whole but it comes to my mind that those socket communication indeed should be probably made using fopen/fread/fwrite/fgetc/fputc
i was doing only basics of socket programming anver liked it and
remember almost nothing - it is becouse i dont liek stupid things
and those sockets looks stupid
i guess using this fopen it would be much better..
A select few svchost are cycle-pigs, and during Windows Update for
example, you can see one of the svchost is railed. Which is to be
expected. It's very busy. it has a thousand packages to evaluate.
ir_uring? ;^)
On 6/9/2026 2:10 AM, Lawrence DrCOOliveiro wrote:
... in regular multitasking OSes, we have these standard techniques
for maximizing responsiveness while minimizing resource usage.
Which is why systems like Linux can scale gracefully to tens or
even hundreds of thousands of simultaneous peer connections.
Well, for servers/clients in windows, IOCP is key.
Lawrence DrCOOliveiro pisze:
this standard techniques are not necesarelly much good imo...ans
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can
scale gracefully to tens or even hundreds of thousands of
simultaneous peer connections.
sleep is architecturally simple and not bad imo
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
sad nevs ai says that TCP not guarantees that whole pack would be
received and it can be only part... so it complicates code using it
a bit
On Tue, 9 Jun 2026 13:54:51 -0700, Chris M. Thomasson wrote:
ir_uring? ;^)
io_uring, you mean?
That, too, is a possibility, for even higher performance.
<https://manpages.debian.org/io_uring(7)>
On Tue, 9 Jun 2026 13:55:25 -0700, Chris M. Thomasson wrote:
On 6/9/2026 2:10 AM, Lawrence DrCOOliveiro wrote:
... in regular multitasking OSes, we have these standard techniques
for maximizing responsiveness while minimizing resource usage.
Which is why systems like Linux can scale gracefully to tens or
even hundreds of thousands of simultaneous peer connections.
Well, for servers/clients in windows, IOCP is key.
IOCP is based on the asynchronous I/O model from DECrCOs old VMS
operating system, which Dave Cutler also masterminded before moving to Microsoft to create Windows NT.
Nobody else seems to have thought it a worthwhile enough model to
copy, though. I think it requires you to have multiple I/O requests in flight, one for each connection you want to watch. This might make for
a more complicated programming model, as opposed to the simplicity of poll(2)/epoll(2).
The most critical known test of Windows Server performance was
probably the London Stock Exchange fiasco. After crowing about winning
the contract ahead of Linux-based competitors, Microsoft had to eat
humble pie after the whole setup fell flat on its face.
And was replaced with a Linux-based alternative.
IOCP is the way to go on Windows. Fwiw, I used it quite a bit around 25+ years ago back on Windows NT 4.0 Then GQCSEX came out:
https://learn.microsoft.com/en-us/windows/win32/fileio/ getqueuedcompletionstatusex-func
That is a fun one that returns more than one completion request.
However, you have to know how to use it correctly! For instance, I would gather the io completions and sort them as usually wsasends, wsarecvs, acceptex, connectex, ect into separate per thread stacks. Then execute
them in batches sometimes on another thread pool. I remember an old
paper, cohort scheduling.
https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/ tr-2001-39.pdf?msockid=156c5513e5e96cdb283d4228e46a6db8
The io worker threads should run full steam ahead and not necessarily do
any user processing. They should only block when there is no io to do at all.
struct cohort
{
-a-a-a per_io* m_recv;
-a-a-a per_io* m_send;
-a-a-a per_io* m_accept;
-a-a-a per_io* m_connect;
-a-a-a //...
};
Just heads for single linked lists of per io data wrt WSAOVERLAPPED.
Pass execute the cohort usually in another thread pool.
On Tue, 9 Jun 2026 13:54:51 -0700, Chris M. Thomasson wrote:
ir_uring? ;^)
io_uring, you mean?
That, too, is a possibility, for even higher performance.
<https://manpages.debian.org/io_uring(7)>
IOCP is the way to go on Windows.
On 6/9/2026 4:47 PM, Lawrence DrCOOliveiro wrote:
That, too, is a possibility, for even higher performance.
<https://manpages.debian.org/io_uring(7)>
Oh I think so.
I just remembered some of the "fun" functions for IOCP on Windows. TransmitPackets and TransmitFile.
https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_transmitpackets
Petty cool, except iirc the client versions of nt 4.0 nerfed them to
only two concurrent in flight calls at a time.
AcceptEx and ConnectEx were pretty cool as well.
https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex
https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_connectex
On Tue, 9 Jun 2026 13:53:28 +0200, fir wrote:
sad nevs ai says that TCP not guarantees that whole pack would be
received and it can be only part... so it complicates code using it
a bit
Why? Surely you would not try to handle an incoming request or
response until you were sure you had received the whole thing,
wouldnrCOt you?
On Tue, 9 Jun 2026 11:34:36 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
this standard techniques are not necesarelly much good imo...ans
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can
scale gracefully to tens or even hundreds of thousands of
simultaneous peer connections.
sleep is architecturally simple and not bad imo
You keep saying that, even after I point out why itrCOs a bad idea.
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
Think of how you could do enough peak throughput to saturate a gigabit Ethernet link. This is at the low end of network connection speeds
these days -- higher-performance configurations might have an order of magnitude or two greater bandwidth.
To manage it, yourCOd need to push through about 120 megabytes per
second. With your sleep-every-100ms poll, this means each I/O request
would need a buffer size of about 12 megabytes. This is ridiculously
large. And of course the 100ms latency would be unacceptable for many
uses -- think of a multiuser game server, for example.
On Tue, 9 Jun 2026 21:42:58 -0700, Chris M. Thomasson wrote:
On 6/9/2026 4:47 PM, Lawrence DrCOOliveiro wrote:
That, too, is a possibility, for even higher performance.
<https://manpages.debian.org/io_uring(7)>
Oh I think so.
I think more suited for block-device (disk/SSD) I/O, rather than
network I/O. Most network I/O (say, up to a few gigabits per second)
would most likely hit a bottleneck in the physical network interface,
rather than in the rate at which the userland code can produce/consume
the data.
Also, this: <https://manpages.debian.org/aio(7)> -- an actual POSIX
spec, not Linux-specific, perhaps not having the best performance ...
On Tue, 9 Jun 2026 21:52:39 -0700, Chris M. Thomasson wrote:
IOCP is the way to go on Windows.I think one reason why itrCOs never been adopted cross-platform is that
it requires threading to be useful. Whereas the *nix poll(2) technique
is scalable across single-threaded and multi-threaded usage.
Microsoft needs to fix its I/O handling to be more friendly to
*nix-style ways of doing things. Otherwise the Windows-specific gaps
listed on this sort of thing
<https://docs.python.org/3/library/select.html> just look
embarrassing.
On 6/9/2026 11:21 PM, Lawrence DrCOOliveiro wrote:
On Tue, 9 Jun 2026 21:42:58 -0700, Chris M. Thomasson wrote:
On 6/9/2026 4:47 PM, Lawrence DrCOOliveiro wrote:
That, too, is a possibility, for even higher performance.
<https://manpages.debian.org/io_uring(7)>
Oh I think so.
I think more suited for block-device (disk/SSD) I/O, rather than
network I/O. Most network I/O (say, up to a few gigabits per second)
would most likely hit a bottleneck in the physical network interface,
rather than in the rate at which the userland code can produce/consume
the data.
Also, this: <https://manpages.debian.org/aio(7)> -- an actual POSIX
spec, not Linux-specific, perhaps not having the best performance ...
io_uring should work fine for network I/O. io_uringrCOs benefits only
appear at extreme scale?
Lawrence DrCOOliveiro pisze:
On Tue, 9 Jun 2026 11:34:36 +0200, fir wrote:this 100 ms was an example not more meaning than using "foo" name if you
Lawrence DrCOOliveiro pisze:
this standard techniques are not necesarelly much good imo...ans
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every
or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can
scale gracefully to tens or even hundreds of thousands of
simultaneous peer connections.
sleep is architecturally simple and not bad imo
You keep saying that, even after I point out why itrCOs a bad idea.
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
Think of how you could do enough peak throughput to saturate a gigabit
Ethernet link. This is at the low end of network connection speeds
these days -- higher-performance configurations might have an order of
magnitude or two greater bandwidth.
To manage it, yourCOd need to push through about 120 megabytes per
second. With your sleep-every-100ms poll, this means each I/O request
would need a buffer size of about 12 megabytes. This is ridiculously
large. And of course the 100ms latency would be unacceptable for many
uses -- think of a multiuser game server, for example.
can change "foo" into "boo" then you can turn 100 ms into 0.1 ms
i hope youre not think i would put 100 ms in a situation when you need 1
ms or 0.1 ms...if you think so yure exceptionally vrong
this polling in active loop is generally good becouse it is so simple it
nt rises complications..you dont need additionsl thread, you dont hang
on input etc.. note also polling is very almost extremally cheep
becouse if-a you do some check then rise sleep
for(;;)
{
if(someting_here) {}
sleep(0.1)
}
then loop and if takes few cycles, where sleep 0.1 ms takes about 300
000 cycles (switching cpu off to another route tales also some) so the
cost is microscopic... i dont think alternative methods are faster
On 6/10/2026 12:06 AM, fir wrote:
Lawrence DrCOOliveiro pisze:
On Tue, 9 Jun 2026 11:34:36 +0200, fir wrote:this 100 ms was an example not more meaning than using "foo" name if
Lawrence DrCOOliveiro pisze:
this standard techniques are not necesarelly much good imo...ans
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic
windows function which sleeps main thread for n miliseconds, every >>>>>> or nearly every (afait) windows app uses it so its totally notmall
Maybe normal in Windows, but in regular multitasking OSes, we have
these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can
scale gracefully to tens or even hundreds of thousands of
simultaneous peer connections.
sleep is architecturally simple and not bad imo
You keep saying that, even after I point out why itrCOs a bad idea.
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
Think of how you could do enough peak throughput to saturate a gigabit
Ethernet link. This is at the low end of network connection speeds
these days -- higher-performance configurations might have an order of
magnitude or two greater bandwidth.
To manage it, yourCOd need to push through about 120 megabytes per
second. With your sleep-every-100ms poll, this means each I/O request
would need a buffer size of about 12 megabytes. This is ridiculously
large. And of course the 100ms latency would be unacceptable for many
uses -- think of a multiuser game server, for example.
you can change "foo" into "boo" then you can turn 100 ms into 0.1 ms
i hope youre not think i would put 100 ms in a situation when you need
1 ms or 0.1 ms...if you think so yure exceptionally vrong
this polling in active loop is generally good becouse it is so simple
it nt rises complications..you dont need additionsl thread, you dont hang
on input etc.. note also polling is very almost extremally cheep
becouse if-a you do some check then rise sleep
for(;;)
{
if(someting_here) {}
sleep(0.1)
}
then loop and if takes few cycles, where sleep 0.1 ms takes about 300
000 cycles (switching cpu off to another route tales also some) so the
cost is microscopic... i dont think alternative methods are faster
why sleep? You should be waiting for IO to complete. The only time a io thread should block is when there is no IO to do. The server is idle.
On Tue, 9 Jun 2026 13:55:25 -0700, Chris M. Thomasson wrote:
On 6/9/2026 2:10 AM, Lawrence DrCOOliveiro wrote:
... in regular multitasking OSes, we have these standard techniques
for maximizing responsiveness while minimizing resource usage.
Which is why systems like Linux can scale gracefully to tens or
even hundreds of thousands of simultaneous peer connections.
Well, for servers/clients in windows, IOCP is key.
IOCP is based on the asynchronous I/O model from DECrCOs old VMS
operating system, which Dave Cutler also masterminded before moving to >Microsoft to create Windows NT.
Nobody else seems to have thought it a worthwhile enough model to
copy, though. I think it requires you to have multiple I/O requests in >flight, one for each connection you want to watch. This might make for
a more complicated programming model, as opposed to the simplicity of >poll(2)/epoll(2).
Chris M. Thomasson pisze:
On 6/10/2026 12:06 AM, fir wrote:
Lawrence DrCOOliveiro pisze:
On Tue, 9 Jun 2026 11:34:36 +0200, fir wrote:this 100 ms was an example not more meaning than using "foo" name if
Lawrence DrCOOliveiro pisze:
this standard techniques are not necesarelly much good imo...ans
On Tue, 9 Jun 2026 08:56:00 +0200, fir wrote:
you know what sleep() function is its extremally often used basic >>>>>>> windows function which sleeps main thread for n miliseconds, every >>>>>>> or nearly every (afait) windows app uses it so its totally notmall >>>>>>Maybe normal in Windows, but in regular multitasking OSes, we have >>>>>> these standard techniques for maximizing responsiveness while
minimizing resource usage. Which is why systems like Linux can
scale gracefully to tens or even hundreds of thousands of
simultaneous peer connections.
sleep is architecturally simple and not bad imo
You keep saying that, even after I point out why itrCOs a bad idea.
this is also not inneficient - its efficient as it returns power to
system (somore app uses sleep more lightweight it is i would say)
Think of how you could do enough peak throughput to saturate a gigabit >>>> Ethernet link. This is at the low end of network connection speeds
these days -- higher-performance configurations might have an order of >>>> magnitude or two greater bandwidth.
To manage it, yourCOd need to push through about 120 megabytes per
second. With your sleep-every-100ms poll, this means each I/O request
would need a buffer size of about 12 megabytes. This is ridiculously
large. And of course the 100ms latency would be unacceptable for many
uses -- think of a multiuser game server, for example.
you can change "foo" into "boo" then you can turn 100 ms into 0.1 ms
i hope youre not think i would put 100 ms in a situation when you
need 1 ms or 0.1 ms...if you think so yure exceptionally vrong
this polling in active loop is generally good becouse it is so simple
it nt rises complications..you dont need additionsl thread, you dont
hang
on input etc.. note also polling is very almost extremally cheep
becouse if-a you do some check then rise sleep
for(;;)
{
if(someting_here) {}
sleep(0.1)
}
then loop and if takes few cycles, where sleep 0.1 ms takes about 300
000 cycles (switching cpu off to another route tales also some) so the
cost is microscopic... i dont think alternative methods are faster
why sleep? You should be waiting for IO to complete. The only time a
io thread should block is when there is no IO to do. The server is idle.
why you think YOU SHOULD be waiting? waiting makes some complications
(like for example you can wait only on one thing - so its like BRAIN
OFF) in general you should monitor conditions activelly and react accordingly imo
On Mon, 8 Jun 2026 18:16:10 +0200, fir wrote:
Sleep(100); //wait 100 ms
ThatrCOs usually a dumb thing to do.
ItrCOs either too slow if something
comes in/goes out more quickly, or too much overhead if communication
is slower than that. And it just gets worse if yourCOre trying to juggle multiple connections (as a server commonly does).
Try using this <https://manpages.debian.org/poll(2)>, at least ...
why you think YOU SHOULD be waiting? waiting makes some
complications (like for example you can wait only on one thing ...
Windows I/O is unified and async across all device types rCo thatrCOs
the whole point of IOCP.
If anything, Unix is the one still trying to catch up with a real
async model (see: io_uring).
Actually, its lower level than IOCP. We have to manage our own ring
buffers.
But IOCP and io_uring has an interesting mapping... They are fairly
damn similar! IOCP and io_uring map onto each other in a way thatrCOs
almost eerie. TheyrCOre not identical, but conceptually they solve the
same problem with almost the same architecture, just at different
abstraction levels...
On 6/8/2026 5:28 PM, Lawrence DrCOOliveiro wrote:
On Mon, 8 Jun 2026 18:16:10 +0200, fir wrote:
Sleep(100); //wait 100 ms
ThatrCOs usually a dumb thing to do.
More ignorant than dumb wrt to fir?
On Tue, 9 Jun 2026 23:01:28 -0700, Chris M. Thomasson wrote:
I just remembered some of the "fun" functions for IOCP on Windows.
TransmitPackets and TransmitFile.
https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_transmitpackets
Why do you need separate calls for rCLsocketsrCY versus rCLfilesrCY?
I was looking for equivalent Linux calls, and found a remarkable number:
<https://manpages.debian.org/copy_file_range(2)> <https://manpages.debian.org/sendfile(2)> <https://manpages.debian.org/splice(2)> <https://manpages.debian.org/vmsplice(2)>
Petty cool, except iirc the client versions of nt 4.0 nerfed them to
only two concurrent in flight calls at a time.
AcceptEx and ConnectEx were pretty cool as well.
https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex
https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_connectex
Mainly to avoid a separate I/O call to send/receive the first lot of
data? Does it do that much for performance?
On 6/9/2026 11:47 PM, Lawrence DrCOOliveiro wrote:
Mainly to avoid a separate I/O call to send/receive the first lot
of data? Does it do that much for performance?
Send it right from memory. It handles everything. It completes with
a status. It way more efficient than sending a file via WSASend'.
On Wed, 10 Jun 2026 00:31:38 -0700, Chris M. Thomasson wrote:
Actually, its lower level than IOCP. We have to manage our own ring
buffers.
But IOCP and io_uring has an interesting mapping... They are fairly
damn similar! IOCP and io_uring map onto each other in a way thatrCOs
almost eerie. TheyrCOre not identical, but conceptually they solve the
same problem with almost the same architecture, just at different
abstraction levels...
I think a key point of io_uring is to minimize the frequency of user/kernel-mode transitions.
One limitation of Windows is that, unlike *nix systems, you cannot
share open file descriptions (particularly network connections, named
pipes, I/O completion ports, etc) between processes.
Sharing a single IOCP between different processes, is well. Probably
going to not work. Never did that anyway.
On Thu, 11 Jun 2026 13:27:22 -0700, Chris M. Thomasson wrote:
On 6/9/2026 11:47 PM, Lawrence DrCOOliveiro wrote:
Mainly to avoid a separate I/O call to send/receive the first lot
of data? Does it do that much for performance?
Send it right from memory. It handles everything. It completes with
a status. It way more efficient than sending a file via WSASend'.
But that only works for a small amount of data. For which you might as
well use datagrams (e.g. UDP) rather than a full virtual circuit
(e.g. TCP).
On 6/11/2026 6:35 PM, Lawrence DrCOOliveiro wrote:
On Thu, 11 Jun 2026 13:27:22 -0700, Chris M. Thomasson wrote:
On 6/9/2026 11:47 PM, Lawrence DrCOOliveiro wrote:
Mainly to avoid a separate I/O call to send/receive the first lot
of data? Does it do that much for performance?
Send it right from memory. It handles everything. It completes with
a status. It way more efficient than sending a file via WSASend'.
But that only works for a small amount of data. For which you might as
well use datagrams (e.g. UDP) rather than a full virtual circuit
(e.g. TCP).
What that is besides the point in a sense, category error, perhaps? TransmitPackets is an efficient way to send some things, winnt client
nerf aside for a moment. Actually, around 25+ years ago, I had a system where you would make a TCP connection, and use UDP for sending a file.
The packets had file offsets where the receiver knew where to write them
to say a memory mapped file. The TCP connection would handle basic
tasks, the UDP for for bulk data transfer. A fun experiment.
Actually, on Windows we should use TransmitPackets wherever we can.
https://www.youtube.com/watch?v=XAzUoizwnXM
i dint watched it whole but it comes to my mind that those socket communication indeed should be probably made using fopen/fread/fwrite/ fgetc/fputc
i was doing only basics of socket programming anver liked it and
remember almost nothing - it is becouse i dont liek stupid things
and those sockets looks stupid
i guess using this fopen it would be much better..
whot would you need i assume you need to fopen connection to distant machine..not sure if it should be one the same for read write or two
one for read and one for write..then i think the network card should
have buffer whete there is stacked incoming data, same for outcoming
data,a nd thats all as to basics probably..no hanging controll no
additional threads..just like working with files
whough additional soft could be written too, based on thai but it should
be sane thing something based like with working with files (knowing
those files are ram files and are contents of incoming and outcoming buffer thise sockets todajy i dont remember but in my vague mameory it feels
like shit
feel free to comment on this topic if you want
On Sat, 13 Jun 2026 14:32:24 -0700, Chris M. Thomasson wrote:
Actually, on Windows we should use TransmitPackets wherever we can.
I was wondering why there are two separate API functions, rCLTransmitPacketsrCY versus rCLTransmitFilerCY. It turns out the latter <https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile>
... only supports connection-oriented sockets of type SOCK_STREAM,
SOCK_SEQPACKET, and SOCK_RDM. Sockets of type SOCK_DGRAM and
SOCK_RAW are not supported. The TransmitPackets function can be
used with sockets of type SOCK_DGRAM.
So there is some kind of overlap of functionality, but the two are
optimized for slightly different application areas.
Oddly, the docs for the former <https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_transmitpackets>
make no mention of SOCK_DGRAM. Is this call in fact suitable for *all*
socket connection types? However, note this caveat:
Expect better performance results when using the TransmitPackets
function on Windows Server 2003.
DoesnrCOt that apply to newer versions? Are you supposed to stick with
Server 2003 to get the best out of it? Also, this:
The TransmitPackets function is optimized according to the
operating system on which it is used:
rCo On Windows server editions, the TransmitPackets function is
optimized for high performance.
rCo On Windows client editions, the TransmitPackets function is
optimized for minimum memory and resource utilization.
So you need to use different calls to get high performance depending
on the edition of Windows yourCOre running on?
Seems like thererCOs a hodge-podge of motley functionality there, added
to and modified over time by different groups with no clear overall
vision driving things.
ConwayrCOs Law applies, I guess ...
On 6/13/2026 5:45 PM, Lawrence DrCOOliveiro wrote:
<https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_transmitpackets>
... note this caveat:
Expect better performance results when using the TransmitPackets
function on Windows Server 2003.
DoesnrCOt that apply to newer versions? Are you supposed to stick
with Server 2003 to get the best out of it?
It applies to new versions.
What do you think of AcceptEx and ConnectEx? ;^)
On Sun, 14 Jun 2026 13:55:58 -0700, Chris M. Thomasson wrote:
On 6/13/2026 5:45 PM, Lawrence DrCOOliveiro wrote:
<https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_transmitpackets>
... note this caveat:
Expect better performance results when using the TransmitPackets
function on Windows Server 2003.
DoesnrCOt that apply to newer versions? Are you supposed to stick
with Server 2003 to get the best out of it?
It applies to new versions.
But the docs donrCOt say so. YourCOre just assuming that.
What do you think of AcceptEx and ConnectEx? ;^)
They seem optimized for circuit-oriented connections which
send/receive very small amounts of data ... and unencrypted ones, at
that. Is this a common use-case in the Windows world?
On 6/15/2026 9:36 PM, Lawrence DrCOOliveiro wrote:
On Sun, 14 Jun 2026 13:55:58 -0700, Chris M. Thomasson wrote:
On 6/13/2026 5:45 PM, Lawrence DrCOOliveiro wrote:
<https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-
mswsock-lpfn_transmitpackets>
... note this caveat:
-a-a-a-a-a Expect better performance results when using the TransmitPackets
-a-a-a-a-a function on Windows Server 2003.
DoesnrCOt that apply to newer versions? Are you supposed to stick
with Server 2003 to get the best out of it?
It applies to new versions.
But the docs donrCOt say so. YourCOre just assuming that.
TransmitPackets/TransmitFile works on new windows. do you mean the performance benefit carries forward, or the API itself works? API works fine.
What do you think of AcceptEx and ConnectEx? ;^)
They seem optimized for circuit-oriented connections which
send/receive very small amounts of data ... and unencrypted ones, at
that. Is this a common use-case in the Windows world?
unencrypted ones? Why should they encrypt? The user needs to do that
before it sends anything.
On 6/15/2026 9:36 PM, Lawrence DrCOOliveiro wrote:
They seem optimized for circuit-oriented connections which
send/receive very small amounts of data ... and unencrypted ones,
at that. Is this a common use-case in the Windows world?
unencrypted ones? Why should they encrypt? The user needs to do that
before it sends anything.
On Tue, 16 Jun 2026 13:08:49 -0700, Chris M. Thomasson wrote:
On 6/15/2026 9:36 PM, Lawrence DrCOOliveiro wrote:
They seem optimized for circuit-oriented connections which
send/receive very small amounts of data ... and unencrypted ones,
at that. Is this a common use-case in the Windows world?
unencrypted ones? Why should they encrypt? The user needs to do that
before it sends anything.
The gold-standard protocol for doing this, namely TLS, requires a Diffie-Hellman exchange to set up the one-off session key for the
connection. That takes more than one packet in each direction.
fir pisze:
https://www.youtube.com/watch?v=XAzUoizwnXMmaybe someone who has some experience with socked programming know how
i dint watched it whole but it comes to my mind that those socket
communication indeed should be probably made using fopen/fread/fwrite/
fgetc/fputc
i was doing only basics of socket programming anver liked it and
remember almost nothing - it is becouse i dont liek stupid things
and those sockets looks stupid
i guess using this fopen it would be much better..
whot would you need i assume you need to fopen connection to distant
machine..not sure if it should be one the same for read write or two
one for read and one for write..then i think the network card should
have buffer whete there is stacked incoming data, same for outcoming
data,a nd thats all as to basics probably..no hanging controll no
additional threads..just like working with files
whough additional soft could be written too, based on thai but it
should be sane thing something based like with working with files
(knowing those files are ram files and are contents of incoming and
outcoming buffer
thise sockets todajy i dont remember but in my vague mameory it feels
like shit
feel free to comment on this topic if you want
the basic communication would look like using this fopen scheme
main()
{
-a-a FILE* f = fopen("1.2.3.4:555");
-a fprintf(f, "hello there\n"); fflush(f);
-a for(int i=0; i<100; i++)
-a {
-a-a-a static char buf[4096];
-a-a-a if(fgets(buf, sizeof(buf), f))
-a-a-a-a-a-a printf("incoming: %s", buf);
-a-a-a Sleep(100); //wait 100 ms
-a }
}
something like that?
On 6/16/2026 8:11 PM, Lawrence DrCOOliveiro wrote:
On Tue, 16 Jun 2026 13:08:49 -0700, Chris M. Thomasson wrote:
On 6/15/2026 9:36 PM, Lawrence DrCOOliveiro wrote:
They seem optimized for circuit-oriented connections which
send/receive very small amounts of data ... and unencrypted ones,
at that. Is this a common use-case in the Windows world?
unencrypted ones? Why should they encrypt? The user needs to do
that before it sends anything.
The gold-standard protocol for doing this, namely TLS, requires a
Diffie-Hellman exchange to set up the one-off session key for the
connection. That takes more than one packet in each direction.
ConnectEx can optionally send data. That data is a bag o bytes.
Encrypted or not. How one sets that up is up to them.
On Wed, 17 Jun 2026 12:13:19 -0700, Chris M. Thomasson wrote:
On 6/16/2026 8:11 PM, Lawrence DrCOOliveiro wrote:
On Tue, 16 Jun 2026 13:08:49 -0700, Chris M. Thomasson wrote:
On 6/15/2026 9:36 PM, Lawrence DrCOOliveiro wrote:
They seem optimized for circuit-oriented connections which
send/receive very small amounts of data ... and unencrypted ones,
at that. Is this a common use-case in the Windows world?
unencrypted ones? Why should they encrypt? The user needs to do
that before it sends anything.
The gold-standard protocol for doing this, namely TLS, requires a
Diffie-Hellman exchange to set up the one-off session key for the
connection. That takes more than one packet in each direction.
ConnectEx can optionally send data. That data is a bag o bytes.
Encrypted or not. How one sets that up is up to them.
Not really enough to set up an encryption session, as I said. Just
seems optimized for circuit-oriented connections which send/receive
small amounts of unencrypted data.
Is this a common use-case in the Windows world?
On 6/17/2026 4:47 PM, Lawrence DrCOOliveiro wrote:
On Wed, 17 Jun 2026 12:13:19 -0700, Chris M. Thomasson wrote:
On 6/16/2026 8:11 PM, Lawrence DrCOOliveiro wrote:
The gold-standard protocol for doing this, namely TLS, requires a
Diffie-Hellman exchange to set up the one-off session key for the
connection. That takes more than one packet in each direction.
ConnectEx can optionally send data. That data is a bag o bytes.
Encrypted or not. How one sets that up is up to them.
Not really enough to set up an encryption session, as I said. Just
seems optimized for circuit-oriented connections which send/receive
small amounts of unencrypted data.
Is this a common use-case in the Windows world?
Well, ConnectEx can send the initial DH exchange bytes right on connect.
But that is up to the user... Right?
(could almost go as far as to mimic Windows drive letters ...
On Wed, 17 Jun 2026 18:41:57 -0500, BGB wrote:
(could almost go as far as to mimic Windows drive letters ...
Oh gods, no ...
On Wed, 17 Jun 2026 20:26:00 -0700, Chris M. Thomasson wrote:
On 6/17/2026 4:47 PM, Lawrence DrCOOliveiro wrote:
On Wed, 17 Jun 2026 12:13:19 -0700, Chris M. Thomasson wrote:
On 6/16/2026 8:11 PM, Lawrence DrCOOliveiro wrote:
The gold-standard protocol for doing this, namely TLS, requires a
Diffie-Hellman exchange to set up the one-off session key for the
connection. That takes more than one packet in each direction.
ConnectEx can optionally send data. That data is a bag o bytes.
Encrypted or not. How one sets that up is up to them.
Not really enough to set up an encryption session, as I said. Just
seems optimized for circuit-oriented connections which send/receive
small amounts of unencrypted data.
Is this a common use-case in the Windows world?
Well, ConnectEx can send the initial DH exchange bytes right on connect.
But that is up to the user... Right?
The TLS setup exchange is diagrammed here <https://www.rfc-editor.org/info/rfc8446/#section-2>. There are three phases:
1) Key exchange: ClientHello + ServerHello -- one message in each direction
2) Server parameters -- two messages from server to client
3) Authentication -- three messages in each direction.
Hard to see how to fit all that into a single ConnectEx + AcceptEx ...
On 6/18/2026 12:30 AM, Lawrence DrCOOliveiro wrote:
On Wed, 17 Jun 2026 20:26:00 -0700, Chris M. Thomasson wrote:
On 6/17/2026 4:47 PM, Lawrence DrCOOliveiro wrote:
On Wed, 17 Jun 2026 12:13:19 -0700, Chris M. Thomasson wrote:
On 6/16/2026 8:11 PM, Lawrence DrCOOliveiro wrote:
The gold-standard protocol for doing this, namely TLS, requires a
Diffie-Hellman exchange to set up the one-off session key for the
connection. That takes more than one packet in each direction.
ConnectEx can optionally send data. That data is a bag o bytes.
Encrypted or not. How one sets that up is up to them.
Not really enough to set up an encryption session, as I said. Just
seems optimized for circuit-oriented connections which send/receive
small amounts of unencrypted data.
Is this a common use-case in the Windows world?
Well, ConnectEx can send the initial DH exchange bytes right on connect. >>> But that is up to the user... Right?
The TLS setup exchange is diagrammed here
<https://www.rfc-editor.org/info/rfc8446/#section-2>. There are three
phases:
-a-a 1) Key exchange: ClientHello + ServerHello -- one message in each
direction
-a-a 2) Server parameters -- two messages from server to client
-a-a 3) Authentication -- three messages in each direction.
Hard to see how to fit all that into a single ConnectEx + AcceptEx ...
The ConnectEx can be the ClientHello at least. ;^)
On 6/18/2026 12:30 AM, Lawrence DrCOOliveiro wrote:
The TLS setup exchange is diagrammed here
<https://www.rfc-editor.org/info/rfc8446/#section-2>. There are
three phases:
1) Key exchange: ClientHello + ServerHello -- one message in
each direction
2) Server parameters -- two messages from server to client
3) Authentication -- three messages in each direction.
Hard to see how to fit all that into a single ConnectEx + AcceptEx
...
The ConnectEx can be the ClientHello at least. ;^)
Just that it is also not a huge leap from:
tcp://whatever
udp://whatever
http://whatever
ftp://whatever
...
To:
c:/whatever...
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
tcp://whatever
udp://whatever
http://whatever
ftp://whatever
...
To:
c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not
even in a unique fashion, like with a volume UUID or something, but
with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed
to be unique or persistent.
Remember, we already have
file://whatever
for denoting files on the local filesystem. That allows the rCLwhateverrCY part to span the entire filesystem, not just one volume/drive.
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not
even in a unique fashion, like with a volume UUID or something, but
with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed
to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives to
the same letter on each boot.
But, yeah, probably wouldn't do it the Windows way. Either they could be specified as mounts (in mtab or such), or possibly treated as aliases, say:
-a c:/ aliases to /mnt/c
Though, granted, not much particular reason to do this...
Remember, we already have
-a-a-a-a file://whatever
for denoting files on the local filesystem. That allows the rCLwhateverrCY >> part to span the entire filesystem, not just one volume/drive.
Maybe, but you wouldn't need "file://" for "fopen()" or similar, since
it is sort of an implied default in this case.
Then again, going into the weeds on this:
Would, say:
-a cd ftp://foo.org/pub/
-a ls
Even really make sense?...
Or, would it be better to ask people to at least mount it into the VFS
or similar?...
Well, or other mysteries, like, say:
Should usermode applications be allowed to export COM-like interfaces
that could then be mounted into the VFS?...
Say, for example, an application exports an IFileSystem or IMount
interface to the VFS, and then one can issue a "mount" on it. Would need some way for the VFS do deal gracefully if the application becomes unresponsive or crashes though (preferably without nuking the whole OS
in the process).
Vs, say, assuming programs that export interfaces (as services) to be at least semi trsusted / stable...
On newer [Windows], the OS remembers and will assign the same drives
to the same letter on each boot.
Maybe, but you wouldn't need "file://" for "fopen()" or similar,
since it is sort of an implied default in this case.
May seem like a waste to burn a thread on each object listener, but
no real better option at present.
Then again, going into the weeds on this:
Would, say:
cd ftp://foo.org/pub/
ls
Even really make sense?...
Or, would it be better to ask people to at least mount it into the VFS
or similar?...
On 19/06/2026 08:20, BGB wrote:
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not
even in a unique fashion, like with a volume UUID or something, but
with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed >>> to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives to
the same letter on each boot.
I am not sure what you call "newer", but IIRC Windows has done that
since Windows 3.1.-a The only letters you could assign yourself were for network drives, and they were persistent if you choose "persistent=yes".
Later versions of Windows (maybe NT4 or W2K?-a I can't remember the
details) let you choose the letter to use for other drives, such as additional harddrives, CD-ROMs and later still, USB drives.-a Those
choices were persistent.
Automatically chosen drive letters were, of course, inconsistent.-a And
when you have a lot of drives and network shares, they run out.
But, yeah, probably wouldn't do it the Windows way. Either they could
be specified as mounts (in mtab or such), or possibly treated as
aliases, say:
-a-a c:/ aliases to /mnt/c
Drive letters make sense when users wanted to distinguish between their
3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still usable
when you had a hard drive with one partition.-a Once it was realistic to have two drives in the one PC, and more than one partition on a disk,
they were outdated and too restrictive for comfort.
On 19/06/2026 07:56, David Brown wrote:
On 19/06/2026 08:20, BGB wrote:
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not
even in a unique fashion, like with a volume UUID or something, but
with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed >>>> to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives to
the same letter on each boot.
I am not sure what you call "newer", but IIRC Windows has done that
since Windows 3.1.-a The only letters you could assign yourself were for
network drives, and they were persistent if you choose "persistent=yes".
Later versions of Windows (maybe NT4 or W2K?-a I can't remember the
details) let you choose the letter to use for other drives, such as
additional harddrives, CD-ROMs and later still, USB drives.-a Those
choices were persistent.
Automatically chosen drive letters were, of course, inconsistent.-a And
when you have a lot of drives and network shares, they run out.
But, yeah, probably wouldn't do it the Windows way. Either they could
be specified as mounts (in mtab or such), or possibly treated as
aliases, say:
-a-a c:/ aliases to /mnt/c
Drive letters make sense when users wanted to distinguish between their
3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still usable
when you had a hard drive with one partition.-a Once it was realistic to
have two drives in the one PC, and more than one partition on a disk,
they were outdated and too restrictive for comfort.
How would you distinguish between two floppy drives on a Unix-like file >system?
If writing a common shell script for other people to use on their own >machines, would you be able to use the same designations?
On 19/06/2026 07:56, David Brown wrote:
On 19/06/2026 08:20, BGB wrote:
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not
even in a unique fashion, like with a volume UUID or something, but
with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed >>>> to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives to
the same letter on each boot.
I am not sure what you call "newer", but IIRC Windows has done that
since Windows 3.1.-a The only letters you could assign yourself were
for network drives, and they were persistent if you choose
"persistent=yes".
Later versions of Windows (maybe NT4 or W2K?-a I can't remember the
details) let you choose the letter to use for other drives, such as
additional harddrives, CD-ROMs and later still, USB drives.-a Those
choices were persistent.
Automatically chosen drive letters were, of course, inconsistent.-a And
when you have a lot of drives and network shares, they run out.
But, yeah, probably wouldn't do it the Windows way. Either they could
be specified as mounts (in mtab or such), or possibly treated as
aliases, say:
-a-a c:/ aliases to /mnt/c
Drive letters make sense when users wanted to distinguish between
their 3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still
usable when you had a hard drive with one partition.-a Once it was
realistic to have two drives in the one PC, and more than one
partition on a disk, they were outdated and too restrictive for comfort.
How would you distinguish between two floppy drives on a Unix-like file system?
If writing a common shell script for other people to use on their own machines, would you be able to use the same designations?
In article <11132u8$37hrh$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
On 19/06/2026 07:56, David Brown wrote:
On 19/06/2026 08:20, BGB wrote:
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not >>>>> even in a unique fashion, like with a volume UUID or something, but
with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed >>>>> to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives to
the same letter on each boot.
I am not sure what you call "newer", but IIRC Windows has done that
since Windows 3.1.-a The only letters you could assign yourself were for >>> network drives, and they were persistent if you choose "persistent=yes". >>>
Later versions of Windows (maybe NT4 or W2K?-a I can't remember the
details) let you choose the letter to use for other drives, such as
additional harddrives, CD-ROMs and later still, USB drives.-a Those
choices were persistent.
Automatically chosen drive letters were, of course, inconsistent.-a And
when you have a lot of drives and network shares, they run out.
But, yeah, probably wouldn't do it the Windows way. Either they could
be specified as mounts (in mtab or such), or possibly treated as
aliases, say:
-a-a c:/ aliases to /mnt/c
Drive letters make sense when users wanted to distinguish between their
3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still usable
when you had a hard drive with one partition.-a Once it was realistic to >>> have two drives in the one PC, and more than one partition on a disk,
they were outdated and too restrictive for comfort.
How would you distinguish between two floppy drives on a Unix-like file
system?
Based on the directory name where you mount them.
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
You don't. You parameterize it. Why would I want to restrict a
shell script to only working with the contents of floppy disks?
Obligatory plan 9 example:
cpu% grep floppy /dev/drivers
#f floppy
cpu% ls '#f'
'#f/fd0ctl'
'#f/fd0disk'
'#f/fd1ctl'
'#f/fd1disk'
cpu% bind -a '#f' /dev
cpu% ls -l /dev/fd0disk
--rw-rw---- f 0 bootes bootes 1474560 Sep 20 2021 /dev/fd0disk
cpu% dossrv
dossrv: serving #s/dos
cpu% mount -c /srv/dos /n/floppy0 /dev/fd0disk
cpu% mount -c /srv/dos /n/floppy1 /dev/fd1disk
cpu%
This was all wrapped up into a shell script:
cpu% cat /bin/a:
#!/bin/rc
rfork e
flop=/dev/fd0disk
if(! test -r $flop)
flop='#f'/fd0disk
if(! test -f /srv/dos)
dossrv >/dev/null </dev/null >[2]/dev/null
unmount /n/a:>[2]/dev/null
mount -c /srv/dos /n/a: $flop
unmount /n/a >[2]/dev/null
mount -c /srv/dos /n/a $flop
cpu%
The floppy device is built into the kernel. The names relative
to `/n` are arbitrary; the contents of both floppies are now
available on /n/floppy0 and /n/floppy1 respectively. `dossrv`
is a program that implements a few variations of FAT
filesystems.
The key observation is that shoehorning everything into `open`
is the wrong model; instead, conceptually splitting into
separate `mount` and access operations simplifies and permits
composition. Making `mount` unprivileged and allowing the user
to control their view of the file namespace makes all of this
natural.
On 19/06/2026 11:42, Bart wrote:
On 19/06/2026 07:56, David Brown wrote:
On 19/06/2026 08:20, BGB wrote:
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not >>>>> even in a unique fashion, like with a volume UUID or something, but
with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed >>>>> to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives
to the same letter on each boot.
I am not sure what you call "newer", but IIRC Windows has done that
since Windows 3.1.-a The only letters you could assign yourself were
for network drives, and they were persistent if you choose
"persistent=yes".
Later versions of Windows (maybe NT4 or W2K?-a I can't remember the
details) let you choose the letter to use for other drives, such as
additional harddrives, CD-ROMs and later still, USB drives.-a Those
choices were persistent.
Automatically chosen drive letters were, of course, inconsistent.
And when you have a lot of drives and network shares, they run out.
But, yeah, probably wouldn't do it the Windows way. Either they
could be specified as mounts (in mtab or such), or possibly treated
as aliases, say:
-a-a c:/ aliases to /mnt/c
Drive letters make sense when users wanted to distinguish between
their 3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still
usable when you had a hard drive with one partition.-a Once it was
realistic to have two drives in the one PC, and more than one
partition on a disk, they were outdated and too restrictive for comfort.
How would you distinguish between two floppy drives on a Unix-like
file system?
To be honest, I have never come across the need.-a In my university days (with SunOS, then Solaris) the machines did not have floppies - most did
not even have hard disks.-a By the time I started using Linux, at about
the turn of the century, floppies were out of fashion.
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
Filesystems are mounted on *nix systems.-a The exact placement of mount points varies, as does the extent to which attached filesystems are automounted, or the user is informed and given a choice, or mounting is manual.-a Different *nix systems have different habits, and in Linux it
can vary by distro or desktop.-a And then administrators or users can
have their own choices.
Hardware is different - if I need to use a floppy these days, it would
be via a USB floppy drive.-a More realistically, people would use USB
memory sticks now.-a But someone might have several USB mass storage
devices attached - I would not presume to know which they want to use
for this script or program.-a So I would say the script should either require a path (for file / directory access - and I can't think why it
would be limited to a floppy), or a device name (for something like a
flash image writer).-a It would likely be better to have a gui or menu choice for some programs.-a Getting lists of the available block devices, mounted systems, filesystem types, etc., and detailed information about
the devices, is not hard on Linux - but I don't know how portable that
might be to other *nix systems.
On 19/06/2026 12:46, David Brown wrote:
On 19/06/2026 11:42, Bart wrote:
On 19/06/2026 07:56, David Brown wrote:
On 19/06/2026 08:20, BGB wrote:
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not >>>>>> even in a unique fashion, like with a volume UUID or something, but >>>>>> with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed
to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives
to the same letter on each boot.
I am not sure what you call "newer", but IIRC Windows has done that
since Windows 3.1.-a The only letters you could assign yourself were
for network drives, and they were persistent if you choose
"persistent=yes".
Later versions of Windows (maybe NT4 or W2K?-a I can't remember the
details) let you choose the letter to use for other drives, such as
additional harddrives, CD-ROMs and later still, USB drives.-a Those
choices were persistent.
Automatically chosen drive letters were, of course, inconsistent.
And when you have a lot of drives and network shares, they run out.
But, yeah, probably wouldn't do it the Windows way. Either they
could be specified as mounts (in mtab or such), or possibly treated >>>>> as aliases, say:
-a-a c:/ aliases to /mnt/c
Drive letters make sense when users wanted to distinguish between
their 3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still >>>> usable when you had a hard drive with one partition.-a Once it was
realistic to have two drives in the one PC, and more than one
partition on a disk, they were outdated and too restrictive for
comfort.
How would you distinguish between two floppy drives on a Unix-like
file system?
To be honest, I have never come across the need.-a In my university
days (with SunOS, then Solaris) the machines did not have floppies -
most did not even have hard disks.-a By the time I started using Linux,
at about the turn of the century, floppies were out of fashion.
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
Filesystems are mounted on *nix systems.-a The exact placement of mount
points varies, as does the extent to which attached filesystems are
automounted, or the user is informed and given a choice, or mounting
is manual.-a Different *nix systems have different habits, and in Linux
it can vary by distro or desktop.-a And then administrators or users
can have their own choices.
Hardware is different - if I need to use a floppy these days, it would
be via a USB floppy drive.-a More realistically, people would use USB
memory sticks now.-a But someone might have several USB mass storage
devices attached - I would not presume to know which they want to use
for this script or program.-a So I would say the script should either
require a path (for file / directory access - and I can't think why it
would be limited to a floppy), or a device name (for something like a
flash image writer).-a It would likely be better to have a gui or menu
choice for some programs.-a Getting lists of the available block
devices, mounted systems, filesystem types, etc., and detailed
information about the devices, is not hard on Linux - but I don't know
how portable that might be to other *nix systems.
If you plug in a USB pen drive on Windows, it will be under a drive
letter, but that it is not guaranteed to be consistent, especially if
you plug in more than one.
So that is a problem. It would be useful, IMV, if the USB sockets were labeled with specific letters.
So, what's it like under Linux: if I plug a pen drive into my RPi, then
the files will be at:
-a /media/bart/EEBEBEBEC313CA9B
Obviously. If I try another, then it's at /media/bart/NEW (note these
are case-sensitive), and a third was at /media/bart/0159078ED.
I assume that 'bart' is specific to my machine, so I can't assume
anything if, say, I wanted to hardcode a path into a program or script
that someone else runs.
On 19/06/2026 11:18, Dan Cross wrote:
In article <11132u8$37hrh$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
On 19/06/2026 07:56, David Brown wrote:
On 19/06/2026 08:20, BGB wrote:
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not >>>>>> even in a unique fashion, like with a volume UUID or something, but >>>>>> with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed
to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives to >>>>> the same letter on each boot.
I am not sure what you call "newer", but IIRC Windows has done that
since Windows 3.1.-a The only letters you could assign yourself were for >>>> network drives, and they were persistent if you choose "persistent=yes". >>>>
Later versions of Windows (maybe NT4 or W2K?-a I can't remember the
details) let you choose the letter to use for other drives, such as
additional harddrives, CD-ROMs and later still, USB drives.-a Those
choices were persistent.
Automatically chosen drive letters were, of course, inconsistent.-a And >>>> when you have a lot of drives and network shares, they run out.
But, yeah, probably wouldn't do it the Windows way. Either they could >>>>> be specified as mounts (in mtab or such), or possibly treated as
aliases, say:
-a-a c:/ aliases to /mnt/c
Drive letters make sense when users wanted to distinguish between their >>>> 3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still usable >>>> when you had a hard drive with one partition.-a Once it was realistic to >>>> have two drives in the one PC, and more than one partition on a disk,
they were outdated and too restrictive for comfort.
How would you distinguish between two floppy drives on a Unix-like file
system?
Based on the directory name where you mount them.
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
You don't. You parameterize it. Why would I want to restrict a
shell script to only working with the contents of floppy disks?
Obligatory plan 9 example:
cpu% grep floppy /dev/drivers
#f floppy
cpu% ls '#f'
'#f/fd0ctl'
'#f/fd0disk'
'#f/fd1ctl'
'#f/fd1disk'
cpu% bind -a '#f' /dev
cpu% ls -l /dev/fd0disk
--rw-rw---- f 0 bootes bootes 1474560 Sep 20 2021 /dev/fd0disk
cpu% dossrv
dossrv: serving #s/dos
cpu% mount -c /srv/dos /n/floppy0 /dev/fd0disk
cpu% mount -c /srv/dos /n/floppy1 /dev/fd1disk
cpu%
This was all wrapped up into a shell script:
cpu% cat /bin/a:
#!/bin/rc
rfork e
flop=/dev/fd0disk
if(! test -r $flop)
flop='#f'/fd0disk
if(! test -f /srv/dos)
dossrv >/dev/null </dev/null >[2]/dev/null
unmount /n/a:>[2]/dev/null
mount -c /srv/dos /n/a: $flop
unmount /n/a >[2]/dev/null
mount -c /srv/dos /n/a $flop
cpu%
The floppy device is built into the kernel. The names relative
to `/n` are arbitrary; the contents of both floppies are now
available on /n/floppy0 and /n/floppy1 respectively. `dossrv`
is a program that implements a few variations of FAT
filesystems.
Machines that used floppy disks with drive letters tended to be used by >non-technical members of the public.
If I was doing technical support on the phone (which I actually did),
what would I tell someone to type in to refer to say the leftmost of
their two floppy drives:
Would it actually be "/n/floppy0", or would that depend on what had been
set up the client's specific machine? I assume it would have to be all
in the right case too?
The beauty of letter designations is that you just say 'type A colon';
it doesn't matter if they do A: or a: either as those OSes tended to be >case-insensitive.
This was also long before Windows, in my case on a CP/M clone.
The key observation is that shoehorning everything into `open`
is the wrong model; instead, conceptually splitting into
separate `mount` and access operations simplifies and permits
composition. Making `mount` unprivileged and allowing the user
to control their view of the file namespace makes all of this
natural.
'Mount' wasn't a thing on those machines. It was usually plug-and-play.
On 19/06/2026 12:46, David Brown wrote:
On 19/06/2026 11:42, Bart wrote:
On 19/06/2026 07:56, David Brown wrote:
[snip]How would you distinguish between two floppy drives on a Unix-like
Drive letters make sense when users wanted to distinguish between
their 3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still >>>> usable when you had a hard drive with one partition.-a Once it was
realistic to have two drives in the one PC, and more than one
partition on a disk, they were outdated and too restrictive for comfort. >>>
file system?
To be honest, I have never come across the need.-a In my university days
(with SunOS, then Solaris) the machines did not have floppies - most did
not even have hard disks.-a By the time I started using Linux, at about
the turn of the century, floppies were out of fashion.
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
Filesystems are mounted on *nix systems.-a The exact placement of mount
points varies, as does the extent to which attached filesystems are
automounted, or the user is informed and given a choice, or mounting is
manual.-a Different *nix systems have different habits, and in Linux it
can vary by distro or desktop.-a And then administrators or users can
have their own choices.
Hardware is different - if I need to use a floppy these days, it would
be via a USB floppy drive.-a More realistically, people would use USB
memory sticks now.-a But someone might have several USB mass storage
devices attached - I would not presume to know which they want to use
for this script or program.-a So I would say the script should either
require a path (for file / directory access - and I can't think why it
would be limited to a floppy), or a device name (for something like a
flash image writer).-a It would likely be better to have a gui or menu
choice for some programs.-a Getting lists of the available block devices, >> mounted systems, filesystem types, etc., and detailed information about
the devices, is not hard on Linux - but I don't know how portable that
might be to other *nix systems.
If you plug in a USB pen drive on Windows, it will be under a drive
letter, but that it is not guaranteed to be consistent, especially if
you plug in more than one.
So that is a problem. It would be useful, IMV, if the USB sockets were >labeled with specific letters.
So, what's it like under Linux: if I plug a pen drive into my RPi, then
the files will be at:
/media/bart/EEBEBEBEC313CA9B
Obviously. If I try another, then it's at /media/bart/NEW (note these
are case-sensitive), and a third was at /media/bart/0159078ED.
I assume that 'bart' is specific to my machine,
so I can't assume anything if, say, I wanted to hardcode a path
into a program or script that someone else runs.
In article <1113kuc$3cklj$2@dont-email.me>, Bart <bc@freeuk.com> wrote:
On 19/06/2026 12:46, David Brown wrote:
On 19/06/2026 11:42, Bart wrote:
On 19/06/2026 07:56, David Brown wrote:
[snip]How would you distinguish between two floppy drives on a Unix-like
Drive letters make sense when users wanted to distinguish between
their 3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still >>>>> usable when you had a hard drive with one partition.-a Once it was
realistic to have two drives in the one PC, and more than one
partition on a disk, they were outdated and too restrictive for comfort. >>>>
file system?
To be honest, I have never come across the need.-a In my university days >>> (with SunOS, then Solaris) the machines did not have floppies - most did >>> not even have hard disks.-a By the time I started using Linux, at about
the turn of the century, floppies were out of fashion.
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
Filesystems are mounted on *nix systems.-a The exact placement of mount
points varies, as does the extent to which attached filesystems are
automounted, or the user is informed and given a choice, or mounting is
manual.-a Different *nix systems have different habits, and in Linux it
can vary by distro or desktop.-a And then administrators or users can
have their own choices.
Hardware is different - if I need to use a floppy these days, it would
be via a USB floppy drive.-a More realistically, people would use USB
memory sticks now.-a But someone might have several USB mass storage
devices attached - I would not presume to know which they want to use
for this script or program.-a So I would say the script should either
require a path (for file / directory access - and I can't think why it
would be limited to a floppy), or a device name (for something like a
flash image writer).-a It would likely be better to have a gui or menu
choice for some programs.-a Getting lists of the available block devices, >>> mounted systems, filesystem types, etc., and detailed information about
the devices, is not hard on Linux - but I don't know how portable that
might be to other *nix systems.
If you plug in a USB pen drive on Windows, it will be under a drive
letter, but that it is not guaranteed to be consistent, especially if
you plug in more than one.
So that is a problem. It would be useful, IMV, if the USB sockets were
labeled with specific letters.
Why letters and not descriptive volume names?
In article <1113jni$3cklj$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
On 19/06/2026 11:18, Dan Cross wrote:
In article <11132u8$37hrh$1@dont-email.me>, Bart <bc@freeuk.com> wrote: >>>> On 19/06/2026 07:56, David Brown wrote:
Drive letters make sense when users wanted to distinguish between their >>>>> 3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still usable >>>>> when you had a hard drive with one partition.-a Once it was realistic to >>>>> have two drives in the one PC, and more than one partition on a disk, >>>>> they were outdated and too restrictive for comfort.
How would you distinguish between two floppy drives on a Unix-like file >>>> system?
The floppy device is built into the kernel. The names relative
to `/n` are arbitrary; the contents of both floppies are now
available on /n/floppy0 and /n/floppy1 respectively. `dossrv`
is a program that implements a few variations of FAT
filesystems.
Machines that used floppy disks with drive letters tended to be used by
non-technical members of the public.
If I was doing technical support on the phone (which I actually did),
what would I tell someone to type in to refer to say the leftmost of
their two floppy drives:
Move the goalposts much?
I was responding to a comment about a
shell script and Unix, not doing technical support over a
telephone for non-technical people.
This was also long before Windows, in my case on a CP/M clone.
I have been fortunate to not have to use Windows very much
throughout my career.
The original question had to do with `fopen`; someone brought up
Unix and shell scripts; I have no idea why you're talking about
CP/M, which copied DEC OSes.
How would you distinguish between two floppy drives on a Unix-like
file system?
If writing a common shell script for other people to use on their own machines, would you be able to use the same designations?
Bart <bc@freeuk.com> writes:
[...]
How would you distinguish between two floppy drives on a Unix-like
file system?
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
I'd ask in a forum that discusses Unix-like systems, not one that
discusses the C programming language.
In article <1113jni$3cklj$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
This was also long before Windows, in my case on a CP/M clone.
I have been fortunate to not have to use Windows very much
throughout my career. That said, some of their kernel people
are amazing engineers.
The key observation is that shoehorning everything into `open`
is the wrong model; instead, conceptually splitting into
separate `mount` and access operations simplifies and permits
composition. Making `mount` unprivileged and allowing the user
to control their view of the file namespace makes all of this
natural.
'Mount' wasn't a thing on those machines. It was usually plug-and-play.
The original question had to do with `fopen`; someone brought up
Unix and shell scripts; I have no idea why you're talking about
CP/M, which copied DEC OSes.
On 19/06/2026 17:18, Dan Cross wrote:
In article <1113jni$3cklj$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
If I was doing technical support on the phone (which I actually did),
what would I tell someone to type in to refer to say the leftmost of
their two floppy drives:
Move the goalposts much?
I haven't moved them at all. Someone made remarks about the scheme to >designate drives with letters, which is very simple and which everyone
could understand.
On 19/06/2026 17:31, Dan Cross wrote:t know how portable that
might be to other *nix systems.
If you plug in a USB pen drive on Windows, it will be under a drive
letter, but that it is not guaranteed to be consistent, especially if
you plug in more than one.
So that is a problem. It would be useful, IMV, if the USB sockets were
labeled with specific letters.
Why letters and not descriptive volume names?
These are letters that are physical labels next to each socket.
On 19/06/2026 18:33, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
How would you distinguish between two floppy drives on a Unix-like
file system?
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
I'd ask in a forum that discusses Unix-like systems, not one that
discusses the C programming language.
Here's the thing: this is thread that has been wildly off-topic for
nearly 100 posts, even aside from the other off-topic threads.
Yet you pick on MY post and tell only ME to move the discussion elsewhere.
On Fri, 19 Jun 2026 01:20:14 -0500, BGB wrote:
On newer [Windows], the OS remembers and will assign the same drives
to the same letter on each boot.
You know, itrCOs a wonder to think, for an OS that was supposedly
designed for 16-bit machines, how many legacy features it inherits
from the 8-bit era.
Maybe, but you wouldn't need "file://" for "fopen()" or similar,
since it is sort of an implied default in this case.
For an OS-level call, yes. But there are lots of higher-level toolkits (particularly GUI-associated ones) that hook in a virtual-I/O layer
that allows accessing remote URLs as easily as opening local files.
May seem like a waste to burn a thread on each object listener, but
no real better option at present.
What, no event loop?
On 19/06/2026 17:18, Dan Cross wrote:
In article <1113jni$3cklj$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
On 19/06/2026 11:18, Dan Cross wrote:
In article <11132u8$37hrh$1@dont-email.me>, Bart <bc@freeuk.com> wrote: >>>>> On 19/06/2026 07:56, David Brown wrote:
Drive letters make sense when users wanted to distinguish between their >>>>>> 3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still usable >>>>>> when you had a hard drive with one partition.-a Once it was realistic to >>>>>> have two drives in the one PC, and more than one partition on a disk, >>>>>> they were outdated and too restrictive for comfort.
How would you distinguish between two floppy drives on a Unix-like file >>>>> system?
The floppy device is built into the kernel. The names relative
to `/n` are arbitrary; the contents of both floppies are now
available on /n/floppy0 and /n/floppy1 respectively. `dossrv`
is a program that implements a few variations of FAT
filesystems.
Machines that used floppy disks with drive letters tended to be used by
non-technical members of the public.
If I was doing technical support on the phone (which I actually did),
what would I tell someone to type in to refer to say the leftmost of
their two floppy drives:
Move the goalposts much?
I haven't moved them at all. Someone made remarks about the scheme to >designate drives with letters, which is very simple and which everyone
could understand.
I asked how that would have been done under Unix. Apparently, with some >difficulty; you needed to be an expert (well, working under Unix seems
to involve an awful lot of configuring anyway), and it's not even clear
who has to do do all that: me, or my client.
So my example showed that was it simpler to use the drive-letter scheme,
and out-of-the box; you don't need to /make/ it 'simple'.
I was responding to a comment about a
shell script and Unix, not doing technical support over a
telephone for non-technical people.
And the shell script presumably was part-answer to my question about
what replaces A: and B: on Unix.
This was also long before Windows, in my case on a CP/M clone.
I have been fortunate to not have to use Windows very much
throughout my career.
I've been even more fortunate in never needing to use Unix at all,
although I tried a few times.
The original question had to do with `fopen`; someone brought up
Unix and shell scripts; I have no idea why you're talking about
CP/M, which copied DEC OSes.
Because the earlier discussion was talking about Windows and drive
letters were associated with Windows, so I made the point that they go
back a lot further. Since people always like to stick it to Windows.
But I've used a couple of DEC OSes and don't remember drive letters.
Google AI tells me: "Drive letters originate from the CP/M operating
system in the 1970s and were popularized by MS-DOS."
On 19/06/2026 17:31, Dan Cross wrote:
[snip]
Why letters and not descriptive volume names?
These are letters that are physical labels next to each socket.
If I
give instructions to somebody to use physical socket 'A', they can do
that even if the machine is powered off.
If I look at the back of my TV, I have HDMI sockets marked 1, 2, 3. The
same numbering appears on the on-screen A/V menu. It's simple and it works.
Content- or device-related labels can be shown too interrogated from >whatever is plugged-in and active (that is, on-screen), but that is >secondary.
Of course, when there are no dedicated cables and it is all wireless,
then it gets harder and not so simple.
Bart <bc@freeuk.com> writes:
On 19/06/2026 17:18, Dan Cross wrote:
In article <1113jni$3cklj$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
<snip discussion of unix floppy disks>
If I was doing technical support on the phone (which I actually did),
what would I tell someone to type in to refer to say the leftmost of
their two floppy drives:
Move the goalposts much?
I haven't moved them at all. Someone made remarks about the scheme to
designate drives with letters, which is very simple and which everyone
could understand.
"Someone" named Bart, per chance?
Bart <bc@freeuk.com> writes:
On 19/06/2026 18:33, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
How would you distinguish between two floppy drives on a Unix-like
file system?
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
I'd ask in a forum that discusses Unix-like systems, not one that
discusses the C programming language.
Here's the thing: this is thread that has been wildly off-topic for
nearly 100 posts, even aside from the other off-topic threads.
Yet you pick on MY post and tell only ME to move the discussion elsewhere.
perhaps it is because _you_ are most often the poster who
moves the thread off-topic?
In article <1113s0b$3f4nm$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
On 19/06/2026 17:31, Dan Cross wrote:
[snip]
Why letters and not descriptive volume names?
These are letters that are physical labels next to each socket.
Not on my system.
If I
give instructions to somebody to use physical socket 'A', they can do
that even if the machine is powered off.
Huh. Kinda hard to access the files on the "A:" drive when the
system is powered off.
I would find it frustrating to type
commands to a machine that isn't even running.
If I look at the back of my TV, I have HDMI sockets marked 1, 2, 3. The
same numbering appears on the on-screen A/V menu. It's simple and it works.
So the Unix scheme assigns each floppy drive a number. The only
substantive difference is that with Unix, you `mount` the
filesystem on the removable drive onto some directory, making
the files on that floppy appear as part of the global file
namespace.
Content- or device-related labels can be shown too interrogated from
whatever is plugged-in and active (that is, on-screen), but that is
secondary.
Of course, when there are no dedicated cables and it is all wireless,
then it gets harder and not so simple.
None of this has to do with `fopen`.
On Thu, 18 Jun 2026 04:36:43 -0700, Chris M. Thomasson wrote:
On 6/18/2026 12:30 AM, Lawrence DrCOOliveiro wrote:
The TLS setup exchange is diagrammed here
<https://www.rfc-editor.org/info/rfc8446/#section-2>. There are
three phases:
1) Key exchange: ClientHello + ServerHello -- one message in
each direction
2) Server parameters -- two messages from server to client
3) Authentication -- three messages in each direction.
Hard to see how to fit all that into a single ConnectEx + AcceptEx
...
The ConnectEx can be the ClientHello at least. ;^)
And what does that achieve, really?
If saving the overhead of one system call is so significant, perhaps
you shouldnrCOt be using that OS for high-performance network operations
...
On 19/06/2026 20:58, Dan Cross wrote:
In article <1113s0b$3f4nm$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
On 19/06/2026 17:31, Dan Cross wrote:
[snip]
Why letters and not descriptive volume names?
These are letters that are physical labels next to each socket.
Not on my system.
This was hypothetical. That is, if USB sockets were labeled like my HDMI >example and those letters or numbers appeared also on menus.
If I
give instructions to somebody to use physical socket 'A', they can do
that even if the machine is powered off.
Huh. Kinda hard to access the files on the "A:" drive when the
system is powered off.
This is about plugging in the device, like I can plug in my PCV to HDMI1 >when the TV is still turned off.
I would find it frustrating to type
commands to a machine that isn't even running.
If I look at the back of my TV, I have HDMI sockets marked 1, 2, 3. TheSo the Unix scheme assigns each floppy drive a number. The only
same numbering appears on the on-screen A/V menu. It's simple and it works. >>
substantive difference is that with Unix, you `mount` the
filesystem on the removable drive onto some directory, making
the files on that floppy appear as part of the global file
namespace.
Content- or device-related labels can be shown too interrogated from
whatever is plugged-in and active (that is, on-screen), but that is
secondary.
Of course, when there are no dedicated cables and it is all wireless,
then it gets harder and not so simple.
None of this has to do with `fopen`.
Yet it hasn't stopped you having your say about a topic before declaring
it as off-topic.
On 6/18/2026 4:03 PM, Lawrence DrCOOliveiro wrote:
If saving the overhead of one system call is so significant,
perhaps you shouldnrCOt be using that OS for high-performance network
operations ...
Humm... I think you are missing the point? ConnectEx/AcceptEx has
the option to send/recv data. That's it.
When you use ConnectEx or AcceptEx to send or receive data
immediately with the connection establishment, you aren't just
"shaving off a system call"; you are minimizing the idle time of the
IOCP...
On 6/19/2026 1:59 AM, Lawrence DrCOOliveiro wrote:
I guess one can distinguish here what belongs in the VFS and shell, vs
On Fri, 19 Jun 2026 01:20:14 -0500, BGB wrote:
Maybe, but you wouldn't need "file://" for "fopen()" or similar,
since it is sort of an implied default in this case.
For an OS-level call, yes. But there are lots of higher-level toolkits
(particularly GUI-associated ones) that hook in a virtual-I/O layer
that allows accessing remote URLs as easily as opening local files.
what belongs in a file-browser or web browser.
As of yet, no file browser or web-browser, still basically at the level
of a very rudimentary GUI that has a shell window that can be used for
other programs.
What, no event loop?
A lot of normal programs use polling loops, but from the way
object-method dispatch works, it would not use a polling/loop or
event loop.
How would you distinguish between two floppy drives on a Unix-like
file system?
On 19/06/2026 08:20, BGB wrote:
On 6/18/2026 6:06 PM, Lawrence DrCOOliveiro wrote:
On Thu, 18 Jun 2026 03:49:55 -0500, BGB wrote:
Just that it is also not a huge leap from:
-a-a-a tcp://whatever
-a-a-a udp://whatever
-a-a-a http://whatever
-a-a-a ftp://whatever
-a-a-a ...
To:
-a-a-a c:/whatever...
Yes it is.
In the former, that part before the colon is a protocol. In the
latter, it is now down to just indicating a filesystem drive. And not
even in a unique fashion, like with a volume UUID or something, but
with an arbitarily-assigned rCLdrive letterrCY which cannot be guaranteed >>> to be unique or persistent.
Well, on older Windows.
On newer systems, the OS remembers and will assign the same drives to
the same letter on each boot.
I am not sure what you call "newer", but IIRC Windows has done that
since Windows 3.1.-a The only letters you could assign yourself were for network drives, and they were persistent if you choose "persistent=yes".
Later versions of Windows (maybe NT4 or W2K?-a I can't remember the
details) let you choose the letter to use for other drives, such as additional harddrives, CD-ROMs and later still, USB drives.-a Those
choices were persistent.
Automatically chosen drive letters were, of course, inconsistent.-a And
when you have a lot of drives and network shares, they run out.
But, yeah, probably wouldn't do it the Windows way. Either they could
be specified as mounts (in mtab or such), or possibly treated as
aliases, say:
-a-a c:/ aliases to /mnt/c
Drive letters make sense when users wanted to distinguish between their
3.5" floppy "A:" and their 5.25" floppy "B:".-a They were still usable
when you had a hard drive with one partition.-a Once it was realistic to have two drives in the one PC, and more than one partition on a disk,
they were outdated and too restrictive for comfort.
They were a product of their time, but offer nothing going forward.
Copying the concept in any way for a new system is a daft idea.
Though, granted, not much particular reason to do this...
Remember, we already have
-a-a-a-a file://whatever
for denoting files on the local filesystem. That allows the rCLwhateverrCY >>> part to span the entire filesystem, not just one volume/drive.
Maybe, but you wouldn't need "file://" for "fopen()" or similar, since
it is sort of an implied default in this case.
Then again, going into the weeds on this:
Would, say:
-a-a cd ftp://foo.org/pub/
-a-a ls
Even really make sense?...
That could be nice, at least for things that support a file and
directory model.-a It all depends on how you want to treat user
convenience, security, reliability, etc.
Or, would it be better to ask people to at least mount it into the VFS
or similar?...
You are likely to need a user name and password here somewhere.
Well, or other mysteries, like, say:
Should usermode applications be allowed to export COM-like interfaces
that could then be mounted into the VFS?...
Say, for example, an application exports an IFileSystem or IMount
interface to the VFS, and then one can issue a "mount" on it. Would
need some way for the VFS do deal gracefully if the application
becomes unresponsive or crashes though (preferably without nuking the
whole OS in the process).
Like "fuse" on Linux (and similar things on other systems) ?-a Usermode
is the way to go for anything that is not speed critical.
Vs, say, assuming programs that export interfaces (as services) to be
at least semi trsusted / stable...
On Fri, 19 Jun 2026 13:42:56 -0700, Chris M. Thomasson wrote:
On 6/18/2026 4:03 PM, Lawrence DrCOOliveiro wrote:
If saving the overhead of one system call is so significant,
perhaps you shouldnrCOt be using that OS for high-performance network
operations ...
Humm... I think you are missing the point? ConnectEx/AcceptEx has
the option to send/recv data. That's it.
That rCLthatrCOs itrCY is precisely the point.
When you use ConnectEx or AcceptEx to send or receive data
immediately with the connection establishment, you aren't just
"shaving off a system call"; you are minimizing the idle time of the
IOCP...
If the userspace has to worry about keeping the kernel network stack
busy to that extent, then thatrCOs another point in favour of the
simpler Linux way of doing things.
On Wed, 10 Jun 2026 00:24:35 -0700, Chris M. Thomasson wrote:
Windows I/O is unified and async across all device types rCo thatrCOs
the whole point of IOCP.
Sure. That same sort of feature was integral both the previous OSes
Dave Cutler had a hand in: VAX/VMS and RSX-11.
If anything, Unix is the one still trying to catch up with a real
async model (see: io_uring).
You mean Linux? Yes, it did inherit the Unix idea of rCLall I/O is blockingrCY, so to do non-blocking calls you should spawn extra
processes -- or from the 1990s onwards, extra threads.
I agree, it might be nice to see a complete separation within the
kernel between I/O operation management and process scheduling.
But, letrCOs face it, even with the current model, Linux server
performance still leaves Windows for dead.
In article <1113t1c$3f4nm$2@dont-email.me>, Bart <bc@freeuk.com> wrote:
[...]
Google AI tells me: "[...]"
I don't think I've ever seen an instance where Google's AI is
right the first time.
What that really tells us is obviously something about AI-believers.Google AI tells me: "[...]"
[...]
Well, actually, a lot of people don't know how to use IOCP
efficiently. They also don't know how to program an efficient server
logic. On Linux, use io_uring. On Windows use IOCP.
I am talking about highly scalable servers under heavy load.
What is the analog of ConnectEx/AcceptEx on Linux?
On Fri, 19 Jun 2026 16:47:35 -0700, Chris M. Thomasson wrote:
Well, actually, a lot of people don't know how to use IOCP
efficiently. They also don't know how to program an efficient server
logic. On Linux, use io_uring. On Windows use IOCP.
If IOCP is the only way to achieve decent server performance on
Windows, no surprise that people find the *nix programming model
simpler.
And this is without even resorting to io_uring.
On Fri, 19 Jun 2026 16:40:07 -0700, Chris M. Thomasson wrote:
I am talking about highly scalable servers under heavy load.
So am I.
What is the analog of ConnectEx/AcceptEx on Linux?
DoesnrCOt need one. It can whip WindowsrCO arse quite nicely without it.
So, what's it like under Linux: if I plug a pen drive into my RPi,
then the files will be at:
/media/bart/EEBEBEBEC313CA9B
Obviously.
If I try another, then it's at /media/bart/NEW (note these are case-sensitive) ...
But I've used a couple of DEC OSes and don't remember drive letters.
Google AI tells me: "Drive letters originate from the CP/M operating
system in the 1970s and were popularized by MS-DOS."
And this is without even resorting to io_uring.
io_uring is the way to go on Linux for high performance servers.
Actually, its more complicated than IOCP.
On 6/19/2026 7:50 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 16:40:07 -0700, Chris M. Thomasson wrote:
I am talking about highly scalable servers under heavy load.
So am I.
What is the analog of ConnectEx/AcceptEx on Linux?
DoesnrCOt need one. It can whip WindowsrCO arse quite nicely without it.
But it seems to have one? io_uring_enter... IORING_OP_ACCEPT and IORING_OP_CONNECT ?
Bart <bc@freeuk.com> writes:
On 19/06/2026 18:33, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
How would you distinguish between two floppy drives on a Unix-like
file system?
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
I'd ask in a forum that discusses Unix-like systems, not one that
discusses the C programming language.
Here's the thing: this is thread that has been wildly off-topic for
nearly 100 posts, even aside from the other off-topic threads.
Yet you pick on MY post and tell only ME to move the discussion elsewhere.
perhaps it is because _you_ are most often the poster who
moves the thread off-topic?
On Fri, 19 Jun 2026 14:47:31 -0500, BGB wrote:
On 6/19/2026 1:59 AM, Lawrence DrCOOliveiro wrote:
I guess one can distinguish here what belongs in the VFS and shell, vs
On Fri, 19 Jun 2026 01:20:14 -0500, BGB wrote:
Maybe, but you wouldn't need "file://" for "fopen()" or similar,
since it is sort of an implied default in this case.
For an OS-level call, yes. But there are lots of higher-level toolkits
(particularly GUI-associated ones) that hook in a virtual-I/O layer
that allows accessing remote URLs as easily as opening local files.
what belongs in a file-browser or web browser.
I should mention that Linux has a filesystem plugin API called FUSE,
which allows filesystem implementations to be done in userland. Not everything has to be a kernel module.
Example: secure remote access to filesystems on other machines via SSH <https://github.com/libfuse/sshfs>.
On 6/19/2026 7:49 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 16:47:35 -0700, Chris M. Thomasson wrote:
io_uring is the way to go on Linux for high performance servers.
Actually, its more complicated than IOCP.
Compared to Windows machines with its pseudorandom system for
assigning COM port numbers,
On 19/06/2026 18:33, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
How would you distinguish between two floppy drives on a Unix-like
file system?
If writing a common shell script for other people to use on their own
machines, would you be able to use the same designations?
I'd ask in a forum that discusses Unix-like systems, not one that
discusses the C programming language.
Here's the thing: this is thread that has been wildly off-topic for
nearly 100 posts, even aside from the other off-topic threads.
Yet you pick on MY post and tell only ME to move the discussion elsewhere.
On Fri, 19 Jun 2026 17:25:01 +0200
David Brown <david.brown@hesbynett.no> wrote:
Compared to Windows machines with its pseudorandom system for
assigning COM port numbers,
There is a system in the madness. Behavior depends on either your USB-to-serial device has USB serial Id or lacks it.
If it has Id then the same port will be assigned to the same device regardless of the USB port that device plugged in this time.
Otherwise port number is assigned per USB port. Mostly.
Cheap FTDI clones tend to not implement serial ID.
Silicon Lab based converters tends to be of better quality, not just relatively to clones, but also relatively to genuine FTDI controllers.
On 21/06/2026 00:42, Michael S wrote:
On Fri, 19 Jun 2026 17:25:01 +0200
David Brown <david.brown@hesbynett.no> wrote:
Compared to Windows machines with its pseudorandom system for
assigning COM port numbers,
There is a system in the madness. Behavior depends on either your USB-to-serial device has USB serial Id or lacks it.
If it has Id then the same port will be assigned to the same device regardless of the USB port that device plugged in this time.
Otherwise port number is assigned per USB port. Mostly.
It is the "mostly" that is the killer.
The port numbers are usually stable if you plug the same devices into
the same physical ports. But sometimes if you have had a number of
new devices attached in the meantime, then go back to the old ones,
Windows might forget the previous numbers, or even re-use them, and
your old devices get new numbers. Mixing devices from different manufacturers appears to make things worse, but I have not done
extensive trials.
If you just have a few devices that you use regularly, it's okay - so
for most of our developers the port numbers don't get too high within
the lifetime of a useable Windows system. For some test machines
it's a different matter - when you build boards with a USB-to-serial
chip onboard, if those chips have serial numbers then you chew
through COM port numbers at an alarming rate. It is just one of many
reasons why we usually try to use Linux (especially Pi's) for test
machines.
Cheap FTDI clones tend to not implement serial ID.
Silicon Lab based converters tends to be of better quality, not just relatively to clones, but also relatively to genuine FTDI
controllers.
I don't remember ever using an FTDI clone - FTDI devices and cables
are not expensive enough for it to make sense for us. And FTDI
devices have worked fine for our needs. I have used a few Silicon
Labs devices too, but I don't see anything to suggest they are
"better quality" - pretty much every USB-to-serial converter from
every manufacturer works fine and does its job.
Some do cause more
pain with Windows then others, with different drivers and
requirements, but that's Windows and/or driver problems, and usually
those problems are surmountable. In the end, it is usually up to the customer - if they want a USB-to-serial converter on their board, and
they've picked a type, that's what they get. Given a free choice, we generally go for FTDI ourselves. (Most common is that boards have a
simple header with TTL signals and we use an external FTDI cable -
the biggest use of serial ports between boards and PC's is for
debugging and testing.)
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
On 6/19/2026 7:49 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 16:47:35 -0700, Chris M. Thomasson wrote:
io_uring is the way to go on Linux for high performance servers.
Actually, its more complicated than IOCP.
The posix asynchronous I/O facilities (e.g lio_listio(2)) were
used in the Oracle ODM (Operating System Dependent module)
of the RDMS product for high performance unix implementations
with lots of spindles more than a quarter century ago.
On Fri, 19 Jun 2026 19:53:15 -0700, Chris M. Thomasson wrote:
On 6/19/2026 7:50 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 16:40:07 -0700, Chris M. Thomasson wrote:
I am talking about highly scalable servers under heavy load.
So am I.
What is the analog of ConnectEx/AcceptEx on Linux?
DoesnrCOt need one. It can whip WindowsrCO arse quite nicely without it.
But it seems to have one? io_uring_enter... IORING_OP_ACCEPT and
IORING_OP_CONNECT ?
I canrCOt find anything that uses it.
On 6/19/2026 8:59 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 19:53:15 -0700, Chris M. Thomasson wrote:
On 6/19/2026 7:50 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 16:40:07 -0700, Chris M. Thomasson wrote:
I am talking about highly scalable servers under heavy load.
So am I.
What is the analog of ConnectEx/AcceptEx on Linux?
DoesnrCOt need one. It can whip WindowsrCO arse quite nicely without
it.
But it seems to have one? io_uring_enter... IORING_OP_ACCEPT and
IORING_OP_CONNECT ?
I canrCOt find anything that uses it.
So what does that mean? They are there, right?
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 21/06/2026 00:42, Michael S wrote:
On Fri, 19 Jun 2026 17:25:01 +0200
David Brown <david.brown@hesbynett.no> wrote:
Cheap FTDI clones tend to not implement serial ID.
Silicon Lab based converters tends to be of better quality, not just
relatively to clones, but also relatively to genuine FTDI
controllers.
I don't remember ever using an FTDI clone - FTDI devices and cables
are not expensive enough for it to make sense for us. And FTDI
devices have worked fine for our needs. I have used a few Silicon
Labs devices too, but I don't see anything to suggest they are
"better quality" - pretty much every USB-to-serial converter from
every manufacturer works fine and does its job.
I wish it was true.
Unfortunately I had seen misdesigned hardware more than one time,
including hardware from major manufactorer, like Aten.
One case I can not forget is USB-1.1 device that claimed to support
912 Kbps, but had 64-byte recieve and transmit queues. Of course, USB
polling rate is 1KHz, so it can't work even in theory, much less in
practice.
Some do cause more
pain with Windows then others, with different drivers and
requirements, but that's Windows and/or driver problems, and usually
those problems are surmountable. In the end, it is usually up to the
customer - if they want a USB-to-serial converter on their board, and
they've picked a type, that's what they get. Given a free choice, we
generally go for FTDI ourselves. (Most common is that boards have a
simple header with TTL signals and we use an external FTDI cable -
the biggest use of serial ports between boards and PC's is for
debugging and testing.)
As long as requirements are minimal, everything goes.
Try something just a little bit more demanding, like programming flash
on ST or TI microcontroller by means of vendor-supplied utility, and
many USB-to-serial converters will cause you problems.
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 21/06/2026 00:42, Michael S wrote:
On Fri, 19 Jun 2026 17:25:01 +0200
David Brown <david.brown@hesbynett.no> wrote:
Compared to Windows machines with its pseudorandom system for
assigning COM port numbers,
There is a system in the madness. Behavior depends on either your
USB-to-serial device has USB serial Id or lacks it.
If it has Id then the same port will be assigned to the same device
regardless of the USB port that device plugged in this time.
Otherwise port number is assigned per USB port. Mostly.
It is the "mostly" that is the killer.
The port numbers are usually stable if you plug the same devices into
the same physical ports. But sometimes if you have had a number of
new devices attached in the meantime, then go back to the old ones,
Windows might forget the previous numbers, or even re-use them, and
your old devices get new numbers. Mixing devices from different
manufacturers appears to make things worse, but I have not done
extensive trials.
If you just have a few devices that you use regularly, it's okay - so
for most of our developers the port numbers don't get too high within
the lifetime of a useable Windows system. For some test machines
it's a different matter - when you build boards with a USB-to-serial
chip onboard, if those chips have serial numbers then you chew
through COM port numbers at an alarming rate. It is just one of many
reasons why we usually try to use Linux (especially Pi's) for test
machines.
Serial device API of Linux (inherited from early Unixes) is too kludgy
to my liking. Why oh why do they think that serial port somehow has to
be related to terminal ?!
Windows API makes more sense.
The difference mattered in the past, when we had to implement
SCADA-style protocols on PC host. Fortunately, we do not doing it any
longer.
Cheap FTDI clones tend to not implement serial ID.
Silicon Lab based converters tends to be of better quality, not just
relatively to clones, but also relatively to genuine FTDI
controllers.
I don't remember ever using an FTDI clone - FTDI devices and cables
are not expensive enough for it to make sense for us. And FTDI
devices have worked fine for our needs. I have used a few Silicon
Labs devices too, but I don't see anything to suggest they are
"better quality" - pretty much every USB-to-serial converter from
every manufacturer works fine and does its job.
I wish it was true.
Unfortunately I had seen misdesigned hardware more than one time,
including hardware from major manufactorer, like Aten.
One case I can not forget is USB-1.1 device that claimed to support
912 Kbps, but had 64-byte recieve and transmit queues. Of course, USB
polling rate is 1KHz, so it can't work even in theory, much less in
practice.
Some do cause more
pain with Windows then others, with different drivers and
requirements, but that's Windows and/or driver problems, and usually
those problems are surmountable. In the end, it is usually up to the
customer - if they want a USB-to-serial converter on their board, and
they've picked a type, that's what they get. Given a free choice, we
generally go for FTDI ourselves. (Most common is that boards have a
simple header with TTL signals and we use an external FTDI cable -
the biggest use of serial ports between boards and PC's is for
debugging and testing.)
As long as requirements are minimal, everything goes.
Try something just a little bit more demanding, like programming flash
on ST or TI microcontroller by means of vendor-supplied utility, and
many USB-to-serial converters will cause you problems.
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
Serial device API of Linux (inherited from early Unixes) is too kludgy
to my liking. Why oh why do they think that serial port somehow has to
be related to terminal ?!
On 6/20/2026 8:49 AM, Scott Lurndal wrote:
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
On 6/19/2026 7:49 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 16:47:35 -0700, Chris M. Thomasson wrote:
io_uring is the way to go on Linux for high performance servers.
Actually, its more complicated than IOCP.
The posix asynchronous I/O facilities (e.g lio_listio(2)) were
used in the Oracle ODM (Operating System Dependent module)
of the RDMS product for high performance unix implementations
with lots of spindles more than a quarter century ago.
Afaict, io_uring is the way to go on Linux. Or want to go POSIX? AIO.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
On 6/20/2026 8:49 AM, Scott Lurndal wrote:
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
On 6/19/2026 7:49 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 16:47:35 -0700, Chris M. Thomasson wrote:
io_uring is the way to go on Linux for high performance servers.
Actually, its more complicated than IOCP.
The posix asynchronous I/O facilities (e.g lio_listio(2)) were
used in the Oracle ODM (Operating System Dependent module)
of the RDMS product for high performance unix implementations
with lots of spindles more than a quarter century ago.
Afaict, io_uring is the way to go on Linux. Or want to go POSIX? AIO.
That's what I said. lio_listio(2) is one of the several POSIX
asynchronous I/O interfaces.
On Wed, 10 Jun 2026 12:37:47 +0200, fir wrote:
why you think YOU SHOULD be waiting? waiting makes some
complications (like for example you can wait only on one thing ...
Heck, no. Look at this man page <https://manpages.debian.org/poll(2)>:
you give it a collection of FDs (these can be any mixture of things
like sockets, pipes, character devices ... actually any kind of file
is valid). You specify for each one whether you are waiting for it to
be read-ready, write-ready, or both. And on top of that you can
specify a timeout, in case you have some other tasks to perform that
you donrCOt want to hold up for *too* long.
A common use for the timeout is to do a periodic scan for client
network connections that have gone idle for too long, so the server
should give up and abandon those connections.
And then the call returns when one or more of those FDs are in the
specified states, or the timeout (if specified) has elapsed.
An even more advanced set of calls is this <https://manpages.debian.org/epoll(7)>. That offers the option for
monitoring individual FDs on a level-triggered or edge-triggered
basis.
On Sun, 21 Jun 2026 16:31:03 -0700, Chris M. Thomasson wrote:
On 6/19/2026 8:59 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 19:53:15 -0700, Chris M. Thomasson wrote:
On 6/19/2026 7:50 PM, Lawrence DrCOOliveiro wrote:
On Fri, 19 Jun 2026 16:40:07 -0700, Chris M. Thomasson wrote:
I am talking about highly scalable servers under heavy load.
So am I.
What is the analog of ConnectEx/AcceptEx on Linux?
DoesnrCOt need one. It can whip WindowsrCO arse quite nicely without >>>>> it.
But it seems to have one? io_uring_enter... IORING_OP_ACCEPT and
IORING_OP_CONNECT ?
I canrCOt find anything that uses it.
So what does that mean? They are there, right?
It just reinforces my point, that Linux servers, particularly network-intensive ones, can run rings around their Windows competitors without needing to resort to such extreme-performance tricks.
Fwiw, remember that DisconnectEx call in Windows with the
TF_REUSE_SOCKET flag? Pretty nice:
https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_disconnectex
On 6/21/2026 5:59 PM, Lawrence DrCOOliveiro wrote:
It just reinforces my point, that Linux servers, particularly
network-intensive ones, can run rings around their Windows
competitors without needing to resort to such extreme-performance
tricks.
So, why did they even create io_uring?
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
Serial device API of Linux (inherited from early Unixes) is too kludgy
to my liking. Why oh why do they think that serial port somehow has to
be related to terminal ?!
Can you elaborate on that? What do you mean 'related to a terminal'?
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud rate,
stop bits, parity, et alia) via library functions (tcsetattr/tcgetattr)
and using standard filesystem calls for reading and writing.
Once the serial port is opened, it is a simple byte stream just like
any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
Serial device API of Linux (inherited from early Unixes) is too kludgy
to my liking. Why oh why do they think that serial port somehow has to
be related to terminal ?!
Can you elaborate on that? What do you mean 'related to a terminal'?
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud rate,
stop bits, parity, et alia) via library functions (tcsetattr/tcgetattr)
and using standard filesystem calls for reading and writing.
Once the serial port is opened, it is a simple byte stream just like
any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
Just look at the documentation: ><https://docs.kernel.org/driver-api/serial/driver.html>
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
It's a
total mess - it's all for handling serial terminals from the 1970's.
David Brown <david.brown@hesbynett.no> writes:
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
Serial device API of Linux (inherited from early Unixes) is too kludgy >>>> to my liking. Why oh why do they think that serial port somehow has to >>>> be related to terminal ?!
Can you elaborate on that? What do you mean 'related to a terminal'?
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud rate,
stop bits, parity, et alia) via library functions (tcsetattr/tcgetattr)
and using standard filesystem calls for reading and writing.
Once the serial port is opened, it is a simple byte stream just like
any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
Just look at the documentation:
<https://docs.kernel.org/driver-api/serial/driver.html>
Which describes how to write a kernel driver for a new
serial port (of which there hasn't been new hardware since
the PL011). Certainly not of interest or use to the average
user.
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
Which describes several long-obsolete API implementations.
It's a
total mess - it's all for handling serial terminals from the 1970's.
I'm sure that the microprocessors you routinely use all still
support either the 16550 UART or the PL011 for debug purposes
if not for production purposes. Our most recently taped out
chip has a dozen pl011 compatible UARTS.
Sure, the modem signals are obsolete and not often used.
With 115k baud, it's less likely that the hardware flow
control signals (RTS/CTS) are still used (although XON/XOFF is
still useful) in most cases, but the classic serial port still
lives and is useful, particularly in embedded hardware.
On 23/06/2026 17:35, Scott Lurndal wrote:
It's a
total mess - it's all for handling serial terminals from the 1970's.
I'm sure that the microprocessors you routinely use all still
support either the 16550 UART or the PL011 for debug purposes
if not for production purposes. Our most recently taped out
chip has a dozen pl011 compatible UARTS.
16550 UARTs are long obsolete. Some embedded processors might have
UARTs that have register sets compatible with them, but I don't think it
is common. Microcontrollers certainly don't make any attempt to have >compatibility with those register sets.
Sure, the modem signals are obsolete and not often used.
With 115k baud, it's less likely that the hardware flow
control signals (RTS/CTS) are still used (although XON/XOFF is
still useful) in most cases, but the classic serial port still
lives and is useful, particularly in embedded hardware.
I use serial ports all the time. I've never had any use for XON/XOFF,
or hardware flow control (the RTS signal is often used for RS-485 drive >enable), and regularly use 3 MBaud for local connections to fast >microcontrollers.
On 23/06/2026 17:35, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
Which describes several long-obsolete API implementations.
OK.
But there is still termio stuff needed in the setup of the UART, when
all that is needed in almost all cases this century is picking the baud >rate, possibly enabling the RTS line as an RS-485 driver enable, picking >8,n,1 (other options are rare, but not quite non-existent), and then
reading and writing characters.
can be useful for UARTs, such as getting feedback when everything is
sent (via a semaphore, condition variable, or similar synchronisation >mechanism),
getting feedback when there has been a pause since the last
received character, and other such things. AFAIK these are not
available with standard Linux serial port handling.
In article <111eavb$2c615$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 17:35, Scott Lurndal wrote:
It's a
total mess - it's all for handling serial terminals from the 1970's.
I'm sure that the microprocessors you routinely use all still
support either the 16550 UART or the PL011 for debug purposes
if not for production purposes. Our most recently taped out
chip has a dozen pl011 compatible UARTS.
16550 UARTs are long obsolete. Some embedded processors might have
UARTs that have register sets compatible with them, but I don't think it
is common. Microcontrollers certainly don't make any attempt to have
compatibility with those register sets.
This is simply incorrect. Lots of parts still have integrated 16550-compatible UARTs; the designware part that is common in a
lot of SoC's will even go up to 3MBAUD.
Sure, the modem signals are obsolete and not often used.
With 115k baud, it's less likely that the hardware flow
control signals (RTS/CTS) are still used (although XON/XOFF is
still useful) in most cases, but the classic serial port still
lives and is useful, particularly in embedded hardware.
I use serial ports all the time. I've never had any use for XON/XOFF,
or hardware flow control (the RTS signal is often used for RS-485 drive
enable), and regularly use 3 MBaud for local connections to fast
microcontrollers.
I use 3MBAUD, 16550-compatible UARTs embedded in AMD's EPYC SoCs
daily. We use hardware flow control to avoid dropping
characters when speaking to a fast uctlr running our own
embedded OS. The DW part in the SoC even supports auto HW flow
control and manages the FIFOs and signaling more or less
independently of the host (which actually caused a problem in
our driver a few months back).
If reliable delivery of data is important to you, some kind of
flow control is useful, whether hardware or software based. If
it's just for debug spew, you may not care.
David Brown <david.brown@hesbynett.no> writes:
On 23/06/2026 17:35, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
Which describes several long-obsolete API implementations.
OK.
But there is still termio stuff needed in the setup of the UART, when
all that is needed in almost all cases this century is picking the baud
rate, possibly enabling the RTS line as an RS-485 driver enable, picking
8,n,1 (other options are rare, but not quite non-existent), and then
reading and writing characters.
I would separate those into two distinct operations:
- One-time setup. Setting the line characteristics (baud rate,
stop-bits, parity) and the UART characteristics (flow
control, Rx and Tx FIFOs, Carrier Detect). For which there
are standard POSIX interfaces (tcsetattr/tcgetattr)
- steady-state operations, such as reading and writing which
use the normal file I/O operations (read, write, poll, et alia)
There are other possible features that
can be useful for UARTs, such as getting feedback when everything is
sent (via a semaphore, condition variable, or similar synchronisation
mechanism),
That really depends on OS API. STDIO buffers output, and provides
a mechanism to flush the buffers. If one bypasses stdio and uses
read/write, the programmer can call tcdrain() to ensure the data
has been transmitted or set VMIN=1 and VTIME=0 with tcsetattr
to avoid any buffering in the kernel driver.
getting feedback when there has been a pause since the last
received character, and other such things. AFAIK these are not
available with standard Linux serial port handling.
The poll(2) system call can be used for this purpose, as it
can timeout if there is no character received within a
specified interval.
David Brown <david.brown@hesbynett.no> writes:
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
Serial device API of Linux (inherited from early Unixes) is too
kludgy to my liking. Why oh why do they think that serial port
somehow has to be related to terminal ?!
Can you elaborate on that? What do you mean 'related to a
terminal'?
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud rate,
stop bits, parity, et alia) via library functions
(tcsetattr/tcgetattr) and using standard filesystem calls for
reading and writing.
Once the serial port is opened, it is a simple byte stream just
like any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
Just look at the documentation: ><https://docs.kernel.org/driver-api/serial/driver.html>
Which describes how to write a kernel driver for a new
serial port (of which there hasn't been new hardware since
the PL011). Certainly not of interest or use to the average
user.
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
Which describes several long-obsolete API implementations.
It's a
total mess - it's all for handling serial terminals from the 1970's.
I'm sure that the microprocessors you routinely use all still
support either the 16550 UART or the PL011 for debug purposes
if not for production purposes. Our most recently taped out
chip has a dozen pl011 compatible UARTS.
Sure, the modem signals are obsolete and not often used.
With 115k baud, it's less likely that the hardware flow
control signals (RTS/CTS) are still used (although XON/XOFF is
still useful) in most cases, but the classic serial port still
lives and is useful, particularly in embedded hardware.
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
Serial device API of Linux (inherited from early Unixes) is too
kludgy to my liking. Why oh why do they think that serial port
somehow has to be related to terminal ?!
Can you elaborate on that? What do you mean 'related to a
terminal'?
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud rate,
stop bits, parity, et alia) via library functions
(tcsetattr/tcgetattr) and using standard filesystem calls for
reading and writing.
Once the serial port is opened, it is a simple byte stream just like
any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
Just look at the documentation: <https://docs.kernel.org/driver-api/serial/driver.html> or <https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
It's a total mess - it's all for handling serial terminals from the
1970's. Most of it is, of course, just a one-off setting - once you
have got the termio stuff right,
and haven't accidentally got some
extra character translation or flow control, then it's just simple
reads and writes.
Of course it is hard to remove stuff once it is there - user space
APIs are, rightly, as stable as they possibly can be.
And of the perhaps 20 or 30 microcontroller families I have used over
the years, I don't remember ever having seen one with a UART that is
16550 compatible. (I did, on a couple of boards, use a dedicated
16x50 UART chip, possibly a 16450.)
On Mon, 22 Jun 2026 13:42:20 -0700, Chris M. Thomasson wrote:
Fwiw, remember that DisconnectEx call in Windows with the
TF_REUSE_SOCKET flag? Pretty nice:
https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_disconnectex
My word:
royNote
The function pointer for the DisconnectEx function must be
obtained at run time by making a call to the WSAIoctl function
with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The
input buffer passed to the WSAIoctl function must contain
WSAID_DISCONNECTEX, a globally unique identifier (GUID) whose
value identifies the DisconnectEx extension function. On success,
the output returned by the WSAIoctl function contains a pointer to
the DisconnectEx function. The WSAID_DISCONNECTEX GUID is defined
in the Mswsock.h header file.
What the heck is that all about?
This <https://manpages.debian.org/setsockopt(2)> is so much simpler
...
On Mon, 22 Jun 2026 14:06:58 -0700, Chris M. Thomasson wrote:
On 6/21/2026 5:59 PM, Lawrence DrCOOliveiro wrote:
It just reinforces my point, that Linux servers, particularly
network-intensive ones, can run rings around their Windows
competitors without needing to resort to such extreme-performance
tricks.
So, why did they even create io_uring?
Obviously, it has its specialized uses, in rarefied realms beyond the imaginings of those only familiar with Dave-Cutler-type operating
systems ...
David Brown <david.brown@hesbynett.no> writes:
On 23/06/2026 17:35, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
Which describes several long-obsolete API implementations.
OK.
But there is still termio stuff needed in the setup of the UART, when
all that is needed in almost all cases this century is picking the baud
rate, possibly enabling the RTS line as an RS-485 driver enable, picking
8,n,1 (other options are rare, but not quite non-existent), and then
reading and writing characters.
I would separate those into two distinct operations:
- One-time setup. Setting the line characteristics (baud rate,
stop-bits, parity) and the UART characteristics (flow
control, Rx and Tx FIFOs, Carrier Detect). For which there
are standard POSIX interfaces (tcsetattr/tcgetattr)
- steady-state operations, such as reading and writing which
use the normal file I/O operations (read, write, poll, et alia)
There are other possible features that
can be useful for UARTs, such as getting feedback when everything is
sent (via a semaphore, condition variable, or similar synchronisation
mechanism),
That really depends on OS API. STDIO buffers output, and provides
a mechanism to flush the buffers. If one bypasses stdio and uses
read/write, the programmer can call tcdrain() to ensure the data
has been transmitted or set VMIN=1 and VTIME=0 with tcsetattr
to avoid any buffering in the kernel driver.
getting feedback when there has been a pause since the last
received character, and other such things. AFAIK these are not
available with standard Linux serial port handling.
The poll(2) system call can be used for this purpose, as it
can timeout if there is no character received within a
specified interval.
Basically to gain those extensions, we need something like. This is
HYPER crude so try not to spill your coffee while reading it. ;^D
rofl.
I think its a rather low level way to make high end servers/clients
akin to dx12/vulkan vs modern opengl?
On Tue, 23 Jun 2026 21:07:48 +0200
David Brown <david.brown@hesbynett.no> wrote:
And of the perhaps 20 or 30 microcontroller families I have used over
the years, I don't remember ever having seen one with a UART that is
16550 compatible. (I did, on a couple of boards, use a dedicated
16x50 UART chip, possibly a 16450.)
I think, I had seen one, in the early 2000, on IBM PPC 4xx embedded
chip. Whether it should be considered MCU or embedded processor is a
matter of opinion. But it was pretty low end chip, esp. comparatively to PowerQUICC I that I was used to back in this era.
Other than that I agree. It seems that Dan Cross has no [1st-hand programming] experience with MCUs.
On 23/06/2026 19:12, Dan Cross wrote:
In article <111eavb$2c615$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 17:35, Scott Lurndal wrote:
It's a
total mess - it's all for handling serial terminals from the 1970's.
I'm sure that the microprocessors you routinely use all still
support either the 16550 UART or the PL011 for debug purposes
if not for production purposes. Our most recently taped out
chip has a dozen pl011 compatible UARTS.
16550 UARTs are long obsolete. Some embedded processors might have
UARTs that have register sets compatible with them, but I don't think it >>> is common. Microcontrollers certainly don't make any attempt to have
compatibility with those register sets.
This is simply incorrect. Lots of parts still have integrated
16550-compatible UARTs; the designware part that is common in a
lot of SoC's will even go up to 3MBAUD.
I don't know all embedded microprocessors. I suspect that in order to >remain as "PC compatible" as possible, x86 SoC's might have 16550
compatible UARTs.
Many others do not. The NXP i.mx family, which is one of the most
popular in industrial usage, have UARTs that do not have 16550 register >sets. There is a reason linux/drivers/tty/serial has several dozen C
files, supporting several dozen UARTs. Critically, embedded UARTs >(excluding 16550 compatible ones) support DMA.
And of the perhaps 20 or 30 microcontroller families I have used over
the years, I don't remember ever having seen one with a UART that is
16550 compatible. (I did, on a couple of boards, use a dedicated 16x50
UART chip, possibly a 16450.)
Of course all these UARTs can /talk/ to 16550 UARTs,
but they are not
compatible in their design or hardware register maps despite plenty of >similarity.
Sure, the modem signals are obsolete and not often used.
With 115k baud, it's less likely that the hardware flow
control signals (RTS/CTS) are still used (although XON/XOFF is
still useful) in most cases, but the classic serial port still
lives and is useful, particularly in embedded hardware.
I use serial ports all the time. I've never had any use for XON/XOFF,
or hardware flow control (the RTS signal is often used for RS-485 drive
enable), and regularly use 3 MBaud for local connections to fast
microcontrollers.
I use 3MBAUD, 16550-compatible UARTs embedded in AMD's EPYC SoCs
daily. We use hardware flow control to avoid dropping
characters when speaking to a fast uctlr running our own
embedded OS. The DW part in the SoC even supports auto HW flow
control and manages the FIFOs and signaling more or less
independently of the host (which actually caused a problem in
our driver a few months back).
If reliable delivery of data is important to you, some kind of
flow control is useful, whether hardware or software based. If
it's just for debug spew, you may not care.
If your systems are fast enough, and you have the right priorities for
your threads, interrupts, DMAs, etc., then you don't need flow control.
And most protocols (other than debug outputs) used over serial ports in >embedded systems are not continuous traffic flows - you have packets,
and typically have request/response patterns. As long as you have DMA
to give you FIFOs that are big enough, you can consider the packet
reception and answering as high-level software flow control.
On Tue, 23 Jun 2026 21:07:48 +0200
David Brown <david.brown@hesbynett.no> wrote:
And of the perhaps 20 or 30 microcontroller families I have used over
the years, I don't remember ever having seen one with a UART that is
16550 compatible. (I did, on a couple of boards, use a dedicated
16x50 UART chip, possibly a 16450.)
I think, I had seen one, in the early 2000, on IBM PPC 4xx embedded
chip. Whether it should be considered MCU or embedded processor is a
matter of opinion. But it was pretty low end chip, esp. comparatively to >PowerQUICC I that I was used to back in this era.
Other than that I agree. It seems that Dan Cross has no [1st-hand >programming] experience with MCUs.
On 23/06/2026 19:39, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 23/06/2026 17:35, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
Which describes several long-obsolete API implementations.
OK.
But there is still termio stuff needed in the setup of the UART, when
all that is needed in almost all cases this century is picking the baud
rate, possibly enabling the RTS line as an RS-485 driver enable, picking >>> 8,n,1 (other options are rare, but not quite non-existent), and then
reading and writing characters.
I would separate those into two distinct operations:
Yes.
- One-time setup. Setting the line characteristics (baud rate,
stop-bits, parity) and the UART characteristics (flow
control, Rx and Tx FIFOs, Carrier Detect). For which there
are standard POSIX interfaces (tcsetattr/tcgetattr)
- steady-state operations, such as reading and writing which
use the normal file I/O operations (read, write, poll, et alia)
Agreed.
It's only the setup that is a pain because of legacy terminal support.
There are other possible features that
can be useful for UARTs, such as getting feedback when everything is
sent (via a semaphore, condition variable, or similar synchronisation
mechanism),
That really depends on OS API. STDIO buffers output, and provides
a mechanism to flush the buffers. If one bypasses stdio and uses
read/write, the programmer can call tcdrain() to ensure the data
has been transmitted or set VMIN=1 and VTIME=0 with tcsetattr
to avoid any buffering in the kernel driver.
getting feedback when there has been a pause since the last
received character, and other such things. AFAIK these are not
available with standard Linux serial port handling.
The poll(2) system call can be used for this purpose, as it
can timeout if there is no character received within a
specified interval.
I guess I am used to microcontroller programming - things happen far
more directly and efficiently there. (Or I use Python, were the source
code is simple and easy, and you don't think about the layers in between
the code and the hardware!)
On Tue, 23 Jun 2026 14:41:28 -0700, Chris M. Thomasson wrote:
I think its a rather low level way to make high end servers/clients
akin to dx12/vulkan vs modern opengl?
No. Async I/O is all about performance. Whereas a programmable
shader pipeline is all about versatility.
On Tue, 23 Jun 2026 14:40:18 -0700, Chris M. Thomasson wrote:
Basically to gain those extensions, we need something like. This is
HYPER crude so try not to spill your coffee while reading it. ;^D
rofl.
Microsoft have no idea how to do shared-library versioning, do they?
On Tue, 23 Jun 2026 07:25:56 +0200
David Brown <david.brown@hesbynett.no> wrote:
[snip]
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud rate,
stop bits, parity, et alia) via library functions
(tcsetattr/tcgetattr) and using standard filesystem calls for
reading and writing.
Once the serial port is opened, it is a simple byte stream just like
any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
Just look at the documentation:
<https://docs.kernel.org/driver-api/serial/driver.html> or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
It's a total mess - it's all for handling serial terminals from the
1970's. Most of it is, of course, just a one-off setting - once you
have got the termio stuff right,
Configuration API sometimes matters.
In particular, support for various timeouts in termio is subpar
relatively to what you have in Windows. May be, Windows has too many of
them, esp. on the transmit side, but termios certainly has too few.
What is even worse, is resolution. Out of memory, resolution of
timeouts in termios is 0.1 sec. For SCADA-style protocols that's
useless.
So, it seems, the only way to implement such protocols on Linux or
similar OSes, is to read one character at time by very high priority
thread. And to pray for good luck.
Today, with many cores available everiwhere, the chance for ending up
lucky is decent. 25 years ago - less so.
and haven't accidentally got some
extra character translation or flow control, then it's just simple
reads and writes.
Of course it is hard to remove stuff once it is there - user space
APIs are, rightly, as stable as they possibly can be.
But it is possible to add better API without removing old stuff.
May be, it even exists. I didn't follow the field since ~2021.
On 6/23/2026 7:05 PM, Lawrence DrCOOliveiro wrote:
On Tue, 23 Jun 2026 14:41:28 -0700, Chris M. Thomasson wrote:
I think its a rather low level way to make high end servers/clients
akin to dx12/vulkan vs modern opengl?
No. Async I/O is all about performance. Whereas a programmable
shader pipeline is all about versatility.
But take a look on how to have to use io_uring? You have to mmap your
ring buffers and tell the kernel about them. Its more low-level, like
dx12 is more low level than modern opengl?
In article <111eli4$2g1qh$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 19:12, Dan Cross wrote:
In article <111eavb$2c615$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 17:35, Scott Lurndal wrote:
It's aI'm sure that the microprocessors you routinely use all still
total mess - it's all for handling serial terminals from the 1970's. >>>>>
support either the 16550 UART or the PL011 for debug purposes
if not for production purposes. Our most recently taped out
chip has a dozen pl011 compatible UARTS.
16550 UARTs are long obsolete. Some embedded processors might have
UARTs that have register sets compatible with them, but I don't think it >>>> is common. Microcontrollers certainly don't make any attempt to have
compatibility with those register sets.
This is simply incorrect. Lots of parts still have integrated
16550-compatible UARTs; the designware part that is common in a
lot of SoC's will even go up to 3MBAUD.
I don't know all embedded microprocessors. I suspect that in order to
remain as "PC compatible" as possible, x86 SoC's might have 16550
compatible UARTs.
Essentially every modern x86 SoC has at least one; usually
several. They may or may not be lined out, but they're there.
Some other systems may use 16550-compatible parts as well; as I
mentioned, DesignWare markets one as an embeddable piece of IP
that one can incorporate into one's own design.
Many others do not. The NXP i.mx family, which is one of the most
popular in industrial usage, have UARTs that do not have 16550 register
sets. There is a reason linux/drivers/tty/serial has several dozen C
files, supporting several dozen UARTs. Critically, embedded UARTs
(excluding 16550 compatible ones) support DMA.
I did not say that other systems used 16550, I was disputing the
incorrect statement that "16550 UARTs are long obsolete." If
you mean discrete UART chips signaling at TTL levels, whether
shifted to RS-232 levels or not, you're correct, but I took your
statement to be more general. Simply, they are not obsolete at
all, and they're extraordinarily common.
And of the perhaps 20 or 30 microcontroller families I have used over
the years, I don't remember ever having seen one with a UART that is
16550 compatible. (I did, on a couple of boards, use a dedicated 16x50
UART chip, possibly a 16450.)
Ok, but your personal experience is anecdotal and by your own
admission not representative of large machines. Judging that
the obsolesence (or not) of a part based on your own experience
alone is not a great way to make judgements about these things.
Of course all these UARTs can /talk/ to 16550 UARTs,
Yes, that's the whole point of a serial protocol between
disparate systems. :-)
but they are not
compatible in their design or hardware register maps despite plenty of
similarity.
If you go back and re-read Scott's statement, he said modern
systems are usually using a 16550 or a PL101-compatible UART.
That's true; ARM and x86 parts are extraordinarily common.
Of course, there are and have been others; I've personally
worked with Zilog and Motorola parts in addition to the
aforementioned two.
Sure, the modem signals are obsolete and not often used.
With 115k baud, it's less likely that the hardware flow
control signals (RTS/CTS) are still used (although XON/XOFF is
still useful) in most cases, but the classic serial port still
lives and is useful, particularly in embedded hardware.
I use serial ports all the time. I've never had any use for XON/XOFF, >>>> or hardware flow control (the RTS signal is often used for RS-485 drive >>>> enable), and regularly use 3 MBaud for local connections to fast
microcontrollers.
I use 3MBAUD, 16550-compatible UARTs embedded in AMD's EPYC SoCs
daily. We use hardware flow control to avoid dropping
characters when speaking to a fast uctlr running our own
embedded OS. The DW part in the SoC even supports auto HW flow
control and manages the FIFOs and signaling more or less
independently of the host (which actually caused a problem in
our driver a few months back).
If reliable delivery of data is important to you, some kind of
flow control is useful, whether hardware or software based. If
it's just for debug spew, you may not care.
If your systems are fast enough, and you have the right priorities for
your threads, interrupts, DMAs, etc., then you don't need flow control.
And most protocols (other than debug outputs) used over serial ports in
embedded systems are not continuous traffic flows - you have packets,
and typically have request/response patterns. As long as you have DMA
to give you FIFOs that are big enough, you can consider the packet
reception and answering as high-level software flow control.
Again, extrapolating from your own personal experience to other
areas is leading to a specious conclusion. You hinted at the
issue: _if_ your systems can keep up, you may be ok. But on a
large system, running a multiuser multitasking operating system,
doing a ton of IO on high speed devices, dealing with many
thousands of interrupts a second across many cores, you may not
be able to keep up.
In article <111elok$2g1qh$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 19:39, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 23/06/2026 17:35, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
Which describes several long-obsolete API implementations.
OK.
But there is still termio stuff needed in the setup of the UART, when
all that is needed in almost all cases this century is picking the baud >>>> rate, possibly enabling the RTS line as an RS-485 driver enable, picking >>>> 8,n,1 (other options are rare, but not quite non-existent), and then
reading and writing characters.
I would separate those into two distinct operations:
Yes.
- One-time setup. Setting the line characteristics (baud rate,
stop-bits, parity) and the UART characteristics (flow
control, Rx and Tx FIFOs, Carrier Detect). For which there
are standard POSIX interfaces (tcsetattr/tcgetattr)
- steady-state operations, such as reading and writing which
use the normal file I/O operations (read, write, poll, et alia)
Agreed.
It's only the setup that is a pain because of legacy terminal support.
Is it really that hard?
struct termios term;
memset(&term, 0, sizeof(term));
cfmakeraw(&term); // BSD extension
cfsetispeed(&term, B38400);
cfsetospeed(&term, B38400);
term.c_cflag |= CS8 | CREAD | CRTSCTS;
tcsetattr(fd, TCSANOW, &term)
Of course, on plan 9, it's even easier:
echo -n b38400 l8 pn s1 >/dev/eia1ctl
There are other possible features that
can be useful for UARTs, such as getting feedback when everything is
sent (via a semaphore, condition variable, or similar synchronisation
mechanism),
That really depends on OS API. STDIO buffers output, and provides
a mechanism to flush the buffers. If one bypasses stdio and uses
read/write, the programmer can call tcdrain() to ensure the data
has been transmitted or set VMIN=1 and VTIME=0 with tcsetattr
to avoid any buffering in the kernel driver.
getting feedback when there has been a pause since the last
received character, and other such things. AFAIK these are not
available with standard Linux serial port handling.
The poll(2) system call can be used for this purpose, as it
can timeout if there is no character received within a
specified interval.
I guess I am used to microcontroller programming - things happen far
more directly and efficiently there. (Or I use Python, were the source
code is simple and easy, and you don't think about the layers in between
the code and the hardware!)
"Efficiently" with respect to what? One could argue that MCUs
waste a lot of CPU cycles because their software is usually
terribly unsophisticated. A blocking system calll like `poll`
allows the operating system to context switch to some other
runnable task while the poll is pending, without the complexity
of directly handling interrupts.
In article <111elok$2g1qh$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 19:39, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 23/06/2026 17:35, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 22/06/2026 16:56, Scott Lurndal wrote:
Michael S <already5chosen@yahoo.com> writes:
On Sun, 21 Jun 2026 12:18:39 +0200
David Brown <david.brown@hesbynett.no> wrote:
or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
Which describes several long-obsolete API implementations.
OK.
But there is still termio stuff needed in the setup of the UART, when
all that is needed in almost all cases this century is picking the baud >>>> rate, possibly enabling the RTS line as an RS-485 driver enable, picking >>>> 8,n,1 (other options are rare, but not quite non-existent), and then
reading and writing characters.
I would separate those into two distinct operations:
Yes.
- One-time setup. Setting the line characteristics (baud rate,
stop-bits, parity) and the UART characteristics (flow
control, Rx and Tx FIFOs, Carrier Detect). For which there
are standard POSIX interfaces (tcsetattr/tcgetattr)
- steady-state operations, such as reading and writing which
use the normal file I/O operations (read, write, poll, et alia)
Agreed.
It's only the setup that is a pain because of legacy terminal support.
Is it really that hard?
struct termios term;
memset(&term, 0, sizeof(term));
cfmakeraw(&term); // BSD extension
cfsetispeed(&term, B38400);
cfsetospeed(&term, B38400);
term.c_cflag |= CS8 | CREAD | CRTSCTS;
tcsetattr(fd, TCSANOW, &term)
Of course, on plan 9, it's even easier:
echo -n b38400 l8 pn s1 >/dev/eia1ctl
On 23/06/2026 22:00, Michael S wrote:
On Tue, 23 Jun 2026 21:07:48 +0200
David Brown <david.brown@hesbynett.no> wrote:
And of the perhaps 20 or 30 microcontroller families I have used
over the years, I don't remember ever having seen one with a UART
that is 16550 compatible. (I did, on a couple of boards, use a
dedicated 16x50 UART chip, possibly a 16450.)
I think, I had seen one, in the early 2000, on IBM PPC 4xx embedded
chip. Whether it should be considered MCU or embedded processor is a
matter of opinion. But it was pretty low end chip, esp.
comparatively to PowerQUICC I that I was used to back in this era.
I know of the PPC 4xx series, but never used one. The PPC
microcontrollers I used first were in the 5xx series - PPC506, if I
remember correctly, then perhaps PPC561. (This is from memory, so I
might have the numbers wrong.)
And then a couple in the 5xxx
families.
One of those had two cores, and was my first use of ASMP in
a microcontroller. All the devices I used had microcontroller-style
UARTs.
Other than that I agree. It seems that Dan Cross has no [1st-hand programming] experience with MCUs.
In article <20260623224836.00001a3c@yahoo.com>,
Michael S <already5chosen@yahoo.com> wrote:
On Tue, 23 Jun 2026 07:25:56 +0200
David Brown <david.brown@hesbynett.no> wrote:
[snip]
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud
rate, stop bits, parity, et alia) via library functions
(tcsetattr/tcgetattr) and using standard filesystem calls for
reading and writing.
Once the serial port is opened, it is a simple byte stream just
like any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
Just look at the documentation:
<https://docs.kernel.org/driver-api/serial/driver.html> or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
It's a total mess - it's all for handling serial terminals from the
1970's. Most of it is, of course, just a one-off setting - once you
have got the termio stuff right,
Configuration API sometimes matters.
In particular, support for various timeouts in termio is subpar
relatively to what you have in Windows. May be, Windows has too many
of them, esp. on the transmit side, but termios certainly has too
few. What is even worse, is resolution. Out of memory, resolution of >timeouts in termios is 0.1 sec. For SCADA-style protocols that's
useless.
So, it seems, the only way to implement such protocols on Linux or
similar OSes, is to read one character at time by very high priority >thread. And to pray for good luck.
Today, with many cores available everiwhere, the chance for ending up
lucky is decent. 25 years ago - less so.
That was not your original complaint, which was about how
complecting the serial port abstraction with the TTY layer
ultimtely proved to be a poor design choice. You are correct
about that, for the record, but this complaint is a different
matter entirely.
What you're saying is that you really just want to get the TTY
layer out of the path between the user program and the serial
device. That's fine, but different.
and haven't accidentally got some
extra character translation or flow control, then it's just simple
reads and writes.
Of course it is hard to remove stuff once it is there - user space
APIs are, rightly, as stable as they possibly can be.
But it is possible to add better API without removing old stuff.
May be, it even exists. I didn't follow the field since ~2021.
I'd suggest reviewing the landscape more thoroughly. This may
be a good start: https://www.youtube.com/watch?v=g4sZUBS57OQ
- Dan C.
On Wed, 24 Jun 2026 08:32:08 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 22:00, Michael S wrote:
On Tue, 23 Jun 2026 21:07:48 +0200
David Brown <david.brown@hesbynett.no> wrote:
And of the perhaps 20 or 30 microcontroller families I have used
over the years, I don't remember ever having seen one with a UART
that is 16550 compatible. (I did, on a couple of boards, use a
dedicated 16x50 UART chip, possibly a 16450.)
I think, I had seen one, in the early 2000, on IBM PPC 4xx embedded
chip. Whether it should be considered MCU or embedded processor is a
matter of opinion. But it was pretty low end chip, esp.
comparatively to PowerQUICC I that I was used to back in this era.
I know of the PPC 4xx series, but never used one. The PPC
microcontrollers I used first were in the 5xx series - PPC506, if I
remember correctly, then perhaps PPC561. (This is from memory, so I
might have the numbers wrong.)
I am pretty sure that you are wrong.
IBM and their licensees did not make 5xx core. Only Moto/Freescale/NXP
made such parts. But they call their cores MPC rather than PPC.
And then a couple in the 5xxx
families.
Here I am less than 100% sure, but 90% sure that the same applies to
5xxx. Most likely your device was called MPC rather than PPC.
One of those had two cores, and was my first use of ASMP in
a microcontroller. All the devices I used had microcontroller-style
UARTs.
Other than that I agree. It seems that Dan Cross has no [1st-hand
programming] experience with MCUs.
On Wed, 24 Jun 2026 12:18:51 -0000 (UTC)
cross@spitfire.i.gajendra.net (Dan Cross) wrote:
In article <20260623224836.00001a3c@yahoo.com>,
Michael S <already5chosen@yahoo.com> wrote:
On Tue, 23 Jun 2026 07:25:56 +0200
David Brown <david.brown@hesbynett.no> wrote:
[snip]
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud
rate, stop bits, parity, et alia) via library functions
(tcsetattr/tcgetattr) and using standard filesystem calls for
reading and writing.
Once the serial port is opened, it is a simple byte stream just
like any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
Just look at the documentation:
<https://docs.kernel.org/driver-api/serial/driver.html> or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
It's a total mess - it's all for handling serial terminals from the
1970's. Most of it is, of course, just a one-off setting - once you
have got the termio stuff right,
Configuration API sometimes matters.
In particular, support for various timeouts in termio is subpar
relatively to what you have in Windows. May be, Windows has too many
of them, esp. on the transmit side, but termios certainly has too
few. What is even worse, is resolution. Out of memory, resolution of
timeouts in termios is 0.1 sec. For SCADA-style protocols that's
useless.
So, it seems, the only way to implement such protocols on Linux or
similar OSes, is to read one character at time by very high priority
thread. And to pray for good luck.
Today, with many cores available everiwhere, the chance for ending up
lucky is decent. 25 years ago - less so.
That was not your original complaint, which was about how
complecting the serial port abstraction with the TTY layer
ultimtely proved to be a poor design choice. You are correct
about that, for the record, but this complaint is a different
matter entirely.
What you're saying is that you really just want to get the TTY
layer out of the path between the user program and the serial
device. That's fine, but different.
Concept of layers is too abstract for my poor mind.
Especially when there are more than 2 or 3 of them.
and haven't accidentally got some
extra character translation or flow control, then it's just simple
reads and writes.
Of course it is hard to remove stuff once it is there - user space
APIs are, rightly, as stable as they possibly can be.
But it is possible to add better API without removing old stuff.
May be, it even exists. I didn't follow the field since ~2021.
I'd suggest reviewing the landscape more thoroughly. This may
be a good start: https://www.youtube.com/watch?v=g4sZUBS57OQ
- Dan C.
I don't consume technical stuff in video form.
Is it available as a written document?
[ ... ]
So, it seems, the only way to implement such protocols on Linux or
similar OSes, is to read one character at time by very high priority
thread. And to pray for good luck.
Today, with many cores available everiwhere, the chance for ending up
lucky is decent. 25 years ago - less so.
Both the slides and a transcript are linked in the video description.
On 6/23/2026 7:05 PM, Lawrence DrCOOliveiro wrote:
On Tue, 23 Jun 2026 14:41:28 -0700, Chris M. Thomasson wrote:
I think its a rather low level way to make high end
servers/clients akin to dx12/vulkan vs modern opengl?
No. Async I/O is all about performance. Whereas a programmable
shader pipeline is all about versatility.
But take a look on how to have to use io_uring?
On 24/06/2026 12:47, Dan Cross wrote:
In article <111eli4$2g1qh$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 19:12, Dan Cross wrote:
In article <111eavb$2c615$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 17:35, Scott Lurndal wrote:
It's aI'm sure that the microprocessors you routinely use all still
total mess - it's all for handling serial terminals from the 1970's. >>>>>>
support either the 16550 UART or the PL011 for debug purposes
if not for production purposes. Our most recently taped out
chip has a dozen pl011 compatible UARTS.
16550 UARTs are long obsolete. Some embedded processors might have
UARTs that have register sets compatible with them, but I don't think it >>>>> is common. Microcontrollers certainly don't make any attempt to have >>>>> compatibility with those register sets.
This is simply incorrect. Lots of parts still have integrated
16550-compatible UARTs; the designware part that is common in a
lot of SoC's will even go up to 3MBAUD.
I don't know all embedded microprocessors. I suspect that in order to
remain as "PC compatible" as possible, x86 SoC's might have 16550
compatible UARTs.
Essentially every modern x86 SoC has at least one; usually
several. They may or may not be lined out, but they're there.
Fair enough.
But x86 SoC's are a tiny fraction of SoC or embedded processors, which
are predominantly ARM based. And microcontrollers are orders of
magnitude more common than processors, embedded or not.
Assuming you are correct (and I have no reason to doubt it, but have not >checked independently) that modern x86 SoCs have 16550 UARTs, then they
are by definition not obsolete. But in pretty much all other devices, >built-in UARTs are not 16550 compatible because there are no benefits in >doing that, while alternative designs are significantly better (in
various possible ways).
So "obsolete" was an exaggeration. But I think if you were to make a
list of the top hundred microcontrollers and microprocessor SoCs, order
by the number of devices shipped during the last few years, I do not
expect you'd see more than a few low down in the list that had a 16550 UART.
(Scott also mentioned PL011 UARTs, which I did not discuss - these are
ARM designs and thus common in some ARM microprocessors, though not in
ARM microcontrollers. They are also not found in most industrial ARM
SoCs, such as the i.mx families - makers of such chips already have
their own peripheral device IPs, which they use. The PL011, from the
quick look I had, seems a reasonable enough UART for many purposes, with >support for DMA and timeouts. It appears to lack RS-485 support, but >perhaps I missed some details.)
Some other systems may use 16550-compatible parts as well; as I
mentioned, DesignWare markets one as an embeddable piece of IP
that one can incorporate into one's own design.
There are countless 16550 (or 8250, or similar) models available under a >variety of licenses.
Many others do not. The NXP i.mx family, which is one of the most
popular in industrial usage, have UARTs that do not have 16550 register
sets. There is a reason linux/drivers/tty/serial has several dozen C
files, supporting several dozen UARTs. Critically, embedded UARTs
(excluding 16550 compatible ones) support DMA.
I did not say that other systems used 16550, I was disputing the
incorrect statement that "16550 UARTs are long obsolete." If
you mean discrete UART chips signaling at TTL levels, whether
shifted to RS-232 levels or not, you're correct, but I took your
statement to be more general. Simply, they are not obsolete at
all, and they're extraordinarily common.
I accept that they exist - I dispute that they are common, at least
viewed in relation to the types of microprocessor SoCs or
microcontrollers currently available, or in terms of numbers shipped.
And of the perhaps 20 or 30 microcontroller families I have used over
the years, I don't remember ever having seen one with a UART that is
16550 compatible. (I did, on a couple of boards, use a dedicated 16x50
UART chip, possibly a 16450.)
Ok, but your personal experience is anecdotal and by your own
admission not representative of large machines. Judging that
the obsolesence (or not) of a part based on your own experience
alone is not a great way to make judgements about these things.
Embedded ARM systems outship embedded x86 systems by a factor of 1000 or >more (from my attempts at googling - noting that you don't get real, >concrete figures without paying real, concrete money to marketing and >analysis companies). There are also devices where the core is neither
ARM nor x86. None of these, as a rule, have 16550's - they have much
better UARTs. (For small microcontrollers, "better" can mean smaller
and lower power, rather than necessarily additional useful features.)
Remember, the sole reason anyone would want to use a 16550 is
compatibility with code that expects a 16550. And that means, to a very >large extent, old x86 code or newer x86 code that is written to be >compatible with the old code and hardware.
[snip personal experience]
Of course, there are and have been others; I've personally
worked with Zilog and Motorola parts in addition to the
aforementioned two.
To be clear here, you are saying you have worked with microprocessors or >microcontrollers with other kinds of UARTs than 16550's or PL011's ? Or
with other stand-alone UART chips?
I know both Motorola and Zilog
produced stand-alone UART chips, and I know Motorola (then Freescale,
now part of NXP) have made a countless number of processors and >microcontrollers with built-in UARTs that are not 16550 compatible.
Sure, the modem signals are obsolete and not often used.
With 115k baud, it's less likely that the hardware flow
control signals (RTS/CTS) are still used (although XON/XOFF is
still useful) in most cases, but the classic serial port still
lives and is useful, particularly in embedded hardware.
I use serial ports all the time. I've never had any use for XON/XOFF, >>>>> or hardware flow control (the RTS signal is often used for RS-485 drive >>>>> enable), and regularly use 3 MBaud for local connections to fast
microcontrollers.
I use 3MBAUD, 16550-compatible UARTs embedded in AMD's EPYC SoCs
daily. We use hardware flow control to avoid dropping
characters when speaking to a fast uctlr running our own
embedded OS. The DW part in the SoC even supports auto HW flow
control and manages the FIFOs and signaling more or less
independently of the host (which actually caused a problem in
our driver a few months back).
If reliable delivery of data is important to you, some kind of
flow control is useful, whether hardware or software based. If
it's just for debug spew, you may not care.
If your systems are fast enough, and you have the right priorities for
your threads, interrupts, DMAs, etc., then you don't need flow control.
And most protocols (other than debug outputs) used over serial ports in
embedded systems are not continuous traffic flows - you have packets,
and typically have request/response patterns. As long as you have DMA
to give you FIFOs that are big enough, you can consider the packet
reception and answering as high-level software flow control.
Again, extrapolating from your own personal experience to other
areas is leading to a specious conclusion. You hinted at the
issue: _if_ your systems can keep up, you may be ok. But on a
large system, running a multiuser multitasking operating system,
doing a ton of IO on high speed devices, dealing with many
thousands of interrupts a second across many cores, you may not
be able to keep up.
Of course you can, if that's what you want to do with the system.
A Gbit network interface generates thousands of interrupts a second. But
is entirely fair to say that general purpose OS's, and x86 hardware, are
not well suited to quick reactions and low or predictable latencies.
Throughput is usually not an issue, but accurate timing is hard to
achieve. It is not without reason that many embedded systems have a
Linux SOM for networking and high-level decisions, and microcontrollers
for the fast reaction and deterministic control stuff. (Many SoC's >targetting industrial embedded Linux have microcontrollers in the SoC >itself.) And it is also fair to say that if you want to have demanding >serial port usage on a general-purpose OS, you want a decent, modern
UART rather than an old-fashioned 16550.
On 24/06/2026 13:04, Dan Cross wrote:
In article <111elok$2g1qh$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
[snip]
Agreed.
It's only the setup that is a pain because of legacy terminal support.
Is it really that hard?
struct termios term;
memset(&term, 0, sizeof(term));
cfmakeraw(&term); // BSD extension
cfsetispeed(&term, B38400);
cfsetospeed(&term, B38400);
term.c_cflag |= CS8 | CREAD | CRTSCTS;
tcsetattr(fd, TCSANOW, &term)
It took a good deal more than that when I did it. But it is certainly >possible that my reference sources for the task were not the best
available. Note also that it's not just the number of lines of C code - >it's knowing what those lines are, what settings you need, which headers
to find the declarations, etc.
[snip]
I guess I am used to microcontroller programming - things happen far
more directly and efficiently there. (Or I use Python, were the source
code is simple and easy, and you don't think about the layers in between >>> the code and the hardware!)
"Efficiently" with respect to what? One could argue that MCUs
waste a lot of CPU cycles because their software is usually
terribly unsophisticated. A blocking system calll like `poll`
allows the operating system to context switch to some other
runnable task while the poll is pending, without the complexity
of directly handling interrupts.
No, I don't think you can argue that at all - sophisticated software at
the OS level wastes as many cycles as sophisticated software at the >application level.
In my microcontroller programming, the serial handling is as
sophisticated or simple as I need it to be. It could be application
code reading and writing hardware registers directly, with busy-waiting >loops. More likely data is transferred into or out of DMA based ring >buffers that feed the UART.
What I don't have is layers of possible translations because the user
might be connecting to a VT100, or expecting the driver to handle
backspace and XON/XOFF.
I don't have to pass data up and down through
the VFS and devfs, checking user permissions, or system calls that have
to check everything coming from user space. I realise that a lot of
this is necessary in Linux (or any other general-purpose OS) - you can't >make a system safe for multiple users and multiple programmers without
lots of checks, and you can't allow "echo Hello > /dev/ttyUSB0" without
lots of abstraction.
Directly handling interrupts in a microcontroller is not particularly >complex - it's daily work for microcontroller developers.
And we too know how to have blocking calls and multiple threads.
On Wed, 24 Jun 2026 12:18:51 -0000 (UTC)
cross@spitfire.i.gajendra.net (Dan Cross) wrote:
In article <20260623224836.00001a3c@yahoo.com>,
Michael S <already5chosen@yahoo.com> wrote:
On Tue, 23 Jun 2026 07:25:56 +0200
David Brown <david.brown@hesbynett.no> wrote:
[snip]
The POSIX serial interface seems quite useful - using ioctl(2)
to handle non-data-transfer interfaces (e.g. setting the baud
rate, stop bits, parity, et alia) via library functions
(tcsetattr/tcgetattr) and using standard filesystem calls for
reading and writing.
Once the serial port is opened, it is a simple byte stream just
like any other unix file.
Bitbanging RS232C for SCADA was never a design goal, unlike
IEEE 488.
Just look at the documentation:
<https://docs.kernel.org/driver-api/serial/driver.html> or
<https://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux>.
It's a total mess - it's all for handling serial terminals from the
1970's. Most of it is, of course, just a one-off setting - once you
have got the termio stuff right,
Configuration API sometimes matters.
In particular, support for various timeouts in termio is subpar
relatively to what you have in Windows. May be, Windows has too many
of them, esp. on the transmit side, but termios certainly has too
few. What is even worse, is resolution. Out of memory, resolution of
timeouts in termios is 0.1 sec. For SCADA-style protocols that's
useless.
So, it seems, the only way to implement such protocols on Linux or
similar OSes, is to read one character at time by very high priority
thread. And to pray for good luck.
Today, with many cores available everiwhere, the chance for ending up
lucky is decent. 25 years ago - less so.
That was not your original complaint, which was about how
complecting the serial port abstraction with the TTY layer
ultimtely proved to be a poor design choice. You are correct
about that, for the record, but this complaint is a different
matter entirely.
What you're saying is that you really just want to get the TTY
layer out of the path between the user program and the serial
device. That's fine, but different.
Concept of layers is too abstract for my poor mind.
Especially when there are more than 2 or 3 of them.
and haven't accidentally got some
extra character translation or flow control, then it's just simple
reads and writes.
Of course it is hard to remove stuff once it is there - user space
APIs are, rightly, as stable as they possibly can be.
But it is possible to add better API without removing old stuff.
May be, it even exists. I didn't follow the field since ~2021.
I'd suggest reviewing the landscape more thoroughly. This may
be a good start: https://www.youtube.com/watch?v=g4sZUBS57OQ
I don't consume technical stuff in video form.
Is it available as a written document?
In article <111gkgm$2vhih$1@dont-email.me>,<snip>
David Brown <david.brown@hesbynett.no> wrote:
A Gbit network interface generates thousands of interrupts a second. But >>is entirely fair to say that general purpose OS's, and x86 hardware, are >>not well suited to quick reactions and low or predictable latencies.
In article <20260624220010.00006ed7@yahoo.com>,
Michael S <already5chosen@yahoo.com> wrote:
Concept of layers is too abstract for my poor mind.
Especially when there are more than 2 or 3 of them.
Huh.
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 24/06/2026 12:47, Dan Cross wrote:
In article <111eli4$2g1qh$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 19:12, Dan Cross wrote:
In article <111eavb$2c615$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 23/06/2026 17:35, Scott Lurndal wrote:
It's aI'm sure that the microprocessors you routinely use all still
total mess - it's all for handling serial terminals from the 1970's. >>>>>>>
support either the 16550 UART or the PL011 for debug purposes
if not for production purposes. Our most recently taped out
chip has a dozen pl011 compatible UARTS.
16550 UARTs are long obsolete. Some embedded processors might have >>>>>> UARTs that have register sets compatible with them, but I don't think it >>>>>> is common. Microcontrollers certainly don't make any attempt to have >>>>>> compatibility with those register sets.
This is simply incorrect. Lots of parts still have integrated
16550-compatible UARTs; the designware part that is common in a
lot of SoC's will even go up to 3MBAUD.
I don't know all embedded microprocessors. I suspect that in order to >>>> remain as "PC compatible" as possible, x86 SoC's might have 16550
compatible UARTs.
Essentially every modern x86 SoC has at least one; usually
several. They may or may not be lined out, but they're there.
Fair enough.
But x86 SoC's are a tiny fraction of SoC or embedded processors, which
are predominantly ARM based. And microcontrollers are orders of
magnitude more common than processors, embedded or not.
Again, not something I was commenting on. Low(er) volume !=
obsolete.
Assuming you are correct (and I have no reason to doubt it, but have not
checked independently) that modern x86 SoCs have 16550 UARTs, then they
are by definition not obsolete. But in pretty much all other devices,
built-in UARTs are not 16550 compatible because there are no benefits in
doing that, while alternative designs are significantly better (in
various possible ways).
There are things I do not like about the 8250-series UARTs, but
I do not know what criteria you are using to judge the relative
merits of the 16550 versus alternatives. Given that you don't
use them, one wonders what your basis for comparison is, as
well.
So "obsolete" was an exaggeration. But I think if you were to make a
list of the top hundred microcontrollers and microprocessor SoCs, order
by the number of devices shipped during the last few years, I do not
expect you'd see more than a few low down in the list that had a 16550 UART.
Perhaps? But also irrelevant.
(Scott also mentioned PL011 UARTs, which I did not discuss - these are
ARM designs and thus common in some ARM microprocessors, though not in
ARM microcontrollers. They are also not found in most industrial ARM
SoCs, such as the i.mx families - makers of such chips already have
their own peripheral device IPs, which they use. The PL011, from the
quick look I had, seems a reasonable enough UART for many purposes, with
support for DMA and timeouts. It appears to lack RS-485 support, but
perhaps I missed some details.)
I just checked and it looks like ST ships PL011's in a bunch of
Cortex-M class parts.
Of course, there are a ton of ARM
microcontrollers, but if you reread Scott's message (again) he
mentions mircoprocessors, not specificially uctlr's.
Some other systems may use 16550-compatible parts as well; as I
mentioned, DesignWare markets one as an embeddable piece of IP
that one can incorporate into one's own design.
There are countless 16550 (or 8250, or similar) models available under a
variety of licenses.
Yes.
Many others do not. The NXP i.mx family, which is one of the most
popular in industrial usage, have UARTs that do not have 16550 register >>>> sets. There is a reason linux/drivers/tty/serial has several dozen C
files, supporting several dozen UARTs. Critically, embedded UARTs
(excluding 16550 compatible ones) support DMA.
I did not say that other systems used 16550, I was disputing the
incorrect statement that "16550 UARTs are long obsolete." If
you mean discrete UART chips signaling at TTL levels, whether
shifted to RS-232 levels or not, you're correct, but I took your
statement to be more general. Simply, they are not obsolete at
all, and they're extraordinarily common.
I accept that they exist - I dispute that they are common, at least
viewed in relation to the types of microprocessor SoCs or
microcontrollers currently available, or in terms of numbers shipped.
That's fine, but I made no statement about that.
And of the perhaps 20 or 30 microcontroller families I have used over
the years, I don't remember ever having seen one with a UART that is
16550 compatible. (I did, on a couple of boards, use a dedicated 16x50 >>>> UART chip, possibly a 16450.)
Ok, but your personal experience is anecdotal and by your own
admission not representative of large machines. Judging that
the obsolesence (or not) of a part based on your own experience
alone is not a great way to make judgements about these things.
Embedded ARM systems outship embedded x86 systems by a factor of 1000 or
more (from my attempts at googling - noting that you don't get real,
concrete figures without paying real, concrete money to marketing and
analysis companies). There are also devices where the core is neither
ARM nor x86. None of these, as a rule, have 16550's - they have much
better UARTs. (For small microcontrollers, "better" can mean smaller
and lower power, rather than necessarily additional useful features.)
term% uname -a
OpenBSD rv64.local 7.9 GENERIC.MP#5 riscv64
term% dmesg | grep 16550
com0 at simplebus0: dw16550
term%
Remember, the sole reason anyone would want to use a 16550 is
compatibility with code that expects a 16550. And that means, to a very
large extent, old x86 code or newer x86 code that is written to be
compatible with the old code and hardware.
Sure. I'm sure there are any number of reasons why a vendor
would pick any given type of UART; software compatibility with
existing drivers is surely one of them.
[snip personal experience]
Of course, there are and have been others; I've personally
worked with Zilog and Motorola parts in addition to the
aforementioned two.
To be clear here, you are saying you have worked with microprocessors or
microcontrollers with other kinds of UARTs than 16550's or PL011's ? Or
with other stand-alone UART chips?
Yes to both. In this case, I am referring specifically to
discrete UART parts from both vendors.
I know both Motorola and Zilog
produced stand-alone UART chips, and I know Motorola (then Freescale,
now part of NXP) have made a countless number of processors and
microcontrollers with built-in UARTs that are not 16550 compatible.
I don't know what the latter has to do with the former, or the
larger discussion. You seem to be discussing something that I
never said or implied.
FTR I am saying I have used discrete UART parts from both Zilog
(Zilog UARTs used to be common in Sun workstations) and Motorola
(they had a reasonable DUART that worked well with 68k).
Sure, the modem signals are obsolete and not often used.
With 115k baud, it's less likely that the hardware flow
control signals (RTS/CTS) are still used (although XON/XOFF is
still useful) in most cases, but the classic serial port still
lives and is useful, particularly in embedded hardware.
I use serial ports all the time. I've never had any use for XON/XOFF, >>>>>> or hardware flow control (the RTS signal is often used for RS-485 drive >>>>>> enable), and regularly use 3 MBaud for local connections to fast
microcontrollers.
I use 3MBAUD, 16550-compatible UARTs embedded in AMD's EPYC SoCs
daily. We use hardware flow control to avoid dropping
characters when speaking to a fast uctlr running our own
embedded OS. The DW part in the SoC even supports auto HW flow
control and manages the FIFOs and signaling more or less
independently of the host (which actually caused a problem in
our driver a few months back).
If reliable delivery of data is important to you, some kind of
flow control is useful, whether hardware or software based. If
it's just for debug spew, you may not care.
If your systems are fast enough, and you have the right priorities for >>>> your threads, interrupts, DMAs, etc., then you don't need flow control. >>>>
And most protocols (other than debug outputs) used over serial ports in >>>> embedded systems are not continuous traffic flows - you have packets,
and typically have request/response patterns. As long as you have DMA >>>> to give you FIFOs that are big enough, you can consider the packet
reception and answering as high-level software flow control.
Again, extrapolating from your own personal experience to other
areas is leading to a specious conclusion. You hinted at the
issue: _if_ your systems can keep up, you may be ok. But on a
large system, running a multiuser multitasking operating system,
doing a ton of IO on high speed devices, dealing with many
thousands of interrupts a second across many cores, you may not
be able to keep up.
Of course you can, if that's what you want to do with the system.
No, not really.
Perhaps in the uctlr world that is true, but in that world
workloads tend to be fixed and predictible; in the world of
large systems, things are far more dynamic. Interrupts can, and
do, get lost; FIFOs get full; data can get corrupted; flow
control and synchronization between endpoints in a
communications protocol is useful.
Perhaps that doesn't matter for your use cases, and you've never
needed it; but don't extrapolate to other use cases you have no
experience with.
A Gbit network interface generates thousands of interrupts a second. But
is entirely fair to say that general purpose OS's, and x86 hardware, are
not well suited to quick reactions and low or predictable latencies.
The hardware is fine. It's the OS that usually struggles
because there may be more load on the machine than can
reasonably be accommodated.
Throughput is usually not an issue, but accurate timing is hard to
achieve. It is not without reason that many embedded systems have a
Linux SOM for networking and high-level decisions, and microcontrollers
for the fast reaction and deterministic control stuff. (Many SoC's
targetting industrial embedded Linux have microcontrollers in the SoC
itself.) And it is also fair to say that if you want to have demanding
serial port usage on a general-purpose OS, you want a decent, modern
UART rather than an old-fashioned 16550.
Again, you haven't specified what's "old-fashioned" about it, or
what makes alternatives superior; on modern systems, this is not
your father's 8250. Modern SoCs support DMA and MMIO accesses
for UARTs and speeds up to 3MBAUD or more, even if the registers
are the same 'ol 16550 registers since the 486 era (with some
extensions, of course).
Beyond that, you're correct that many modern SoCs have embedded microcontrollers capable of real-time response; yay. Using one
just to avoid flow control over a serial protocol seems like
going to extremes to avoid a simple thing. As I mentioned, the
DW part even does CTS/RTS HW flow control automatically, without
software intervention.
This is hardly an obsolete part in any measurable sense, and
arguments about the volume of microcontrollers using other parts
don't make it obsolete.
- Dan C.
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
Embedded ARM systems outship embedded x86 systems by a factor of 1000 or >>> more (from my attempts at googling - noting that you don't get real,
concrete figures without paying real, concrete money to marketing and
analysis companies). There are also devices where the core is neither
ARM nor x86. None of these, as a rule, have 16550's - they have much
better UARTs. (For small microcontrollers, "better" can mean smaller
and lower power, rather than necessarily additional useful features.)
term% uname -a
OpenBSD rv64.local 7.9 GENERIC.MP#5 riscv64
term% dmesg | grep 16550
com0 at simplebus0: dw16550
term%
That is very interesting, and somewhat unexpected. Thanks for the
example. Where is this riscv core from?
<snip> (My understanding is that for very fast network
cards on big systems, you dedicate a core to the task and using polling >rather than interrupts to avoid context switches. But that is
definitely outside my experience.)
David Brown <david.brown@hesbynett.no> writes:
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
Embedded ARM systems outship embedded x86 systems by a factor of 1000 or >>>> more (from my attempts at googling - noting that you don't get real,
concrete figures without paying real, concrete money to marketing and
analysis companies). There are also devices where the core is neither >>>> ARM nor x86. None of these, as a rule, have 16550's - they have much
better UARTs. (For small microcontrollers, "better" can mean smaller
and lower power, rather than necessarily additional useful features.)
term% uname -a
OpenBSD rv64.local 7.9 GENERIC.MP#5 riscv64
term% dmesg | grep 16550
com0 at simplebus0: dw16550
term%
That is very interesting, and somewhat unexpected. Thanks for the
example. Where is this riscv core from?
The dw16550 is synopsys (DW_apb_uart) optimized for the ARM
APB bus. It's modeled on the 16550 for backward compatability
yet includes additional features from 16650 and 16750 designs
using MMIO registers rather than the x86 I/O space registers.
It seems to be popular in some DSUs (e.g. Marvell Armada).
<snip> (My understanding is that for very fast network
cards on big systems, you dedicate a core to the task and using polling
rather than interrupts to avoid context switches. But that is
definitely outside my experience.)
There are various techniques to moderate the interrupt frequency
at high packet arrival rates. Usually based on a packet-count + timer; the interrupt fires after the specified number of packets has arrived
or the timer has expired.
In article <111gm0p$2vhih$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 24/06/2026 13:04, Dan Cross wrote:
In article <111elok$2g1qh$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
[snip]
Agreed.
It's only the setup that is a pain because of legacy terminal support.
Is it really that hard?
struct termios term;
memset(&term, 0, sizeof(term));
cfmakeraw(&term); // BSD extension
cfsetispeed(&term, B38400);
cfsetospeed(&term, B38400);
term.c_cflag |= CS8 | CREAD | CRTSCTS;
tcsetattr(fd, TCSANOW, &term)
It took a good deal more than that when I did it. But it is certainly
possible that my reference sources for the task were not the best
available. Note also that it's not just the number of lines of C code -
it's knowing what those lines are, what settings you need, which headers
to find the declarations, etc.
One presumes that you if you are using, say, the POSIX
interfaces, you'll have some idea of how to write code for POSIX
and have access to a reference. My system's man pages are
reasonable for the latter.
[snip]
I guess I am used to microcontroller programming - things happen far
more directly and efficiently there. (Or I use Python, were the source >>>> code is simple and easy, and you don't think about the layers in between >>>> the code and the hardware!)
"Efficiently" with respect to what? One could argue that MCUs
waste a lot of CPU cycles because their software is usually
terribly unsophisticated. A blocking system calll like `poll`
allows the operating system to context switch to some other
runnable task while the poll is pending, without the complexity
of directly handling interrupts.
No, I don't think you can argue that at all - sophisticated software at
the OS level wastes as many cycles as sophisticated software at the
application level.
Again, I ask, "efficiently" with respect to what? Note what I
said: "One could argue that MCUs waste a lot of CPU cycles
because their software _is usually terribly unsophisticated_":
emphasis added.
In my microcontroller programming, the serial handling is as
sophisticated or simple as I need it to be. It could be application
code reading and writing hardware registers directly, with busy-waiting
loops. More likely data is transferred into or out of DMA based ring
buffers that feed the UART.
What I don't have is layers of possible translations because the user
might be connecting to a VT100, or expecting the driver to handle
backspace and XON/XOFF.
You are conflating the TTY layer in Unix-style systems with the
serial port driver, specifically. I will acknowledge that this
is a problem; a TTY-abstraction might have made sense in the
1970s ("VT100?! Luxury. I'm stuck with an ASR Model 37
teletype...."), but does not make a lot of sense now, but that
does not mean that large systems _need_ to use that metaphor.
See the Plan 9 examples I keep sprinkling around; that system
doesn't have a TTY abstraction at all.
I don't have to pass data up and down through
the VFS and devfs, checking user permissions, or system calls that have
to check everything coming from user space. I realise that a lot of
this is necessary in Linux (or any other general-purpose OS) - you can't
make a system safe for multiple users and multiple programmers without
lots of checks, and you can't allow "echo Hello > /dev/ttyUSB0" without
lots of abstraction.
The purpose of an operating system is to control hardware,
isolate software principles from one another, and provide useful
programming abstractions. Essentially what you're saying is
that you don't want or need that, for some kinds of programs.
That's fine. But to extrapolate from that to, "and this
category of software is more efficient", as an absolute
statement, is what I take exception to: there's too much
disconfirming evidence to the contrary. Perhaps not in the
programs you personally write, but I took your statement was
general and not restricted to only those programs.
Directly handling interrupts in a microcontroller is not particularly
complex - it's daily work for microcontroller developers.
Yes, because if your needs are not as general as those demanded
by general purposes operating systems on general purpose CPUs,
it can be made reasonably simple.
As I mentioned, most (not
all) programs that target microcontrollers are not terribly
sophisticated, and have very modest requirements in this regard.
And we too know how to have blocking calls and multiple threads.
...and there are embedded OSes that have system calls and
privileged modes that restrict access to the hardware, too. :-}
On Wed, 24 Jun 2026 04:36:20 -0700, Chris M. Thomasson wrote:
On 6/23/2026 7:05 PM, Lawrence DrCOOliveiro wrote:
On Tue, 23 Jun 2026 14:41:28 -0700, Chris M. Thomasson wrote:
I think its a rather low level way to make high end
servers/clients akin to dx12/vulkan vs modern opengl?
No. Async I/O is all about performance. Whereas a programmable
shader pipeline is all about versatility.
But take a look on how to have to use io_uring?
Except you donrCOt (usually) have to use io_uring, as I already showed.
David Brown <david.brown@hesbynett.no> writes:
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
Embedded ARM systems outship embedded x86 systems by a factor of
1000 or more (from my attempts at googling - noting that you
don't get real, concrete figures without paying real, concrete
money to marketing and analysis companies). There are also
devices where the core is neither ARM nor x86. None of these, as
a rule, have 16550's - they have much better UARTs. (For small
microcontrollers, "better" can mean smaller and lower power,
rather than necessarily additional useful features.)
term% uname -a
OpenBSD rv64.local 7.9 GENERIC.MP#5 riscv64
term% dmesg | grep 16550
com0 at simplebus0: dw16550
term%
That is very interesting, and somewhat unexpected. Thanks for the >example. Where is this riscv core from?
The dw16550 is synopsys (DW_apb_uart) optimized for the ARM
APB bus. It's modeled on the 16550 for backward compatability
yet includes additional features from 16650 and 16750 designs
using MMIO registers rather than the x86 I/O space registers.
It seems to be popular in some DSUs (e.g. Marvell Armada).
<snip> (My understanding is that for very fast network
cards on big systems, you dedicate a core to the task and using
polling rather than interrupts to avoid context switches. But that
is definitely outside my experience.)
There are various techniques to moderate the interrupt frequency
at high packet arrival rates. Usually based on a packet-count +
timer; the interrupt fires after the specified number of packets has
arrived or the timer has expired.
On 25/06/2026 20:29, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
term% uname -a
Embedded ARM systems outship embedded x86 systems by a factor of 1000 or >>>>> more (from my attempts at googling - noting that you don't get real, >>>>> concrete figures without paying real, concrete money to marketing and >>>>> analysis companies). There are also devices where the core is neither >>>>> ARM nor x86. None of these, as a rule, have 16550's - they have much >>>>> better UARTs. (For small microcontrollers, "better" can mean smaller >>>>> and lower power, rather than necessarily additional useful features.) >>>>
OpenBSD rv64.local 7.9 GENERIC.MP#5 riscv64
term% dmesg | grep 16550
com0 at simplebus0: dw16550
term%
That is very interesting, and somewhat unexpected. Thanks for the
example. Where is this riscv core from?
The dw16550 is synopsys (DW_apb_uart) optimized for the ARM
APB bus. It's modeled on the 16550 for backward compatability
yet includes additional features from 16650 and 16750 designs
using MMIO registers rather than the x86 I/O space registers.
It seems to be popular in some DSUs (e.g. Marvell Armada).
<snip> (My understanding is that for very fast network
cards on big systems, you dedicate a core to the task and using polling
rather than interrupts to avoid context switches. But that is
definitely outside my experience.)
There are various techniques to moderate the interrupt frequency
at high packet arrival rates. Usually based on a packet-count + timer; the >> interrupt fires after the specified number of packets has arrived
or the timer has expired.
Basically, a FIFO at the packet level, in the same way that byte FIFOs
work for UARTs ? I am sure that is a very good idea, especially for the >higher speed interfaces. I don't see a problem with thousands of
interrupts a second for 1 Gbps networking,
but I do not see it going so
well when scaling by a factor of 100 for 100 Gpbs!
And for even higher
rates, I believe it is common to have various kinds of accelerators
tightly integrated with the network interface, further reducing the work
(or at least the latency challenges) for the host.
But again, those are
not things I have done myself.
David Brown <david.brown@hesbynett.no> writes:
On 25/06/2026 20:29, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
term% uname -a
Embedded ARM systems outship embedded x86 systems by a factor of 1000 or >>>>>> more (from my attempts at googling - noting that you don't get real, >>>>>> concrete figures without paying real, concrete money to marketing and >>>>>> analysis companies). There are also devices where the core is neither >>>>>> ARM nor x86. None of these, as a rule, have 16550's - they have much >>>>>> better UARTs. (For small microcontrollers, "better" can mean smaller >>>>>> and lower power, rather than necessarily additional useful features.) >>>>>
OpenBSD rv64.local 7.9 GENERIC.MP#5 riscv64
term% dmesg | grep 16550
com0 at simplebus0: dw16550
term%
That is very interesting, and somewhat unexpected. Thanks for the
example. Where is this riscv core from?
The dw16550 is synopsys (DW_apb_uart) optimized for the ARM
APB bus. It's modeled on the 16550 for backward compatability
yet includes additional features from 16650 and 16750 designs
using MMIO registers rather than the x86 I/O space registers.
It seems to be popular in some DSUs (e.g. Marvell Armada).
<snip> (My understanding is that for very fast network
cards on big systems, you dedicate a core to the task and using polling >>>> rather than interrupts to avoid context switches. But that is
definitely outside my experience.)
There are various techniques to moderate the interrupt frequency
at high packet arrival rates. Usually based on a packet-count + timer; the
interrupt fires after the specified number of packets has arrived
or the timer has expired.
Basically, a FIFO at the packet level, in the same way that byte FIFOs
work for UARTs ? I am sure that is a very good idea, especially for the
higher speed interfaces. I don't see a problem with thousands of
interrupts a second for 1 Gbps networking,
That's a lot of unnecessary overhead. Consider that at 1Gb/s,
the controller can theoretically receive 1,488,095 64-byte packets every second.
That's a million and a half interrupts per second.
but I do not see it going so
well when scaling by a factor of 100 for 100 Gpbs!
Tis truth, forsooth.
And for even higher
rates, I believe it is common to have various kinds of accelerators
tightly integrated with the network interface, further reducing the work
(or at least the latency challenges) for the host.
Indeed. Packet classification/Receive-side-scaling, handling the
various tunneling protocols, VLANs, IPSEC, MPLS et alia are all efficiently done by hardware accelerators. Something I have done myself :-)
But again, those are
not things I have done myself.
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 24/06/2026 12:47, Dan Cross wrote:Again, not something I was commenting on. Low(er) volume !=
[snip]
obsolete.
OK. I have already accepted that "obsolete" was an exaggeration. More >appropriate would be "not suitable for new designs".
Assuming you are correct (and I have no reason to doubt it, but have not >>> checked independently) that modern x86 SoCs have 16550 UARTs, then they
are by definition not obsolete. But in pretty much all other devices,
built-in UARTs are not 16550 compatible because there are no benefits in >>> doing that, while alternative designs are significantly better (in
various possible ways).
There are things I do not like about the 8250-series UARTs, but
I do not know what criteria you are using to judge the relative
merits of the 16550 versus alternatives. Given that you don't
use them, one wonders what your basis for comparison is, as
well.
I already said that I /had/ used one, as specific external chip, on a
board. Admittedly that was a long time ago.
But regardless of how much or how little I have used them, I am entirely >capable of looking at a datasheet and judging the features a device has
or does not have. I can look at the way a peripheral is connected, and
the kind of databus it supports, the kind of inputs and outputs it has,
the registers it has, and everything else. That's an important part of
the job I do. The idea that I would have to have /used/ a device to be
able to compare it to other related devices is, frankly, bizarre.
[snip]
I just checked and it looks like ST ships PL011's in a bunch of
Cortex-M class parts.
Have you a reference for those?
[snip]
Of course, there are a ton of ARM
microcontrollers, but if you reread Scott's message (again) he
mentions mircoprocessors, not specificially uctlr's.
And if you re-read Scott's message, you'll see there's been a dozen
posts since then - mentioning other related things. We have moved on
from there.
[snip]
term% uname -a
OpenBSD rv64.local 7.9 GENERIC.MP#5 riscv64
term% dmesg | grep 16550
com0 at simplebus0: dw16550
term%
That is very interesting, and somewhat unexpected. Thanks for the
example. Where is this riscv core from?
I know both Motorola and Zilog
produced stand-alone UART chips, and I know Motorola (then Freescale,
now part of NXP) have made a countless number of processors and
microcontrollers with built-in UARTs that are not 16550 compatible.
I don't know what the latter has to do with the former, or the
larger discussion. You seem to be discussing something that I
never said or implied.
(As a general point, not everything people write is an immediate direct >response to what someone else wrote - nor is it necessarily disputing
what they wrote. People add extra information, anecdotes,
clarifications, questions, and digressions. Several times you have said
my comments were irrelevant, or denied saying or implying the point you >think I am disputing. My posts are not a series of attacks on what I >imagine you said. While it is entirely possible that I misunderstand or >misread something someone says, and respond to that misunderstood point, >usually if I write something that does not appear to be a direct
response to a previous point, it is not a direct response to /any/ point
- real or imagined. Conversations would quickly get boring if they
never wander a little from previous points.)
[snip]
No, not really.
Perhaps in the uctlr world that is true, but in that world
workloads tend to be fixed and predictible; in the world of
large systems, things are far more dynamic. Interrupts can, and
do, get lost; FIFOs get full; data can get corrupted; flow
control and synchronization between endpoints in a
communications protocol is useful.
I do appreciate that on "big" systems things are more dynamic and >unpredictable compared to many microcontroller systems. And yes, things
can get lost or corrupted - that is true in communications in >microcontroller systems too. As the Mythbuster's tee-shirt says,
failure is always an option. You almost always want some kind of
control, synchronisation, error checking, and retry mechanism. You
usually have several of these, at different levels of the system from
the hardware, through low-level drivers or interfaces, and up to
high-level control.
But yes, really - you /can/ handle thousands of interrupts per second on >Linux systems if you want to.
I've happily passed packets through Linux
systems at high speeds, without failures. My current system has a >microcontroller connected to a Linux SOM. My focus is on the >microcontroller software, but amongst other things I have Python code on
the PC sending UDP telegrams via the SOM (with a USB to Ethernet dongle)
to the microcontroller. I run about 2,000+ transactions a second,
without failures - where a transaction means the Linux SOM getting a
packet in, routing it out to the microcontroller, getting a reply back,
and routing that towards the PC. In the background, the SOM is
continuously bzipping and bunzipping a big file, just to have it working
on something. How many interrupts per second do you think that is?
Of course there are other patterns of interrupts that are more stressful >than the ones I have there. But then, I am running just a single core
SoC here, and the speed bottlenecks are mostly in the Python test code.
And I have done nothing towards improving the latencies or anything else
- this is a bog standard Debian ARM installation.
Perhaps that doesn't matter for your use cases, and you've never
needed it; but don't extrapolate to other use cases you have no
experience with.
I have worked on systems where we have locked interrupts and programs to >particular cores (of a 4 core SoC) to minimise jitter, with real-time >extensions in the kernel. Admittedly there were not many packets
handled in and out every millisecond, but the millisecond tick needed to
be within about 1% jitter.
Of course there are vast combinations of hardware and requirements that
I have /not/ worked with. But I have seen enough to know that you can
do a great deal with Linux even without careful tuning - and even more
with tuning. Thousands of interrupts per second is peanuts to a modern >Linux system - big or small. Tens or hundreds of thousands of
interrupts per second - then you are pushing it, and will want to
re-think things a bit. (My understanding is that for very fast network >cards on big systems, you dedicate a core to the task and using polling >rather than interrupts to avoid context switches. But that is
definitely outside my experience.)
And certainly it is harder to do high frequency operations on Linux, and
on microprocessors, than on microcontrollers. Context switches are >massively more demanding, and you have little details like "security"
that are a different world on a multi-user system than on a
microcontroller. On one 500 MHz microcontroller I did some testing with
an RTOS doing round-robin context switches at 1 MHz, taking about 10% of
the processor capacity. I don't think you'd get far with a jiffy rate
of 1 MHz on any Linux system, big or small. And I have also had a
system where I did bit-banging of a 115200 baud UART with 4x
oversampling. That's 460,800 timer interrupts per second - on a >microcontroller running with a 18.432 MHz clock. 40 clocks per
interrupt, and time to spare for the rest of the application.
Throughput is usually not an issue, but accurate timing is hard to
achieve. It is not without reason that many embedded systems have a
Linux SOM for networking and high-level decisions, and microcontrollers
for the fast reaction and deterministic control stuff. (Many SoC's
targetting industrial embedded Linux have microcontrollers in the SoC
itself.) And it is also fair to say that if you want to have demanding
serial port usage on a general-purpose OS, you want a decent, modern
UART rather than an old-fashioned 16550.
Again, you haven't specified what's "old-fashioned" about it, or
what makes alternatives superior; on modern systems, this is not
your father's 8250. Modern SoCs support DMA and MMIO accesses
for UARTs and speeds up to 3MBAUD or more, even if the registers
are the same 'ol 16550 registers since the 486 era (with some
extensions, of course).
Well, to be fair it depends on what you want to do with the UART - and
my bias is towards industrial systems. I guess the biggest want an
RS-485 driver line - when doing faster communication, that is an
essential feature. (While I have never had the dubious pleasure of >implementing Profibus DP, it runs at 12 Mbps on RS-485.) I like better >control of FIFOs and triggers, for both interrupts and DMA. I have >occasionally had need of 9 bit characters. Sending break characters is >important in some protocols, like LIN. Automatic detection of frame
start characters can significantly reduce the load on the rest of the >system. Many modern full-featured UARTs have additional features like >swapping pin polarity (great for when people wire up RS-485 buses >incorrectly) or Rx/Tx pins, IrDA support, Smartcard support, Manchester >encoding and other things that could reasonably also be done in hardware >outside the UART.
And of course there are different balances that can be achieved between >features and power usage, and die space.
Usually most UARTs are usable for most purposes, but some are definitely >more convenient and better suited than others for offloading work.
Beyond that, you're correct that many modern SoCs have embedded
microcontrollers capable of real-time response; yay. Using one
just to avoid flow control over a serial protocol seems like
going to extremes to avoid a simple thing. As I mentioned, the
DW part even does CTS/RTS HW flow control automatically, without
software intervention.
I would not pick a UART to /avoid/ hardware flow control support - but
it is not a feature I have seen as useful since the days of dial-up
modems. XON/XOFF style of software flow control is completely absent
from anything I have been involved in. Of course there this software >synchronisation and control, but it is at a higher level.
On 25/06/2026 20:29, Scott Lurndal wrote:
David Brown <david.brown@hesbynett.no> writes:
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
term% uname -a
Embedded ARM systems outship embedded x86 systems by a factor of 1000 or >>>>> more (from my attempts at googling - noting that you don't get real, >>>>> concrete figures without paying real, concrete money to marketing and >>>>> analysis companies). There are also devices where the core is neither >>>>> ARM nor x86. None of these, as a rule, have 16550's - they have much >>>>> better UARTs. (For small microcontrollers, "better" can mean smaller >>>>> and lower power, rather than necessarily additional useful features.) >>>>
OpenBSD rv64.local 7.9 GENERIC.MP#5 riscv64
term% dmesg | grep 16550
com0 at simplebus0: dw16550
term%
That is very interesting, and somewhat unexpected. Thanks for the
example. Where is this riscv core from?
The dw16550 is synopsys (DW_apb_uart) optimized for the ARM
APB bus. It's modeled on the 16550 for backward compatability
yet includes additional features from 16650 and 16750 designs
using MMIO registers rather than the x86 I/O space registers.
It seems to be popular in some DSUs (e.g. Marvell Armada).
<snip> (My understanding is that for very fast network
cards on big systems, you dedicate a core to the task and using polling
rather than interrupts to avoid context switches. But that is
definitely outside my experience.)
There are various techniques to moderate the interrupt frequency
at high packet arrival rates. Usually based on a packet-count + timer; the >> interrupt fires after the specified number of packets has arrived
or the timer has expired.
Basically, a FIFO at the packet level, in the same way that byte FIFOs
work for UARTs ? I am sure that is a very good idea, especially for the >higher speed interfaces. I don't see a problem with thousands of
interrupts a second for 1 Gbps networking, but I do not see it going so
well when scaling by a factor of 100 for 100 Gpbs! And for even higher >rates, I believe it is common to have various kinds of accelerators
tightly integrated with the network interface, further reducing the work
(or at least the latency challenges) for the host. But again, those are
not things I have done myself.
On 25/06/2026 13:56, Dan Cross wrote:
In article <111gm0p$2vhih$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 24/06/2026 13:04, Dan Cross wrote:
In article <111elok$2g1qh$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
[snip]Is it really that hard?
Agreed.
It's only the setup that is a pain because of legacy terminal support. >>>>
struct termios term;
memset(&term, 0, sizeof(term));
cfmakeraw(&term); // BSD extension
cfsetispeed(&term, B38400);
cfsetospeed(&term, B38400);
term.c_cflag |= CS8 | CREAD | CRTSCTS;
tcsetattr(fd, TCSANOW, &term)
It took a good deal more than that when I did it. But it is certainly
possible that my reference sources for the task were not the best
available. Note also that it's not just the number of lines of C code - >>> it's knowing what those lines are, what settings you need, which headers >>> to find the declarations, etc.
One presumes that you if you are using, say, the POSIX
interfaces, you'll have some idea of how to write code for POSIX
and have access to a reference. My system's man pages are
reasonable for the latter.
Sure. But not all references are created equal, and I am merely saying
that the references or examples that I used might not have been the
best, or were maybe outdated or overly complex.
[snip]
I guess I am used to microcontroller programming - things happen far >>>>> more directly and efficiently there. (Or I use Python, were the source >>>>> code is simple and easy, and you don't think about the layers in between >>>>> the code and the hardware!)
"Efficiently" with respect to what? One could argue that MCUs
waste a lot of CPU cycles because their software is usually
terribly unsophisticated. A blocking system calll like `poll`
allows the operating system to context switch to some other
runnable task while the poll is pending, without the complexity
of directly handling interrupts.
No, I don't think you can argue that at all - sophisticated software at
the OS level wastes as many cycles as sophisticated software at the
application level.
Again, I ask, "efficiently" with respect to what? Note what I
said: "One could argue that MCUs waste a lot of CPU cycles
because their software _is usually terribly unsophisticated_":
emphasis added.
Let me rephrase - I don't think you can /reasonably/ argue that, without
at a minimum some concrete examples of MCUs wasting lots of CPU cycles
due to terribly unsophisticated software for UART handling, and a >justification for thinking it is common practice. I suppose you could
say that sometimes microcontroller software works by polling UART
hardware status registers in busy-waiting loops, but it is not likely to
be common practice except in special circumstances.
If code on my microcontroller wants to sent data to the UART (i.e., put
it into the software FIFO that feeds the hardware FIFO), the call is
perhaps 30 cycles plus maybe 6 or 8 per byte sent. Entering a "wait for
end of received frame event" is maybe 50 cycles, and the time from the
UART detecting the idle time, triggering the event, and the resulting >context switch starting up the blocked task is perhaps 200 cycles.
Those are all rough guesses out of my head, I have not measured them.
How many cpu cycles does it take for a program on Linux to send out a
dozen bytes on a UART, or between the UART hardware detecting the
receive timeout to the polling process exiting the poll() call?
[snip]
The purpose of an operating system is to control hardware,
isolate software principles from one another, and provide useful
programming abstractions. Essentially what you're saying is
that you don't want or need that, for some kinds of programs.
There a range of possible OS types, with kernels ranging from micro to >monolithic, widely different ideas of how much separation different
tasks need, and how much hardware control is done in the OS or in other >code. It is certainly the case that the features I want from an RTOS on
a microcontroller differ significantly from what I want in a general
purpose OS on a PC or other "big" system.
That's fine. But to extrapolate from that to, "and this
category of software is more efficient", as an absolute
statement, is what I take exception to: there's too much
disconfirming evidence to the contrary. Perhaps not in the
programs you personally write, but I took your statement was
general and not restricted to only those programs.
To be clear - when comparing efficiency, you have to know when you are >comparing apples to apples, and apples to oranges. My point is that for >many tasks, microcontrollers are more efficient but it is an apples to >oranges comparison in the details since the big OS has many other
important considerations.
Directly handling interrupts in a microcontroller is not particularly
complex - it's daily work for microcontroller developers.
Yes, because if your needs are not as general as those demanded
by general purposes operating systems on general purpose CPUs,
it can be made reasonably simple.
Exactly.
Microcontroller code will typically be much more focused and specialised.
As I mentioned, most (not
all) programs that target microcontrollers are not terribly
sophisticated, and have very modest requirements in this regard.
I am still not sure what you are saying here. It sounds a bit like you
have been saying the code is not sophisticated and therefore inefficient
and wasteful of cycles, when it is often the case that code is not very >sophisticated because it can be done simply and efficiently.
And we too know how to have blocking calls and multiple threads.
...and there are embedded OSes that have system calls and
privileged modes that restrict access to the hardware, too. :-}
Yes, there are. Again, I have used some of these at times.
In article <111jnmp$3tni8$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 24/06/2026 12:47, Dan Cross wrote:Again, not something I was commenting on. Low(er) volume !=
[snip]
obsolete.
OK. I have already accepted that "obsolete" was an exaggeration. More
appropriate would be "not suitable for new designs".
Something approximately 16550-shaped will be in essentially
every new x86 SoC, because there's basically no incentive to
change: modern variants support DMA, speeds in the MBAUD, are
not tied to x86 programmed IO, and are fine for consoles,
communication between disparate IPs on a board, and so on.
I get that you don't think this series is suitable for embedded
use, and that's fine: don't use it if you you don't want to in microcontroller applications. But you're using your experience
in that domain to extrapolate and make a value judgement that
doesn't follow in a different domain.
The DW APB from Synopsis is common and I mentioned it at least
twice before Scott did, but you don't seem at all familiar with
it; it's pretty common.
[snip]
I just checked and it looks like ST ships PL011's in a bunch of
Cortex-M class parts.
Have you a reference for those?
[snip]
Actually, I think I was just wrong; the device I was thinking of
that used the PL011 off the shelf from ST was the ARM926 based
chip you mentioned: it's old, and they don't have them in their
Cortex-M offerings.
The RPi2040 and Zynq boards seem to have PL011s, but are much
lower volume.
That is very interesting, and somewhat unexpected. Thanks for the
example. Where is this riscv core from?
That is from a JH7110 SoC in a StarFive VisionFive2 SBC. I use
those things for little utility machines around the house (DHCP,
DNS, etc).
Ok, fair points. I conress I find it somewhat difficult to
follow your exact line of discussion becuase it jumps between seemingly-unrelated points.
But yes, really - you /can/ handle thousands of interrupts per second on
Linux systems if you want to.
Of course. But eventually, if you saturate the system enough,
something has to give. That's when data in flight can get lost.
I've happily passed packets through Linux
systems at high speeds, without failures. My current system has a
microcontroller connected to a Linux SOM. My focus is on the
microcontroller software, but amongst other things I have Python code on
the PC sending UDP telegrams via the SOM (with a USB to Ethernet dongle)
to the microcontroller. I run about 2,000+ transactions a second,
without failures - where a transaction means the Linux SOM getting a
packet in, routing it out to the microcontroller, getting a reply back,
and routing that towards the PC. In the background, the SOM is
continuously bzipping and bunzipping a big file, just to have it working
on something. How many interrupts per second do you think that is?
No idea. About eight years ago, on a 192 Xeon core system, with
256GB of RAM and a 200Gbps NIC plus about 16TB of NVMe, I
regularly saw ~250k interrupts/sec across the fabric in the
steady-state, bursting up to a million or so.
Of course there are other patterns of interrupts that are more stressful
than the ones I have there. But then, I am running just a single core
SoC here, and the speed bottlenecks are mostly in the Python test code.
And I have done nothing towards improving the latencies or anything else
- this is a bog standard Debian ARM installation.
Perhaps that doesn't matter for your use cases, and you've never
needed it; but don't extrapolate to other use cases you have no
experience with.
I have worked on systems where we have locked interrupts and programs to
particular cores (of a 4 core SoC) to minimise jitter, with real-time
extensions in the kernel. Admittedly there were not many packets
handled in and out every millisecond, but the millisecond tick needed to
be within about 1% jitter.
So you're optimizing for latency, not throughput. Ok.
Of course there are vast combinations of hardware and requirements that
I have /not/ worked with. But I have seen enough to know that you can
do a great deal with Linux even without careful tuning - and even more
with tuning. Thousands of interrupts per second is peanuts to a modern
Linux system - big or small. Tens or hundreds of thousands of
interrupts per second - then you are pushing it, and will want to
re-think things a bit. (My understanding is that for very fast network
cards on big systems, you dedicate a core to the task and using polling
rather than interrupts to avoid context switches. But that is
definitely outside my experience.)
And certainly it is harder to do high frequency operations on Linux, and
on microprocessors, than on microcontrollers. Context switches are
massively more demanding, and you have little details like "security"
that are a different world on a multi-user system than on a
microcontroller. On one 500 MHz microcontroller I did some testing with
an RTOS doing round-robin context switches at 1 MHz, taking about 10% of
the processor capacity. I don't think you'd get far with a jiffy rate
of 1 MHz on any Linux system, big or small. And I have also had a
system where I did bit-banging of a 115200 baud UART with 4x
oversampling. That's 460,800 timer interrupts per second - on a
microcontroller running with a 18.432 MHz clock. 40 clocks per
interrupt, and time to spare for the rest of the application.
That, frankly, seems kind of hard to believe: the math just does
not add up, even assuming no wait states for access to e.g.
SRAM and single-cycle memory access times, with an instruction
dispatched per cycle; did you just, like, NEVER touch memory or
more than 2 or 3 registers in that path? Was the internal CPU
frequency 18MHz, or was that a reference oscillator?
I think the DW part I mentioned does, basically, all of those
thngs. I don't know about swapping Rx/Tx pins; I suspect that'd
be a function of the pin mux on the parts I'm most familiar
with.
And of course there are different balances that can be achieved between
features and power usage, and die space.
Usually most UARTs are usable for most purposes, but some are definitely
more convenient and better suited than others for offloading work.
Beyond that, you're correct that many modern SoCs have embedded
microcontrollers capable of real-time response; yay. Using one
just to avoid flow control over a serial protocol seems like
going to extremes to avoid a simple thing. As I mentioned, the
DW part even does CTS/RTS HW flow control automatically, without
software intervention.
I would not pick a UART to /avoid/ hardware flow control support - but
it is not a feature I have seen as useful since the days of dial-up
modems. XON/XOFF style of software flow control is completely absent
from anything I have been involved in. Of course there this software
synchronisation and control, but it is at a higher level.
Correction: it's not a feature that is usefulf or _your use
cases_. Again, I urge caution in making assumptions about other
use cases based on that.
In article <111jnmp$3tni8$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 24/06/2026 12:47, Dan Cross wrote:Again, not something I was commenting on. Low(er) volume !=
[snip]
obsolete.
OK. I have already accepted that "obsolete" was an exaggeration.
More appropriate would be "not suitable for new designs".
Something approximately 16550-shaped will be in essentially
every new x86 SoC, because there's basically no incentive to
change: modern variants support DMA, speeds in the MBAUD, are
not tied to x86 programmed IO, and are fine for consoles,
communication between disparate IPs on a board, and so on.
In article <111jnmp$3tni8$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
I think the DW part I mentioned does, basically, all of those
thngs. I don't know about swapping Rx/Tx pins; I suspect that'd
be a function of the pin mux on the parts I'm most familiar
with.
Michael S <already5chosen@yahoo.com> wrote:
[ ... ][...]
About 25 years ago I wanted to synchronize my computer's clock to
the NIST Automated Computer Time Service [1] over a dialup modem.
The computer was an alphalinux with a 21164 if I remember correctly.
One core, but fast for the time.
NIST sends a ~50 character timestamp string, followed after a short pause
by a "*" on-time-marker. Reading the string one char at a time in a
tight loop didn't work, it dropped characters. Just saying.
The right way, in pseudocode:
[...]
[1] https://www.nist.gov/pml/time-and-frequency-division/time-distribution/automated-computer-time-service-acts
Don't know if NIST still operates the service. I hope so, there are
many places left with no Internet access.
In article <111jvkg$168d$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 25/06/2026 13:56, Dan Cross wrote:
In article <111gm0p$2vhih$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 24/06/2026 13:04, Dan Cross wrote:
In article <111elok$2g1qh$2@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
[snip]
Let me rephrase - I don't think you can /reasonably/ argue that, without
at a minimum some concrete examples of MCUs wasting lots of CPU cycles
due to terribly unsophisticated software for UART handling, and a
justification for thinking it is common practice. I suppose you could
say that sometimes microcontroller software works by polling UART
hardware status registers in busy-waiting loops, but it is not likely to
be common practice except in special circumstances.
I'll wager a month's salary that the _vast_ bulk of MCU software
sits in a tight loop polling one or two bits in a couple of
registers. Sophisticated context handling, thread switching
(a lot of 8-bit MCUs just don't have enough memory available for
multiple stacks, let alone thread save areas), or even
interrupts are _probably_ pretty rare.
If code on my microcontroller wants to sent data to the UART (i.e., put
it into the software FIFO that feeds the hardware FIFO), the call is
perhaps 30 cycles plus maybe 6 or 8 per byte sent. Entering a "wait for
end of received frame event" is maybe 50 cycles, and the time from the
UART detecting the idle time, triggering the event, and the resulting
context switch starting up the blocked task is perhaps 200 cycles.
Those are all rough guesses out of my head, I have not measured them.
How many cpu cycles does it take for a program on Linux to send out a
dozen bytes on a UART, or between the UART hardware detecting the
receive timeout to the polling process exiting the poll() call?
That's an apples/oranges comparison.
What you really want to
ask is, how much time does it take to enqueue data into the
outbound ring buffer for a particular device, and how many
cycles does it take to fill the output FIFO from the ring when
space becomes available? Both of those costs _can_ be very low.
What is the cost of busy-waiting? It's hard to say.
If you only have a small handful of tasks, and everything is in
the same address space, then sure, picking a different thread to
run and doing the coroutine jump dance to resume it isn't that
hard.
Distance between timing out (say) a poll and a user program
exiting a system call is difficult to measure, since a polled
event happening doesn't mean that the system call automatically
returns; it means that the task that invoked the system call is
unblocked gets marked runnable; when it actually runs again
depends on a lot of factors (load vs available resources;
scheduling latency; time quantums assigned to currently running
tasks; etc). Most Unix/Linux-style schedulers are not real
time schedulers; so we freqntly just say, "eventually."
There's a whole branch of systems research devoted to doing this
as efficiently as possible.
[snip]
The purpose of an operating system is to control hardware,
isolate software principles from one another, and provide useful
programming abstractions. Essentially what you're saying is
that you don't want or need that, for some kinds of programs.
There a range of possible OS types, with kernels ranging from micro to
monolithic, widely different ideas of how much separation different
tasks need, and how much hardware control is done in the OS or in other
code. It is certainly the case that the features I want from an RTOS on
a microcontroller differ significantly from what I want in a general
purpose OS on a PC or other "big" system.
That's fine. But to extrapolate from that to, "and this
category of software is more efficient", as an absolute
statement, is what I take exception to: there's too much
disconfirming evidence to the contrary. Perhaps not in the
programs you personally write, but I took your statement was
general and not restricted to only those programs.
To be clear - when comparing efficiency, you have to know when you are
comparing apples to apples, and apples to oranges. My point is that for
many tasks, microcontrollers are more efficient but it is an apples to
oranges comparison in the details since the big OS has many other
important considerations.
That's kind of my point. The statement you made that I
responded to was that microcontroller software is "more
efficient" than what a general purpose OS does. It is more
nuanced than that, as it so often is: this is one reason I
dislike categorical statements of that nature.
Directly handling interrupts in a microcontroller is not particularly
complex - it's daily work for microcontroller developers.
Yes, because if your needs are not as general as those demanded
by general purposes operating systems on general purpose CPUs,
it can be made reasonably simple.
Exactly.
Microcontroller code will typically be much more focused and specialised.
Which doesn't necessarily mean more efficient. That was my
point.
As I mentioned, most (not
all) programs that target microcontrollers are not terribly
sophisticated, and have very modest requirements in this regard.
I am still not sure what you are saying here. It sounds a bit like you
have been saying the code is not sophisticated and therefore inefficient
and wasteful of cycles, when it is often the case that code is not very
sophisticated because it can be done simply and efficiently.
What I am saying is that words have meaning, and if you're going
to make an absolute statement about the relative efficiency of
one category of system versus another, you need to qualify what
you mean.
And we too know how to have blocking calls and multiple threads.
...and there are embedded OSes that have system calls and
privileged modes that restrict access to the hardware, too. :-}
Yes, there are. Again, I have used some of these at times.
The salient characteristic is that they share many of the same
properties of OSes on larger systems: MPUs might divide the
available address space into discrete regions, and so context
switching now involves memory-management hardware, where perhaps
it did not before. The point is that, even within "embedded
systems" there's too much variability to make absolute
statements. In general, I advice refraining from such for
precisely that reason.
[snip]
[snip]
I just checked and it looks like ST ships PL011's in a bunch of
Cortex-M class parts.
Have you a reference for those?
[snip]
Actually, I think I was just wrong; the device I was thinking of
that used the PL011 off the shelf from ST was the ARM926 based
chip you mentioned: it's old, and they don't have them in their
Cortex-M offerings.
OK. Those were older chips - in the earlier days of ARM processor SoCs >(though ST was a little later than many others), designs from the likes
of NXP and ST were based more on complete packages or reference designs
from ARM. The types of IP licenses these manufacturers have with ARM
have varied as they moved from making just a few ARM devices along with
all their other chips, towards having ARM processor and microcontroller >cores across a solid proportion of their portfolios. I expect they
started with whatever was easiest for other ARM users (thus the PL011),
and now integrate a lot more of their own peripherals in their chips. It
is also not uncommon that big manufacturers buy smaller manufacturers,
and so their early devices have whatever the small manufacturers used -
that will be off-the-shelf peripherals. Then later on, they do more >integration and use their own peripherals (saving them money). I don't
know the history of ST's ARM processor SoCs at all - despite being one
of the biggest in the ARM microcontroller world, they are relative
newcomers to the processor / embedded Linux side of things.
The RPi2040 and Zynq boards seem to have PL011s, but are much
lower volume.
That is perhaps slightly unexpected (for me) - both come from companies
that can happily make their own UART implementations to avoid additional >royalties to ARM, and money is always the main motivator. But maybe
they don't pay much, or maybe they make their own PL011-compatible UARTs
- ARM license terms are rarely public knowledge!
That is very interesting, and somewhat unexpected. Thanks for the
example. Where is this riscv core from?
That is from a JH7110 SoC in a StarFive VisionFive2 SBC. I use
those things for little utility machines around the house (DHCP,
DNS, etc).
I think it's a good thing if there are more Risc-V devices around - ARM
is too dominant in many areas, and while standardisation on common
platforms is convenient, competition is good too.
How does this board compare to the ubiquitous Raspberry Pi's for such
uses? Neither DHCP nor DNS are particularly challenging applications, >unless you have a huge network, but your "etc." might cover other things.
[snip]
No idea. About eight years ago, on a 192 Xeon core system, with
256GB of RAM and a 200Gbps NIC plus about 16TB of NVMe, I
regularly saw ~250k interrupts/sec across the fabric in the
steady-state, bursting up to a million or so.
Perhaps we can conclude that Linux systems can handle lots of
interrupts, but too many become inefficient and have a risk of losing
some. Careful system tuning and consideration of the pattern of
interrupts lets you handle more without losses, but smarter hardware the >reduces the interrupt rate is essential at some point. And attempts at >putting figures on things is going to be too vague or require far more >detail of the hardware and applications than appropriate here.
[snip]
That, frankly, seems kind of hard to believe: the math just does
not add up, even assuming no wait states for access to e.g.
SRAM and single-cycle memory access times, with an instruction
dispatched per cycle; did you just, like, NEVER touch memory or
more than 2 or 3 registers in that path? Was the internal CPU
frequency 18MHz, or was that a reference oscillator?
No, the chip ran at 18.432 MHz - it was an 8-bit AVR microcontroller.
Most instructions are single cycle, except for branches (mostly 1 or 2 >cycles), call / return, and load/store to memory (2 cycles). That >application was all in assembly, and I split the cpu's 32 registers
between ones used in the software UART timer interrupt, and ones used in
the main code. Thus no cycles were needed for stacking or restoring >registers on interrupts, or other context switch stuff other than the PC
and flag registers.
It would, of course, have made more sense to have had a different >microcontroller with an additional UART, but sometimes you have to make >things work with the board you have. (And it was fun :-) )
On Sat, 27 Jun 2026 01:52:24 -0000 (UTC)
cross@spitfire.i.gajendra.net (Dan Cross) wrote:
In article <111jnmp$3tni8$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 25/06/2026 13:29, Dan Cross wrote:
In article <111gkgm$2vhih$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
On 24/06/2026 12:47, Dan Cross wrote:Again, not something I was commenting on. Low(er) volume !=
[snip]
obsolete.
OK. I have already accepted that "obsolete" was an exaggeration.
More appropriate would be "not suitable for new designs".
Something approximately 16550-shaped will be in essentially
every new x86 SoC, because there's basically no incentive to
change: modern variants support DMA, speeds in the MBAUD, are
not tied to x86 programmed IO, and are fine for consoles,
communication between disparate IPs on a board, and so on.
And why do you call such thing "16550-shaped" ?
What exactly is left from 16550?
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 70 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 37:38:24 |
| Calls: | 948 |
| Calls today: | 2 |
| Files: | 1,325 |
| Messages: | 280,462 |