• this guy talks about fopen (and im thinking about fopen for network)

    From fir@profesor.fir@gmail.com to comp.lang.c on Mon Jun 8 17:49:03 2026
    From Newsgroup: comp.lang.c

    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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Mon Jun 8 18:16:10 2026
    From Newsgroup: comp.lang.c

    fir pisze:
    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

    maybe someone who has some experience with socked programming know how
    the basic communication would look like using this fopen scheme

    main()

    {
    FILE* f = fopen("1.2.3.4:555");

    fprintf(f, "hello there\n"); fflush(f);

    for(int i=0; i<100; i++)
    {
    static char buf[4096];
    if(fgets(buf, sizeof(buf), f))
    printf("incoming: %s", buf);

    Sleep(100); //wait 100 ms



    }


    }
    something like that?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Mon Jun 8 18:24:06 2026
    From Newsgroup: comp.lang.c

    fir pisze:
    fir pisze:
    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

    maybe someone who has some experience with socked programming know how
    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?

    that sockets are so shit i maybe could learn imagining how it could more
    look in old c stdlib (still they probably be in stdlib in fact)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Tue Jun 9 00:26:08 2026
    From Newsgroup: comp.lang.c

    On Mon, 8 Jun 2026 17:49:03 +0200, fir wrote:

    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

    On POSIX systems, the actual connection setup is not done by opening
    normal files, but once setup, the result is an fd that can be used
    with many regular fd calls. In particular, for a stream connection,
    you can get by with normal read/write calls for most purposes. And poll(2)/epoll(2) work just fine, of course.

    Plan9 tried to do all network I/O this way -- pretend itrCOs all just
    file I/O. I donrCOt think it works all that well.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Tue Jun 9 00:28:48 2026
    From Newsgroup: comp.lang.c

    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 ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Tue Jun 9 08:56:00 2026
    From Newsgroup: comp.lang.c

    Lawrence DrCOOliveiro pisze:
    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 ...


    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

    i 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) 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
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Tue Jun 9 10:26:13 2026
    From Newsgroup: comp.lang.c

    fir pisze:
    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

    ok i slightly talked with ai how it looks like and seems that it is such
    as i thought in cse of TCP (withs some details, ai say that the buffers
    are smaller in network cards and data are passed to kernel level ram
    buffer, which is maybe not so big again but the tcp can stop undil data
    are consumed)

    this sleep scheme is imo ok ..becouse generally if you have no sleep
    you will hang on some event loop and if so this event loop hanging
    internally must have something like sleep wake up mechanism and if
    its internall it means its worse imo (until you eventually know
    externally this mechanisms)...so imo sleep is ok



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Tue Jun 9 09:10:04 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Tue Jun 9 11:34:36 2026
    From Newsgroup: comp.lang.c

    Lawrence DrCOOliveiro pisze:
    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 standard techniques are not necesarelly much good imo...ans 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)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Paul@nospam@needed.invalid to comp.lang.c on Tue Jun 9 06:02:25 2026
    From Newsgroup: comp.lang.c

    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


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Tue Jun 9 12:18:12 2026
    From Newsgroup: comp.lang.c

    Paul pisze:
    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

    im not sure what about this all is? some try to say that event driven is better than poling? (imo polling is probably generally better)
    (polling is "classical" and easy, by simple sleep (which should be very effective by itself) one can do a lot and the code is clean)

    but what has svchost to it all?


    BTW im rather fan of sleep() but maybe im not much fan of hanging on
    this event queue...imo it would be probably better not have its
    explicitelly but maybe just registering an event handler (one big for
    all events of maybe many specific ones) THOUGH there is also option
    for even not registering handles but indeed just having a raw acces to
    this queue (filled by system) and manage it itself
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Tue Jun 9 12:25:24 2026
    From Newsgroup: comp.lang.c

    On 09/06/2026 11:34, fir wrote:
    Lawrence DrCOOliveiro pisze:
    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 standard techniques are not necesarelly much good imo...ans 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 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. 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. 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.)

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Tue Jun 9 12:31:40 2026
    From Newsgroup: comp.lang.c

    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:

    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 standard techniques are not necesarelly much good imo...ans 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.-a (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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Tue Jun 9 13:43:53 2026
    From Newsgroup: comp.lang.c

    fir pisze:
    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:

    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 standard techniques are not necesarelly much good imo...ans
    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

    as to servers though i dont think the situation would be quite different

    you got

    for(;;)
    {
    fread(..., f);
    //do something
    fwrite(..., f);

    sleep(1);
    }

    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)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Tue Jun 9 13:53:28 2026
    From Newsgroup: comp.lang.c

    fir pisze:
    fir pisze:
    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:

    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 standard techniques are not necesarelly much good imo...ans
    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

    as to servers though i dont think the situation would be quite different

    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)

    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

    othervvise it could be i think

    game_loop()
    {
    if(frame_number>0)
    receive_enemy_state(); //in first frame we only send (?)

    //game mechanic

    send_player_state();

    draw_frame();
    sleep(10);

    }

    where those receive_enemy_state/send_player_state are simple functions
    based on some fread/fwrite

    imo its generally gard to write apps with a lot of error handling
    mechanic so it would be better to keep it simple (and how error hendling mechanic it would need i dont know yet)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 9 13:54:51 2026
    From Newsgroup: comp.lang.c

    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. 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 ...

    ir_uring? ;^)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 9 13:55:25 2026
    From Newsgroup: comp.lang.c

    On 6/9/2026 2: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.

    Well, for servers/clients in windows, IOCP is key.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Kaz Kylheku@046-301-5902@kylheku.com to comp.lang.c on Tue Jun 9 21:21:49 2026
    From Newsgroup: comp.lang.c

    On 2026-06-08, fir <profesor.fir@gmail.com> wrote:
    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

    That's how it is in the Plan 9 operating system. It takes the
    "everything is a file" paradigm that Unix started on. Unix diverged
    from that paradigm in implementing new things like networking.


    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..

    "Using fopen" is better is basically "using strings is better"
    in disguise. When you use fopen to open a network client or server
    connection, all the connection parameters have to be encoded into
    a character string, instead of binary structures.

    That makes some things easy, such as binding to networking from a new programming language (no "FFI" required, just buffered file I/O and
    string munging).

    The strings are inefficient, though; they have to be formatted
    and parsed. They lack type safety. You can put wrong values
    into a binary address structure, but in a string you can cause
    a syntax error. And worse, injection security holes and whatnot.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Tue Jun 9 23:45:50 2026
    From Newsgroup: comp.lang.c

    On Tue, 9 Jun 2026 06:02:25 -0400, Paul wrote:

    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.

    It has long been known that the Windows update process is very
    inefficient, for some reason <https://www.tomshardware.com/news/windows-update-needs-eight-hours>.

    I have more than a thousandrCa packages installed on my main Linux
    system, and it can still evaluate all the updates needed in just a
    few minutes.

    rCaThe command rCLdpkg-query -l | grep -c ^irCY reports a count of 5503.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Tue Jun 9 23:47:26 2026
    From Newsgroup: comp.lang.c

    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)>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Tue Jun 9 23:56:25 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 10 00:00:50 2026
    From Newsgroup: comp.lang.c

    On Tue, 9 Jun 2026 11:34:36 +0200, fir wrote:

    Lawrence DrCOOliveiro pisze:

    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 standard techniques are not necesarelly much good imo...ans
    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 10 00:02:17 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 9 21:42:58 2026
    From Newsgroup: comp.lang.c

    On 6/9/2026 4:47 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 9 Jun 2026 13:54:51 -0700, Chris M. Thomasson wrote:

    ir_uring? ;^)

    io_uring, you mean?

    DOH!



    That, too, is a possibility, for even higher performance.

    <https://manpages.debian.org/io_uring(7)>

    Oh I think so.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 9 21:52:39 2026
    From Newsgroup: comp.lang.c

    On 6/9/2026 4:56 PM, Lawrence DrCOOliveiro wrote:
    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
    {
    per_io* m_recv;
    per_io* m_send;
    per_io* m_accept;
    per_io* m_connect;
    //...
    };

    Just heads for single linked lists of per io data wrt WSAOVERLAPPED.

    Pass execute the cohort usually in another thread pool.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 9 21:55:35 2026
    From Newsgroup: comp.lang.c

    On 6/9/2026 9:52 PM, Chris M. Thomasson wrote:

    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.

    The only time an IO thread should block is when there is NO io to do...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 9 22:05:04 2026
    From Newsgroup: comp.lang.c

    On 6/9/2026 9:52 PM, Chris M. Thomasson wrote:
    [...]

    You can see how that would work right? a cohort is built up on an io
    thread using the fact that GQCSEX can return multiple completions, and
    we can check it using a zero timeout. If that returns no completions,
    then that can be one of the triggers for the io thread to pass its per
    thread cohort to the logic threads.

    So, we know that after a GQCSEX fails to return any completions, we can
    send local cohorts to the logic threads, and wait on GQCSEX with a
    timeout. Usually say one minute. Then the IO thread can timeout and
    check things, try again, etc. This works with INFINITE timeout as well,
    but a minute timeout can be good as well, depending on your needs.

    So a cohort was actually:

    struct cohort
    {
    struct cohort* m_next;
    per_io* m_recv;
    per_io* m_send;
    per_io* m_accept;
    per_io* m_connect;
    //...
    };




    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 9 23:01:28 2026
    From Newsgroup: comp.lang.c

    On 6/9/2026 4:47 PM, Lawrence DrCOOliveiro wrote:
    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)>

    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


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 10 06:03:19 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 10 06:21:28 2026
    From Newsgroup: comp.lang.c

    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 ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 10 06:47:38 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Wed Jun 10 08:55:37 2026
    From Newsgroup: comp.lang.c

    Lawrence DrCOOliveiro pisze:
    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?

    well if it would be guarantee if i got it its a whole then i no need to
    check in client code

    (note btw i got no experience in any network programing except writing
    one or two winsock hello worlds..and here i try to understand the
    problem with no experience more lika arhitecturally/theoretically (so
    i can make many mistakes not knowing the reality/practice ...but the
    reality seems so boring it was always to boring to learn - when spending
    some
    time to try to understand it theoretically is at least less borong)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Wed Jun 10 09:06:08 2026
    From Newsgroup: comp.lang.c

    Lawrence DrCOOliveiro pisze:
    On Tue, 9 Jun 2026 11:34:36 +0200, fir wrote:

    Lawrence DrCOOliveiro pisze:

    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 standard techniques are not necesarelly much good imo...ans
    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.

    this 100 ms was an example not more meaning than using "foo" name if 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 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
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 10 00:14:56 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 10 00:24:35 2026
    From Newsgroup: comp.lang.c

    On 6/9/2026 11:03 PM, Lawrence DrCOOliveiro wrote:
    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.

    You can run IOCP with a single thread, nothing stops you. But why
    deliberately nerf the model? IOCP isnrCOt rCLthreadrCaheavy,rCY itrCOs completionrCadriven. Threads are just the delivery mechanism, not the concurrency model. Create an IO worker thread pool and an IOCP port, and thatrCOs the start.

    On Windows, async I/O is basically native. You donrCOt poll for readiness,
    you donrCOt spin on EAGAIN, and you donrCOt build a giant state machine. The kernel completes the operation when the data is actually ready.

    If you want singlerCathreaded event loops, thatrCOs what Unix readiness APIs are for. IOCP solves a different problem.

    However, io_uring is pretty neat!


    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.

    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).

    And yesrCa never use select() for anything serious. ;^)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 10 00:31:38 2026
    From Newsgroup: comp.lang.c

    On 6/10/2026 12:14 AM, Chris M. Thomasson wrote:
    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?

    Afaict, at extreme scale (100k+ connections, microburst workloads)
    io_uring is the only Linux API that can keep up without heroic tuning...

    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...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 10 00:34:04 2026
    From Newsgroup: comp.lang.c

    On 6/10/2026 12:06 AM, fir wrote:
    Lawrence DrCOOliveiro pisze:
    On Tue, 9 Jun 2026 11:34:36 +0200, fir wrote:

    Lawrence DrCOOliveiro pisze:

    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 standard techniques are not necesarelly much good imo...ans
    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.

    this 100 ms was an example not more meaning than using "foo" name if 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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From fir@profesor.fir@gmail.com to comp.lang.c on Wed Jun 10 12:37:47 2026
    From Newsgroup: comp.lang.c

    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:

    Lawrence DrCOOliveiro pisze:

    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 standard techniques are not necesarelly much good imo...ans
    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.

    this 100 ms was an example not more meaning than using "foo" name if
    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
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Wed Jun 10 14:56:03 2026
    From Newsgroup: comp.lang.c

    Lawrence =?iso-8859-13?q?D=FFOliveiro?= <ldo@nz.invalid> writes:
    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).

    VMS applications for high performance async I/O used ASTs or Event Flags
    for synchronization. Using ASTs was preferred for high-throughput
    I/O.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 10 11:40:32 2026
    From Newsgroup: comp.lang.c

    On 6/10/2026 3:37 AM, fir wrote:
    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:

    Lawrence DrCOOliveiro pisze:

    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 standard techniques are not necesarelly much good imo...ans
    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.

    this 100 ms was an example not more meaning than using "foo" name if
    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

    Huh? What do you mean by waiting on only one thing? Take IOCP, you wait
    on the port for any io completion. So, its waiting for activity. Take a
    close look at the following because I think reading that might help you understand:

    https://learn.microsoft.com/en-us/windows/win32/fileio/getqueuedcompletionstatusex-func

    Read all of it.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 10 12:02:59 2026
    From Newsgroup: comp.lang.c

    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?


    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 ...

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Jun 11 00:01:41 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Jun 11 00:07:11 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Jun 11 00:15:18 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Jun 11 00:16:37 2026
    From Newsgroup: comp.lang.c

    On Wed, 10 Jun 2026 12:02:59 -0700, Chris M. Thomasson wrote:

    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?

    Ignorance should go away with enlightenment.

    If they persist in sticking to it, then it becomes wilful ignorance.

    Which is just ... dumb.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Thu Jun 11 13:27:22 2026
    From Newsgroup: comp.lang.c

    On 6/9/2026 11:47 PM, Lawrence DrCOOliveiro wrote:
    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?

    Send it right from memory. It handles everything. It completes with a
    status. It way more efficient than sending a file via WSASend'.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Fri Jun 12 01:35:30 2026
    From Newsgroup: comp.lang.c

    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).
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Thu Jun 11 21:08:25 2026
    From Newsgroup: comp.lang.c

    On 6/10/2026 5:15 PM, Lawrence DrCOOliveiro wrote:
    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.

    Yeah. Actually, its kind of more "akin" to say using dx12 vs modern
    opengl. You have to manage a lot of the work yourself.


    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.

    I think one can use WSADuplicateSocket, but that can be dangerous.
    Sharing a single IOCP between different processes, is well. Probably
    going to not work. Never did that anyway.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Sat Jun 13 00:10:35 2026
    From Newsgroup: comp.lang.c

    On Thu, 11 Jun 2026 21:08:25 -0700, Chris M. Thomasson wrote:

    Sharing a single IOCP between different processes, is well. Probably
    going to not work. Never did that anyway.

    Yeah, you see, a key part of the original Unix philosophy was to use
    multiple processes to achieve concurrency/asynchrony. Multithreading
    came later. And I think asynchronous I/O completion callbacks were
    considered too low-level a concept to be worthy of userspace.

    Since process creation was such a common operation, a lot of work went
    into making it as efficient as possible.

    Whereas Windows NT was created by a Unix-hater refugee from DEC. His
    previous OS, VMS, had a process-creation operation that was quite
    expensive, so you were discouraged from creating lots of processes as
    part of a single program. And he took that idea (among others) with
    him when he joined Microsoft.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Sat Jun 13 14:26:14 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Sat Jun 13 14:32:24 2026
    From Newsgroup: comp.lang.c

    On 6/13/2026 2:26 PM, Chris M. Thomasson wrote:
    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.
    Using UDP is way different than using TransmitPackets on a TCP
    connection. With UDP you'd embed file offsets directly in the packets.
    This solves duplicated packets... Just write them, or discard them. Lost packets can use the TCP connection to show the state, and resend
    relevant data...

    Actually AcceptEx and ConnectEx on Windows are pretty fun... :^)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Sun Jun 14 00:45:02 2026
    From Newsgroup: comp.lang.c

    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 ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Sun Jun 14 14:44:06 2026
    From Newsgroup: comp.lang.c

    Am 08.06.2026 um 17:49 schrieb fir:
    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

    The official name for fopen() for network is Boost.ASIO.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Sun Jun 14 13:55:58 2026
    From Newsgroup: comp.lang.c

    On 6/13/2026 5:45 PM, Lawrence DrCOOliveiro wrote:
    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:

    It applies to new versions. TransmitPackets is there. But, The client
    versions of windows nerfs it.


    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?

    Well, on a client, iirc only two TransmitPackets/File are allowed to be
    in concurrent pending flight at one time. So, shit! I always hated that.
    Its been many years since I used it. Also, I always used them with TCP.
    I had my UDP thing, and that was for something else.

    Iirc, TransmitFile was before TransmitPackets.


    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 ...

    Shit happens. What do you think of AcceptEx and ConnectEx? ;^)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Tue Jun 16 04:36:17 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 16 13:08:49 2026
    From Newsgroup: comp.lang.c

    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:

    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.

    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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 16 13:11:18 2026
    From Newsgroup: comp.lang.c

    On 6/16/2026 1:08 PM, Chris M. Thomasson wrote:
    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.


    ConnectEx can send some initial data as a convenience, but it's just
    bytes. if you need it encrypted, encrypt it before passing it in. That's
    true of any socket send API.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 17 03:11:47 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 17 12:13:19 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@cr88192@gmail.com to comp.lang.c on Wed Jun 17 18:41:57 2026
    From Newsgroup: comp.lang.c

    On 6/8/2026 11:16 AM, fir wrote:
    fir pisze:
    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

    maybe someone who has some experience with socked programming know how
    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?


    You would probably want it as a URI at least...

    Say:
    tcp://1.2.3.4:555
    tcp://[1492:0069::1]:1234
    ...


    I had considered something like this for my makeshift TestKern OS, but:
    Thus far no proper networking support;
    For an FPGA, would need to implement Ethernet, which is a big ask;
    For the emulator, would need to implement a full network stack on both
    ends to have fake Ethernet;
    ...

    Within the VFS, URI like notation is supported, and can behave in a
    similar way to mount points (could almost go as far as to mimic Windows
    drive letters, but I had gone with a a Unix style single-root filesystem
    for the main VFS, with directories as mount points).


    Given I had already tried and failed to implement working USB support on
    the FPGA, not particularly inclined to face off with Ethernet. A project
    from long ago had used PPP and a Modem, which I could emulate again, or
    use a virtual Null-Modem connection, but, ...

    In the project, IIRC there is an (internal only) network stack which
    mostly assumes IPv6 as the baseline, but then maps both IPv4 and Unix-domain-sockets through this (and would also support GUID/UUID
    through the same mechanism). Had briefly considered routing X11 over
    this, but then noted that this would be far higher hassle and overhead
    than routing Window/GUI stuff over COM.

    You can mostly use the same 128-bit space for nearly all of them, but
    with some level of mutual-exclusivity:
    SIXTEENCC and GUIDs are mutually exclusive at the encoding level;
    Heuristic means can be used to separate IPv6 addresses from the others;
    Though, for IPv6 is it weaker as there are fewer rules the IPv6
    addresses are required to follow, so one can prove that an IPv6 address
    is not a valid SIXTEENCC or a GUID, but can't prove that one of these is
    not a valid IPv6 address (unless by assuming that if it hits as one of
    these, it is probably not an IPv6).

    Though, can use different internal protocol numbers for address strength (while possibly fudging it for the internal routing).

    For Unix sockets, had used SIXTEENCC if the name was short (typical), or
    a hashed ID if longer...



    Well, and theoretically could support non-local GUI (if not implementing
    X11) by routing COM over either TCP or UDP (on a LAN setting, UDP would
    likely make more sense).

    Well, and/or eventually implement an X11 server as a wrapper.

    ...



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 17 23:47:42 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 17 20:26:00 2026
    From Newsgroup: comp.lang.c

    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:

    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?

    Well, ConnectEx can send the initial DH exchange bytes right on connect.
    But that is up to the user... Right?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Jun 18 07:30:06 2026
    From Newsgroup: comp.lang.c

    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 ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Jun 18 07:30:55 2026
    From Newsgroup: comp.lang.c

    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 ...

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@cr88192@gmail.com to comp.lang.c on Thu Jun 18 03:49:55 2026
    From Newsgroup: comp.lang.c

    On 6/18/2026 2:30 AM, Lawrence DrCOOliveiro wrote:
    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 ...


    Not that there is any plan to do so...

    Just that it is also not a huge leap from:
    tcp://whatever
    udp://whatever
    http://whatever
    ftp://whatever
    ...
    To:
    c:/whatever...


    But, as noted, I was already mostly going with a Unix-like directory
    tree and mount system.

    So:
    /usr
    /usr/bin
    /usr/etc
    /dev/...
    ...

    Though, in this case, "/boot" is the actual mounted boot device
    (typically a FAT32 drive);
    With '/' as a small ramdisk, and "/dev" as a special "devfs";
    And, '/usr' was typically a prebuilt read-only VFS image.


    Some parts of the design inspired by Unix and Linux, some by Windows,
    and other parts by things like the Doom and Quake engines and similar.

    And, then some oddities, like despite nominally FAT being
    case-insensitive, TestKern treats it as case-sensitive.




    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Thu Jun 18 04:36:43 2026
    From Newsgroup: comp.lang.c

    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:

    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. ;^)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Thu Jun 18 04:38:51 2026
    From Newsgroup: comp.lang.c

    On 6/18/2026 4:36 AM, Chris M. Thomasson wrote:
    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. ;^)

    Iirc, ConnectEx sends the ClientHello on connect AcceptEx receives it on
    the server side simultaneously wrt accepting the connection...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Jun 18 23:03:43 2026
    From Newsgroup: comp.lang.c

    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
    ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Jun 18 23:06:49 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@cr88192@gmail.com to comp.lang.c on Fri Jun 19 01:20:14 2026
    From Newsgroup: comp.lang.c

    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:
    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.


    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:
    c:/ aliases to /mnt/c


    Though, granted, not much particular reason to do this...




    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.

    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:
    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?...



    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...

    Though, TODO here would still be to come up with a general mechanism for applications to export COM-like interfaces (and tag the interface, and
    have at some way to verify whether both sides agree as to the interface layout). Though, there is the trick that was used for versioning in BITMAPINFOHEADER and WAVEFORMATEX:
    Pass the sizeof the object and vtable, and use this as an informal
    version key (crap strategy, but kinda works...).


    In most other contexts, you know in advance which type of interface is expected.

    But, for some cases, could make sense to have some way for an
    application to just be like "Hey, I want to export an instance of this particular interface...".

    Say, something sorta like:
    HANDLE tkObjExportInterface(
    GUID uidClz, GUID uidIface,
    IObjectPVoid pVt,
    SIZE szVt, SIZE szDat);


    Well, which could likely spawn a new service-handler thread for this and return the handle (well, at least in TestKern, every sort of listener
    object essentially needs a thread whose sole purpose is to dispatch
    method calls that come in for that object; in effect the thread goes to
    sleep in a special state where it wakes every time a new method-call
    comes in, and goes back to sleep as soon as it returns to the caller).

    Where, say, uidClz gives a GUID or similar identifying the object
    interface type, and uidIface giving an "assumed unique" ID for the
    specific interface being exported.

    Could use strings, with a special hashing algorithm to map strings to GUID-like form (otherwise, they are either magic numbers; or "assumed
    unique" values generated with a random number generator, and some
    special tag-pattern bits). Note that (like ASLR), the GUID generation
    needs access to a moderately strong random number generator.


    May seem like a waste to burn a thread on each object listener, but no
    real better option at present.

    Though, another option could be something like, say:
    clz_someobj *obj;
    HANDLE hPub;

    obj=tkObjCreatePublicInstance(
    clz_uid_clz, &clz_someobj_iface,
    sizeof(clz_someobj_iface), sizeof(clz_someobj));
    hPub=tkObjExportInstance(obj, uid_interface);

    But, implicitly this is what "tkObjExportInterface()" could likely do internally.


    Though, generally, this sort of thing is more done for kernel-space
    stuff, not so much for userland. Userland is more often in the role as a consumer of interfaces.


    Then again, I guess one could argue:
    Maybe if userland exports an object, and the handler dies somehow, all
    the method calls simply become no ops?... (well, either this or
    terminate the caller, or do the equivalent of a kernel panic).

    Well, may need to sort this stuff out eventually.


    Note that generally the interface exported on one side is not the same
    as what the client sees. Generally the client merely sees a dummy object
    with a dummy vtable (method calls then perform system calls that route
    control to the target object).



    Well, can note that this is one area where my efforts differ somewhat
    from Linux (which mostly doesn't go here; or would more likely just use
    a sockets).

    ...

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Fri Jun 19 08:56:32 2026
    From Newsgroup: comp.lang.c

    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. 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? 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. 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 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:". They were still usable
    when you had a hard drive with one partition. 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 cd ftp://foo.org/pub/
    -a ls
    Even really make sense?...


    That could be nice, at least for things that support a file and
    directory model. 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) ? 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...

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Fri Jun 19 06:59:33 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Fri Jun 19 02:21:03 2026
    From Newsgroup: comp.lang.c

    BGB <cr88192@gmail.com> writes:
    [...]
    Then again, going into the weeds on this:
    Would, say:
    cd ftp://foo.org/pub/
    ls
    Even really make sense?...

    It wouldn't work that way, because "ftp:" is a valid name for a
    directory on a Unix-like system, and "//" is equivalent to "/".

    $ cd ftp://foo.org/pub/
    $ ls
    this-is-not-an-ftp-server
    $

    Trying to be at least vaguely topical, on systems with a more
    restrictive file name syntax it might be possible for fopen() to
    distinguish by name between a local file and a URL, but not on a
    Unix-like system without more information.

    Or, would it be better to ask people to at least mount it into the VFS
    or similar?...

    It's certainly possible to mount an ftp server as a filesystem on
    most Unix-like systems, probably with some add-on software
    (like curlftpfs, which I haven't tried).

    [...]
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 10:42:32 2026
    From Newsgroup: comp.lang.c

    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?


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Fri Jun 19 10:18:13 2026
    From Newsgroup: comp.lang.c

    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.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Fri Jun 19 13:46:58 2026
    From Newsgroup: comp.lang.c

    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.-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?

    To be honest, I have never come across the need. In my university days
    (with SunOS, then Solaris) the machines did not have floppies - most did
    not even have hard disks. 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. 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. Different *nix systems have different habits, and in Linux it
    can vary by distro or desktop. 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. More realistically, people would use USB
    memory sticks now. 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. 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). It would likely be better to have a gui or menu
    choice for some programs. 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.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 15:29:07 2026
    From Newsgroup: comp.lang.c

    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.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 15:49:48 2026
    From Newsgroup: comp.lang.c

    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:

    /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.





    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Fri Jun 19 17:25:01 2026
    From Newsgroup: comp.lang.c

    On 19/06/2026 16:49, Bart 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:
    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.


    That would be useful if you use a lot of different drives and plug them
    in and out a lot. But Windows can't handle anything like that.

    On Linux, setting up something like would be straightforward. In my
    work, I use a lot of USB serial cables, and have such a system set up so
    that when I (for example) plug one into port 3 on the hub I have on my electronics desk, it turns up as /dev/ttySerial_hub3. Doing something
    similar with usb drives would just be a few lines in a udev rules file.
    (It will look a bit like a magic incantation at first, but Google will
    lead you through it.) Sometimes I give specific names to specific
    cables independent of the physical address on the USB port tree -
    whatever is most useful for the situation.

    Compared to Windows machines with its pseudorandom system for assigning
    COM port numbers, it is a joy - especially on test machines when you
    find an old device suddenly gets COM port number 129 and the test
    software only shows a list up to COM port 128. (That is not a made-up
    story.)


    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.


    The names are not random - they are the filesystem labels. So if you
    have a USB stick and you have given the filesystem (vfat, ntfs, ext4,
    whatever you like) the label "Bart's files", then it will turn up with
    that directory name. If you haven't done anything to a new
    off-the-shelf drive, it will use the filesystem label provided by the manufacturer, or probably something like a serial number or block device
    UUID if the label is missing. Crucially, it will be consistent for the
    same drive (unless you rename it manually).


    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.


    "bart" is your username. When a user is logged on to a relatively full-featured desktop, as commonly used on Linux workstations, it is
    assumed that it is the current logged-on desktop user that has plugged
    in the device, and it is mounted in a directory private to them. Other options are easily possible if that does not fit your needs.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Fri Jun 19 16:18:14 2026
    From Newsgroup: comp.lang.c

    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:
    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:

    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.

    That said....

    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.

    I mentioned that Plan 9 wrapped all of this up into a shell
    script that they called (I think somewhat ironically, `a:`). So
    what you would say is, "type 'a:'...now type 'cd /n/a'". Not
    that much different.

    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.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Fri Jun 19 16:31:42 2026
    From Newsgroup: comp.lang.c

    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]
    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.

    Why letters and not descriptive volume names? If I insert a USB
    flash device into my Macintosh, it gets mounted under
    `/Volumes/<some name>` where the name is a property of the image
    on the drive; usually it's descriptive. It also shows up in the
    Finder as a separate thing that I can double-click on to expand
    the view of in a window.

    That seems infinitely better to me than what Windows does.

    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.

    This conflates so many things that I don't even know where to
    rightfully begin. In particular, you are referring to the
    actual directory pathnames that Linux uses as mount points for
    the filesystems on devices. But I see no reason why I couldn't
    have a userspace image that creates symbolic links to those
    named 'a', 'b', 'c', etc.

    I assume that 'bart' is specific to my machine,

    I assume it's specific to you as a user.

    so I can't assume anything if, say, I wanted to hardcode a path
    into a program or script that someone else runs.

    In general, that's a bad idea and poor practice anyway. But if
    you wanted to, you could assume a pathname that's a symbolic lnk.

    Sounds like you can't assume that on Windows, either.

    You could do something like

    dir=${dir:-/media/$LOGNAME/expected_volume_name/...}

    ...and then refer to things using names relative to $dir.
    People have been doing things like that for half a century now.
    It's relaly not that hard.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 17:50:20 2026
    From Newsgroup: comp.lang.c

    On 19/06/2026 17:31, Dan Cross wrote:
    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]
    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.

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 18:07:57 2026
    From Newsgroup: comp.lang.c

    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."
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Fri Jun 19 10:33:11 2026
    From Newsgroup: comp.lang.c

    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.

    fopen() takes a pointer to a string as its first argument.
    The requirements for that string are system-specific.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 19:04:26 2026
    From Newsgroup: comp.lang.c

    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.

    Why?

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Fri Jun 19 18:50:10 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    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.

    At least one of them used to be one of the architects of
    SVR4.2 ES/MP. (Enhanced Security, Multiprocessor). I think
    he may still be there.


    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.

    It's Bart, the master of the non sequitor.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Fri Jun 19 18:51:32 2026
    From Newsgroup: comp.lang.c

    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?

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Fri Jun 19 18:54:21 2026
    From Newsgroup: comp.lang.c

    Bart <bc@freeuk.com> writes:
    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.

    If I have two USB floppy drives plugged into a windows box,
    which one is A and which one is B? There are no labels on the
    drives.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Fri Jun 19 18:55:21 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@cr88192@gmail.com to comp.lang.c on Fri Jun 19 14:47:31 2026
    From Newsgroup: comp.lang.c

    On 6/19/2026 1:59 AM, Lawrence DrCOOliveiro wrote:
    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.

    MS-DOS copied CP/M.
    Win 3.x and 9x built on top of DOS.
    WinNT copied the same general structure of the DOS-based Windows.
    ...

    As for TestKern, it is in a weird space of being sorta Unix-like but
    also sorta more resembling Cygwin in some ways.


    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.


    I guess one can distinguish here what belongs in the VFS and shell, vs
    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.

    When not running the GUI, it is just a shell.


    May seem like a waste to burn a thread on each object listener, but
    no real better option at present.

    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.


    In this case, the method calls are not actually themselves "messages"
    that are passed along, but more that the thread goes into a special
    state where it effectively expects the OS scheduler to wake it at the
    exact moment a method call arrives, with this method call effectively
    taking over the whole thread (which then serves no purpose other than
    handling incoming message calls).


    When the method returns, it is a trip right back into the OS scheduler,
    which typically restores the task that initiated the method call.

    Or, in effect, less like traditional message/event handling, and more
    like direct method calls bounced over the OS's SYSCALL/SCHED mechanism.

    Actually, the normal system calls in this case work in a similar way,
    where one can view bare system calls as essentially method calls to a
    special NULL object.


    Say, from RV or similar:
    X10: Object Handle
    X11: Method Number (depends on Object)
    X12: Argument List Pointer
    X13: Return Value Pointer
    X14/X15/X16: MBZ here
    X17: -1 (0+ would map to Linux style SYSCALLs)
    Then one uses a special instruction, 'ECALL' which invokes the mechanism.

    This invokes a handler in a lower operating mode (lets call it "Machine Mode"). For most calls, this handler can't deal with it directly, but
    what it can do is pass the call where it needs to go.

    If handle is NULL (0), it pulls up the normal SYSCALL handler task, and initiates a context switch.

    As soon as the Syscall Thread wakes, it grabs the arguments (which the
    SYSCALL handler shoved into the appropriate registers) and "lets it rip".


    For other objects, the SYSCALL handler can instead choose the task
    associated with the object handle in question (which basically can work
    like an index into an array of tasks and objects). It then does the register-shoving magic, and performs the context switch (mostly some
    arcane magic where it reloads all the registers from the new context,
    rather than the ones saved off when initiating the SYSCALL).


    For an object method handler (assuming RV here), it would do something
    like (on waking):
    Use method number from X11 to fetch method pointer from VTable for
    current object;
    Save off X13 for later;
    Copy arguments from Argument list into the argument registers
    (X10..X17), with some more into the current stack;
    Call the method;
    Restore saved X13;
    Copy X10/X11 from called method;
    Load -2 into X17;
    ECALL (Returns to caller)

    At this point, object handler should be back in the same state it was
    before the call, and if woken again, will go through the same ritual.

    Granted, the mechanism could potentially be tweaked to allow multiple
    object instances to be handled by the same thread (rather than needing
    to spend a thread per handler object).

    In this case, multiple objects could export from the same root handler
    thread.


    Note that in this OS, memory is subdivided into Local and Global:
    Local memory is only accessible within the current process;
    Global memory may be accessed by other processes;
    ...

    Any structures or memory passed over this call interface effectively
    needs to be Global, or else stuff is liable to explode.

    The memory map is maybe a little wonky, but sorta like (48 bit):
    0000_xxxxxxxx .. 3FFF_xxxxxxxx: System / Global
    4000_xxxxxxxx .. 7FFF_xxxxxxxx: Local
    8000_xxxxxxxx .. FFFF_xxxxxxxx: System / Hardware (Special)

    ...


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Fri Jun 19 19:55:10 2026
    From Newsgroup: comp.lang.c

    In article <1113t1c$3f4nm$2@dont-email.me>, Bart <bc@freeuk.com> wrote:
    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.

    It doesn't seem difficult to me, but I recognize that that is
    subjective.

    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'.

    You do realize that that is subjective, right? Hopefully we
    don't devolve into another discussion about the meaning of that
    word (or how it's different from objective), but calling it
    "simpler" is your opinion.

    ...and do you know how much engineering goes into that "out of
    the box" statement?

    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.

    It's funny that I showed you a shell script that was actually
    called `a:`.

    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.

    Its ok; not everybody is cut out for using it.

    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."

    I don't think I've ever seen an instance where Google's AI is
    right the first time.

    DEC OSes were noted for using unique identifiers for each
    storage device. For instance, on VMS one might refer to a file
    on a specific disk as `DKA1:[SOME.DIRECTORY]FILE.EXT;3`, meaning
    version 3 of a file named "FILE.EXT" in "some directory"
    relative to the start of the filesystem on device DKA1.

    It is known that Gary Kildall used a DEC PDP-10 running TOPS-10
    (a DECsystem-10 machine) to do the initial development of CP/M;
    the semblance in some places is unmistakable (e.g., the `PIP`
    command, `DIR`, etc). File specifications on TOPS-10 include a
    device or structure name; see sec 1.4.2.4 of this reference: https://bitsavers.org/pdf/dec/pdp10/TOPS10/1972_PDP-10_Users_Handbook/08_commands.pdf
    `DSKA:PROG2.FOR` is a valid TOPS-10 file spec, for example,

    Of course, none of this has anything to do with C.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Fri Jun 19 19:58:35 2026
    From Newsgroup: comp.lang.c

    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`.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 21:04:10 2026
    From Newsgroup: comp.lang.c

    On 19/06/2026 19:51, Scott Lurndal wrote:
    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?

    Actually, no it wasn't. Why don't you read the fucking thread rather
    than make false accusations?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 21:07:35 2026
    From Newsgroup: comp.lang.c

    On 19/06/2026 19:55, Scott Lurndal wrote:
    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?

    After nearly 100 posts made by other people? Bastard.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 19 21:15:38 2026
    From Newsgroup: comp.lang.c

    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. 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`.

    Yet it hasn't stopped you having your say about a topic before declaring
    it as off-topic.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Fri Jun 19 13:42:56 2026
    From Newsgroup: comp.lang.c

    On 6/18/2026 4:03 PM, Lawrence DrCOOliveiro wrote:
    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
    ...

    Humm... I think you are missing the point? ConnectEx/AcceptEx has the
    option to send/recv data. That's it. And yes, shaving off a system call
    can add up over time... 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...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Fri Jun 19 22:09:41 2026
    From Newsgroup: comp.lang.c

    In article <111481a$3ioc8$3@dont-email.me>, Bart <bc@freeuk.com> wrote:
    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.

    Those would probably be numbered, not identified by letters. I
    have never seen someone label USB ports like that.

    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 thought it was about naming conventions and shell scripts.
    Before that, it was about `fopen`.

    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`.

    Yet it hasn't stopped you having your say about a topic before declaring
    it as off-topic.

    Hey, it's not my fault if Unix is too hard for you to understand
    or use. *shrug*

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Fri Jun 19 22:40:12 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Fri Jun 19 22:47:17 2026
    From Newsgroup: comp.lang.c

    On Fri, 19 Jun 2026 14:47:31 -0500, BGB wrote:

    On 6/19/2026 1:59 AM, Lawrence DrCOOliveiro wrote:

    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.

    I guess one can distinguish here what belongs in the VFS and shell, vs
    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>.

    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.

    Actually, lots of them do. Just one example I came across recently: <https://telehack.com/>.

    Also this <https://xen-orchestra.com/> Web-based GUI front-end to
    XCP-ng <https://xcp-ng.org/> lets you open console windows to your
    VMs, directly in the browser.

    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.

    The two are not mutually exclusive <https://docs.python.org/3/library/asyncio-eventloop.html>.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Fri Jun 19 22:49:17 2026
    From Newsgroup: comp.lang.c

    On Fri, 19 Jun 2026 10:42:32 +0100, Bart wrote:

    How would you distinguish between two floppy drives on a Unix-like
    file system?

    Remember that Unix-like systems donrCOt access volumes via device names,
    but by mount points.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@cr88192@gmail.com to comp.lang.c on Fri Jun 19 18:06:27 2026
    From Newsgroup: comp.lang.c

    On 6/19/2026 1:56 AM, 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.


    I meant where you could pick the drive letter and the OS would remember.

    But, yeah, the DOS-based Windows variants (3.x/95/98/Me), would just
    sort of enumerate drives and pick letters sequentially.

    A/B: First/Second floppy drive;
    C: First HDD
    ...

    Typically, HDDs would be assigned letters first, followed by CD-ROMs,
    which could make a problem for any CD-ROM based software that was
    hard-coded to assume that the CD-ROM drive was in "D:", ...

    Generally the NT based Windows (now all of then) instead using
    statically assigned drive letters, though the letters are remembered by
    the OS vs drive, so plugging the same physical drive into different
    systems, or booting a different version of the OS (or reinstalling the
    OS) may move the drive letters around.



    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.


    Likely only real reason to do this would be either for software or user familiarity. Like, say, users are more used to seeing "C:\" vs, say,
    "/usr", "/home/username".

    Well, then again, many might just expect to see "My Documents" and not know/care where it is stored in the filesystem, eg:
    "C:\Users\username\My Documents"
    And, might not notice or care much if suddenly it became, say:
    /home/username/Documents




    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.


    Maybe.

    It sort of exists in the VFS layer, but more for functional things.

    Doesn't currently work in the shell which assumes a single-rooted
    Unix-style tree at present.

    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.


    Yeah, this would likely work against the ability to 'cd' into an FTP server.

    It would likely still make more sense as a mount point or something.





    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.


    Yeah, although IIRC 'fuse' works over sockets or similar.


    Things like sockets or message passing have higher overhead and latency,
    but also have more well-defined behavior (and less risk) than
    inter-process method calls.

    Then again, if I could set up a task that would wait for something to
    come over a socket and then dispatch the request, sending the response
    over a socket, this would be more decoupled...

    But, then again, for kernel level stuff, one either expects the request
    can be completed or it can't. This breaks with the message passing (we
    can't know success/failure/etc until after a response gets back).

    But, if one makes an object call to a usermode Object handler from
    within the kernel's syscall handler, a new problem arises: The
    System-Call handler is effectively "out of commission" until it's
    response gets back. So, it could end up in a state where you are in
    usermode but unable to make any system calls, which is, not ideal...


    Seems like some more thought would be needed for the engineering on this one...


    May likely need a more asynchronous mechanism, with some way for the VFS
    to be like "we don't know yet...", and then somehow put the caller on
    hold until a response gets back from the userland FS driver (though
    likely initiating a context switch to the FS driver so that it can
    handle the request, but not in a way that would block the FS's driver's ability to make system calls).

    Well, maybe the system-call handler could have a mechanism to signal to
    the SYSCALL interrupt, "I have more work to do, fire off a virtual
    syscall as soon as control gets back there...".





    Vs, say, assuming programs that export interfaces (as services) to be
    at least semi trsusted / stable...


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Fri Jun 19 16:40:07 2026
    From Newsgroup: comp.lang.c

    On 6/19/2026 3:40 PM, Lawrence DrCOOliveiro wrote:
    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.

    I am talking about highly scalable servers under heavy load.

    What is the analog of ConnectEx/AcceptEx on Linux?

    io_uring_enter? IORING_OP_ACCEPT and IORING_OP_CONNECT ?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Fri Jun 19 16:47:35 2026
    From Newsgroup: comp.lang.c

    On 6/10/2026 5:07 PM, Lawrence DrCOOliveiro wrote:
    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.

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Sat Jun 20 01:52:17 2026
    From Newsgroup: comp.lang.c

    This post is, as seen in the subject, off-topic and rather longish.
    Persons that have problems with such posts better leave here. :-)

    On 2026-06-19 21:55, Dan Cross wrote:
    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.

    Sorry, but that "the first time" triggered a recent experience and
    that statement should be refined; it fails even after issuing many
    "doubting statements". I admit that I deliberately stressed the AI
    after my first (seriously asked) question. - See it as "behavioral
    analysis". ;-)

    That recent request was _simple_; I'd asked for the north-south
    orientation of a specific football stadium. The dialog was like
    that (here much abbreviated, not literally, to see the pattern):

    Q: north-south orientation of that stadium
    A: that stadium is exactly N-S-oriented

    (The AI claims even "exactly"; on maps you see that's wrong.)

    Q: it's not exactly N-S-oriented
    A: the orientation deviates by almost 14 deg to N-NE

    (Now there's numbers and some [wrong] orientation.)

    Q: the orientation does not deviate by almost 14 deg to N-NE
    A: right, I [the AI] was again unprecise,
    the orientation is N-NW about 11-14 deg

    (N-NE became now N-NW, and that [wrong] number a [wrong] range.)
    (The AI formulates former answers as being just "unprecise".)

    At this point I used a map and Gimp and determined the orientation
    myself as N-NW and 15.25 deg. - Okay, so give it a final kick...

    Q: the orientation is not N-NW about 11-14 deg
    A: (prompt to be heavily "thinking", and after many seconds ...)
    I'll abstain from assumptions here and focus on provable facts
    instead of constantly admitting you every orientation change

    ("Facts", even "provable"! And sort of a "pissed" comment; the AI
    "doesn't like" its answers being doubted. :-)
    (Its last line was indeed such a semantically strange formulation.)

    In fact the last answer was a lot bulkier since it lists all sorts
    of "facts" that have never been asked for. But that simple correct
    fact I had asked for I've *never* got.

    Note: I deliberately just negated the AI's wrong answers instead of
    asking differently; the original question had been clearly defined,
    and I didn't want to manipulate the AI's "response path" to trigger
    yet more and other hallucinated "facts".

    It's not only that it regularly produces wrong answers, and that it
    presents them as facts, it also doesn't converge to a right answer
    to a simple question on a mundane fact. It prefers hallucinating.

    And Bart (and a few others) seriously tells us:
    Google AI tells me: "[...]"
    What that really tells us is obviously something about AI-believers.

    Janis

    [...]

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Sat Jun 20 02:49:18 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Sat Jun 20 02:50:05 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Fri Jun 19 19:52:09 2026
    From Newsgroup: comp.lang.c

    On 6/19/2026 7:49 PM, Lawrence DrCOOliveiro wrote:
    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.

    IOCP is usable and highly efficient. But, if you don't know what you are doing, well... Pretty bad.


    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Fri Jun 19 19:53:15 2026
    From Newsgroup: comp.lang.c

    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 ?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Sat Jun 20 03:00:05 2026
    From Newsgroup: comp.lang.c

    On Fri, 19 Jun 2026 15:49:48 +0100, Bart wrote:

    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.

    By default itrCOs using the device serial number to create a unique
    name.

    If I try another, then it's at /media/bart/NEW (note these are case-sensitive) ...

    It is possible to set up things to be case-insensitive, if you want.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Sat Jun 20 03:03:39 2026
    From Newsgroup: comp.lang.c

    On Fri, 19 Jun 2026 18:07:57 +0100, Bart wrote:

    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."

    DEC OSes had multi-character device names. Gary Kildall copied the
    idea (one of many) into CP/M, but simplified them down to single
    letters, just for the disk drives. Because who would want more than 26
    drives on a single 8-bit machine, right? And then somebody invented rCLreservedrCY file names for non-disk devices (e.g. serial ports).

    For some reason, Microsoft still thinks rCL26 drive letters ought to be
    enough for anybodyrCY ...

    And those rCLreservedrCY file names also continue to plague Windows today
    ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Sat Jun 20 03:57:48 2026
    From Newsgroup: comp.lang.c

    On Fri, 19 Jun 2026 19:52:09 -0700, Chris M. Thomasson wrote:

    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.

    Name one common Linux server app that feels the need to use io_uring.

    Hint: I just searched through the sources for both Apache and Nginx,
    and found no mention of it.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Sat Jun 20 03:59:01 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Sat Jun 20 13:53:36 2026
    From Newsgroup: comp.lang.c

    On 19/06/2026 20:55, Scott Lurndal wrote:
    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?

    At the risk of speculating on Keith's motives, I think it is far
    simpler. Bart asked how he would do something that was not C related,
    and Keith suggested he asked in a newsgroup where the question was
    topical. That strikes me as perfectly reasonable, but it triggered
    Bart's paranoia.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Sat Jun 20 14:02:14 2026
    From Newsgroup: comp.lang.c

    On 20/06/2026 00:47, Lawrence DrCOOliveiro wrote:
    On Fri, 19 Jun 2026 14:47:31 -0500, BGB wrote:

    On 6/19/2026 1:59 AM, Lawrence DrCOOliveiro wrote:

    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.

    I guess one can distinguish here what belongs in the VFS and shell, vs
    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.


    Exactly. Using FUSE gives a bit more overhead and latency compared to a kernel filesystem, but is much more convenient to develop (being
    userspace), easier to make secure (being userspace), can be written in
    any language you like (being userspace), does not need to be updated for different kernels (being userspace), can be packaged and distributed independently from the kernel (being userspace) and does not introduce security or reliability risks for people who don't use it (being
    userspace). It is the right choice for every filesystem that does not
    need maximal efficiency or to work as the root filesystem.

    You can even use WinFUSE to make your FUSE filesystem work on Windows.

    Example: secure remote access to filesystems on other machines via SSH <https://github.com/libfuse/sshfs>.

    sshfs is a thing of beauty, and I use it continuously.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Sat Jun 20 15:49:48 2026
    From Newsgroup: comp.lang.c

    "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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Sun Jun 21 01:42:40 2026
    From Newsgroup: comp.lang.c

    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.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From James Kuyper@jameskuyper@alumni.caltech.edu to comp.lang.c on Sat Jun 20 19:25:16 2026
    From Newsgroup: comp.lang.c

    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.

    You say that as if being advised to discuss this question in a place
    where you're more likely to get good answers is some kind of punishment.
    Is getting a good answer to your question so undesirable? If you prefer
    bad answers, there's even better newsgroups I could suggest than this
    one to achieve that result.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Sun Jun 21 12:18:39 2026
    From Newsgroup: comp.lang.c

    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.)

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Sun Jun 21 23:15:54 2026
    From Newsgroup: comp.lang.c

    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.








    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Sun Jun 21 16:30:27 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Sun Jun 21 16:31:03 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Mon Jun 22 00:59:55 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.lang.c on Mon Jun 22 04:33:09 2026
    From Newsgroup: comp.lang.c

    Michael S <already5chosen@yahoo.com> wrote:
    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.

    IME at high speed different converters behave differently
    and that can make difference between say dropping connection
    and working OK. Also, theoretically supported speeds and
    working ones may differ (higher speed may work while theoretically
    supported lower speed may fail to work).

    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.

    1.1 device plugged in via 2.0 hub uses 8KHz polling rate (at least
    Linux drivers seem to use this rate). There is measurable difference
    in available throughput between converter connected directly to
    USB port and converter connected as only device in 2.0 hub.

    Theoretically driver could poll 1.1 device more frequently than 1KHz,
    but apparently it is not doing this without appropriate hardware
    support (like intermediate 2.0 hub).

    AFAICS 912 Kbps claim is about speed on serial wire, what you get
    trough USB may be lower. But even if you can not get full
    throughput higher speed on serial wire may be useful.

    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.

    I did this only few times (normally I use ST-Link) and on Linux side
    I used non-ST tool, but each time it worked fine. But in general
    I agree, I saw problems in some cases and people tell me that
    there are problems in some other cases that I did not try.
    --
    Waldek Hebisch
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Mon Jun 22 10:01:40 2026
    From Newsgroup: comp.lang.c

    On 21/06/2026 22:15, Michael S wrote:
    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 ?!

    I can agree with you there. I have only once, that I can remember,
    actually used the serial API directly from C on Linux and "kludgy" is an appropriate description. Some kinds of programs are best written in C,
    other kinds are best written in other languages - serial port access
    from Python is simple, clear, and identical (except for the device
    names) for Windows and Linux, and that is what I use.

    Windows API makes more sense.

    It's a long time since I have used the Windows API for serial port
    access, and that was probably from Pascal (Borland Pascal, then Delphi).
    I seem to remember accessing the port from the "OpenFile" call that
    could be used to open handles to all sorts of things, except files. But
    there was no need for anything involving terminals.

    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.


    I've done plenty of that, and use several - but I do it in Python on
    Linux. (It's C or C++ on the microcontroller side.)

    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.


    Maybe I've just been lucky :-)

    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.


    The thing that is sometimes an issue, IME, is timing. Some protocols
    have particular timing requirements such maximum or minimum number of
    idle characters within or between packets. If the USB is not flowing smoothly, an unexpected break within a packet can cause trouble. This
    was especially true with early USB (1 ms cycle time), and earlier (or
    cheaper) converters with small buffers. It is also an issue with RS-485
    if the drive enable is controlled "manually" from PC software side,
    rather than a dedicated drive enable output from the converter chip.

    And occasionally you meet and awkward protocol that uses 9-bit data, or
    break frames, which are not necessarily supported by converters.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Mon Jun 22 14:56:10 2026
    From Newsgroup: comp.lang.c

    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.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Mon Jun 22 14:56:59 2026
    From Newsgroup: comp.lang.c

    "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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Mon Jun 22 12:23:38 2026
    From Newsgroup: comp.lang.c

    On 6/22/2026 7:56 AM, Scott Lurndal wrote:
    "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.

    io_uring starts to get fairly fine grain; having to make your own mmap'd buffers, ect. Actually, AIO is also akin to IOCP over in the Windows. So
    is io_uring. They have the same style. Completion based over polling.

    Well, wrt io_uring... It sure seems like say IOCP and AIO is akin to a
    modern opengl, vs something like Vulkan or Directx12. Its harder to
    program for, but can reap some interesting benefits.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Mon Jun 22 13:42:20 2026
    From Newsgroup: comp.lang.c

    On 6/10/2026 5:01 PM, Lawrence DrCOOliveiro wrote:
    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.

    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

    :^)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Mon Jun 22 14:06:58 2026
    From Newsgroup: comp.lang.c

    On 6/21/2026 5:59 PM, Lawrence DrCOOliveiro wrote:
    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.

    So, why did they even create io_uring?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Mon Jun 22 22:38:32 2026
    From Newsgroup: comp.lang.c

    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
    ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Mon Jun 22 22:40:31 2026
    From Newsgroup: comp.lang.c

    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 ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Tue Jun 23 07:25:56 2026
    From Newsgroup: comp.lang.c

    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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Tue Jun 23 15:35:52 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Tue Jun 23 18:07:06 2026
    From Newsgroup: comp.lang.c

    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:




    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.


    OK - my mistake.

    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. 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), 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.

    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.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Tue Jun 23 17:12:40 2026
    From Newsgroup: comp.lang.c

    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.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Tue Jun 23 17:39:05 2026
    From Newsgroup: comp.lang.c

    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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Tue Jun 23 21:07:48 2026
    From Newsgroup: comp.lang.c

    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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Tue Jun 23 21:11:16 2026
    From Newsgroup: comp.lang.c

    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!)


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Tue Jun 23 22:30:35 2026
    From Newsgroup: comp.lang.c

    On Tue, 23 Jun 2026 15:35:52 GMT
    scott@slp53.sl.home (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:




    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.


    I personally implemented new serial port hardware and Linux driver for
    it approximately 8 years ago.
    Not your average user stuff, sure. I don't remeber all details now, but
    I think it was up to 4 or 5 Mbit/s per port with plenty of ports. About
    10, IIRC.

    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.


    You demonstrate lack of imagination.

    Sure, the modem signals are obsolete and not often used.


    With that I agree.

    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.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Tue Jun 23 22:48:36 2026
    From Newsgroup: comp.lang.c

    On Tue, 23 Jun 2026 07:25:56 +0200
    David Brown <david.brown@hesbynett.no> wrote:

    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,

    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.





    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Tue Jun 23 23:00:02 2026
    From Newsgroup: comp.lang.c

    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.





    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 23 14:40:18 2026
    From Newsgroup: comp.lang.c

    On 6/22/2026 3:38 PM, Lawrence DrCOOliveiro wrote:
    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?

    ;^D God damn right!

    Well, shit happens. We need a damn SOCKET to gain the right pointers to
    these extensions. For a server its easy, just use the listening socket.
    Or, well, this is strange... We can create a dummy socket. Basically...
    Shit man. I was bored a couple of nights ago and made a little sketch
    from my memory of 20+ years ago. 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.


    struct wsa_extensions
    {
    LPFN_ACCEPTEX m_acceptex = nullptr;
    LPFN_CONNECTEX m_connectex = nullptr;
    LPFN_DISCONNECTEX m_disconnectex = nullptr;
    LPFN_GETACCEPTEXSOCKADDRS m_getacceptexsockaddrs = nullptr;

    bool
    load(
    SOCKET socket
    ) {
    if (!load_fn(socket, WSAID_ACCEPTEX, &m_acceptex))
    return false;
    if (!load_fn(socket, WSAID_CONNECTEX, &m_connectex))
    return false;
    if (!load_fn(socket, WSAID_DISCONNECTEX, &m_disconnectex))
    return false;
    if (!load_fn(socket, WSAID_GETACCEPTEXSOCKADDRS,
    &m_getacceptexsockaddrs)) return false;

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "wsa_extensions::load()\n"
    " m_acceptex = " << m_acceptex << "\n"
    " m_connectex = " << m_connectex << "\n"
    " m_disconnectex = " << m_disconnectex << "\n"
    " m_getacceptexsockaddrs = " << m_getacceptexsockaddrs <<
    "\n";

    return true;
    }

    private:

    template<typename T>
    bool
    load_fn(
    SOCKET socket,
    GUID guid,
    T* fn_out
    ) {
    DWORD bytes = 0;

    int status = WSAIoctl(
    socket,
    SIO_GET_EXTENSION_FUNCTION_POINTER,
    &guid, sizeof(guid),
    fn_out, sizeof(*fn_out),
    &bytes,
    nullptr,
    nullptr
    );

    if (status == SOCKET_ERROR)
    {
    std::cout << "WSAIoctl() failed: " << WSAGetLastError() <<
    "\n";
    return false;
    }

    return true;
    }
    };


    struct winsock
    {
    WSADATA m_wsa_data = { };
    wsa_extensions m_wsaex = { };

    // extend for version...
    winsock()
    {
    int status = WSAStartup(MAKEWORD(2, 2), &m_wsa_data);

    if (status) {
    std::cout << "WSAStartup() failed...\n";
    throw std::runtime_error("WSAStartup failed");
    }

    std::cout << "WSAStartup()\n";
    }

    ~winsock()
    {
    if (WSACleanup() == SOCKET_ERROR)
    {
    std::cout << "WSACleanup() failed...\n";
    return;
    }

    std::cout << "WSACleanup()\n";
    }
    };



    This <https://manpages.debian.org/setsockopt(2)> is so much simpler
    ...


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 23 14:41:28 2026
    From Newsgroup: comp.lang.c

    On 6/22/2026 3:40 PM, Lawrence DrCOOliveiro wrote:
    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 ...

    I think its a rather low level way to make high end servers/clients akin
    to dx12/vulkan vs modern opengl?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Tue Jun 23 14:44:44 2026
    From Newsgroup: comp.lang.c

    On 6/23/2026 10:39 AM, 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:

    - 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.

    For some reason that reminds me of EIEIO on the PPC.



    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.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 24 02:04:01 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 24 02:05:15 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Wed Jun 24 08:32:08 2026
    From Newsgroup: comp.lang.c

    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.






    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Wed Jun 24 10:47:39 2026
    From Newsgroup: comp.lang.c

    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 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.

    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.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Wed Jun 24 10:48:34 2026
    From Newsgroup: comp.lang.c

    In article <20260623230002.000063d8@yahoo.com>,
    Michael S <already5chosen@yahoo.com> 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.

    Other than that I agree. It seems that Dan Cross has no [1st-hand >programming] experience with MCUs.

    a) specious conclusion, and b) my statement was not limited to
    MCUs.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Wed Jun 24 11:04:32 2026
    From Newsgroup: comp.lang.c

    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.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 24 04:36:20 2026
    From Newsgroup: comp.lang.c

    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?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jun 24 04:42:32 2026
    From Newsgroup: comp.lang.c

    On 6/23/2026 7:04 PM, Lawrence DrCOOliveiro wrote:
    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?

    ;^)

    Iirc, I think from memory. We can possible get different function
    pointers based on the state of the SOCKET... Can be a Qos, or some shit.
    Hard to remember right now.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Wed Jun 24 12:18:51 2026
    From Newsgroup: comp.lang.c

    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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Wed Jun 24 12:19:52 2026
    From Newsgroup: comp.lang.c

    In article <111gffk$2vmup$1@dont-email.me>,
    Chris M. Thomasson <chris.m.thomasson.1@gmail.com> 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? 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?

    Perhaps you and Lawrence can take this to comp.unix.programmer
    or a similar group.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Wed Jun 24 15:02:14 2026
    From Newsgroup: comp.lang.c

    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 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.

    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.

    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.

    It's entirely possible that there has been different interpretations
    about "the microprocessors you routinely use". It's very likely that on
    some or all of the PC's I have on my desk, there is a 16550 (or related)
    UART inside - probably as part of the supporting chipset rather than the processor, and probably not even routed to a header on the motherboard.
    On some of my older "archived" machines, they certainly had 16550-style
    serial ports.

    In the context, however, I viewed it in terms of the microprocessors and microcontrollers I work with. Glancing around my desk, I think I have
    perhaps 2 different Linux SoCs and 6 or 7 different microcontrollers on
    boards that I am using in projects under active development at the
    moment. Those are the ones I am /using/, and none have 16550's (or even PL011's).

    If I were to add up the count of microcontrollers and embedded
    processors and microcontrollers in my office, I'd guess I could easily
    find a hundred in products that we neither design nor program - in
    switches, routers, keyboards, powerbanks, monitors, hard drives, "smart" lights, oscilloscopes, and everything else. And there's probably
    another half-hundred microcontrollers in boards that we have made, in
    boxes around the office which I am not working with at the moment.
    (I've had the same office for 20 years, and still have not found the
    rubbish bin...)

    Now, I can agree that there are likely to be some PL011 UARTs around -
    if nothing else, I know there is one on each of the Raspberry Pi's I
    have scattered about. It was the 16550 I said (admittedly an
    exaggeration) was obsolete, not the PL011 - the PL011 is a perfectly serviceable UART for many modern uses. I would not be surprised if
    there was a PL011 in the ARM SoC's in some of the routers and managed
    switches I have, for example. But there are none in any of the chips I
    work with, as far as I am aware.


    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.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Wed Jun 24 15:27:53 2026
    From Newsgroup: comp.lang.c

    On 24/06/2026 13:04, Dan Cross wrote:
    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)


    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.

    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.


    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.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Wed Jun 24 15:51:29 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    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

    Or 'stty(1)' on unix/linux.

    e.g

    $ stty -icrnl -ocrnl cs8 38400 -crtscts < /dev/tty0


    (-crtscts is a GNU coreutils extension to posix).
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Wed Jun 24 21:54:16 2026
    From Newsgroup: comp.lang.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.








    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Wed Jun 24 22:00:10 2026
    From Newsgroup: comp.lang.c

    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?






    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Wed Jun 24 21:09:29 2026
    From Newsgroup: comp.lang.c

    On 24/06/2026 20:54, Michael S wrote:
    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.

    Indeed - they were MPC5xx and MPC5xxx devices. But they had PowerPC
    cores, like the PPC 4xx family, though of course different devices had different variants of the embedded PowerPC cores.


    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.


    Yes.

    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.









    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Wed Jun 24 20:09:25 2026
    From Newsgroup: comp.lang.c

    Michael S <already5chosen@yahoo.com> writes:
    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?


    Both the slides and a transcript are linked in the video description.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From pa@pa@see.signature.invalid (Pierre Asselin) to comp.lang.c on Wed Jun 24 21:21:15 2026
    From Newsgroup: comp.lang.c

    Michael S <already5chosen@yahoo.com> wrote:

    [ ... ]
    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.

    Hmmm, no.

    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:

    Set the fd for non-blocking reads;
    loop: {
    Select to read with a short timeout (2 ms or so at 9600 baud).
    Read what's available, appending to a buffer.
    }
    // timed out; that means we finished reading the string.
    {
    Select to read with a long timeout.
    Read the marker.
    (Read the system clock so we can calculate the delta later.)
    Echo the marker.
    }
    // That's one timestamp. Repeat for more, until NIST hangs up.

    The select() call had plenty timeout resolution. (You could use poll() too.)

    (When you echo the marker, NIST measures the round-trip time, corrects
    for it and changes the marker to a "#".)



    [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.
    --
    pa at panix dot com
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Thu Jun 25 00:25:31 2026
    From Newsgroup: comp.lang.c

    On Wed, 24 Jun 2026 20:09:25 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:



    Both the slides and a transcript are linked in the video description.


    Thank you.
    I found slide. Didn't find transcript yet.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Wed Jun 24 21:47:45 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Thu Jun 25 11:29:23 2026
    From Newsgroup: comp.lang.c

    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 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.

    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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Thu Jun 25 11:56:19 2026
    From Newsgroup: comp.lang.c

    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. :-}

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Thu Jun 25 12:00:36 2026
    From Newsgroup: comp.lang.c

    In article <20260624220010.00006ed7@yahoo.com>,
    Michael S <already5chosen@yahoo.com> wrote:
    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.

    Huh.

    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?

    Systems is kind of weird in computer science (and other
    disciplines) in the sense that conferences are the primary venue
    where new material is presented. Seems like you're cutting
    yourself off from most of frontier of work in the subfield
    arbitrarily, but you do you.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Jun 25 15:31:20 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    In article <111gkgm$2vhih$1@dont-email.me>,
    David Brown <david.brown@hesbynett.no> wrote:
    <snip>
    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.


    I would dispute that. A modern 1Gb (or faster) network interface
    will use various hardware interrupt moderation techniques to
    reduce the interrupt rate to the OS. 10/25/50/100Gb network
    adapters must use such techniques to achieve line rate.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Jun 25 15:37:05 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    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.

    Michael must dislike HTTP, IMAP, SSH, SMTP, not to mention
    the protocols layered atop HTTP.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Jun 25 19:15:05 2026
    From Newsgroup: comp.lang.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:
    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 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.

    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.


    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.


    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.

    Have you a reference for those? ST makes a /lot/ of devices with
    Cortex-M cores, and I have not looked at the details of more than a
    small fraction of them. None of the ones I have seen have a PL011, and
    it would surprise me to hear that they used them. If ST incorporates a
    PL011 into a microcontroller with a Cortex-M core, they need to pay
    royalties to ARM for that (along with the cost of the cpu core) - if
    they use one of their own UART peripherals, it costs them nothing but
    the die space and they can choose from UARTs that smaller and lower
    power than the PL011, or ones with additional features and capabilities.
    ST has had re-usable UART cores from long before the PL011 existed. I
    am not saying that I know for sure that they haven't picked PL011's, but
    I find hard to see how it would make sense. I am also not saying the
    PL011 is a bad UART - it has more useful features than the 16550 (DMA
    support is key) - but it also lacks features that I find useful in the
    UARTs in the ST Cortex-M33 device I am working with right now.

    The only reference to PL011's that I found on ST's site was on some
    ARM926 based processors from fifteen years ago. You can still buy the devices, so they are not obsolete, but they are long outdated and marked
    "not suitable for new designs". (Again, the PL011 appears to be a
    reasonable enough UART, but it's not used in modern processors targeting industrial use. Basically, it's not used in processors where you expect
    to use the UART for something other than debugging output or a serial terminal.)


    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.


    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%

    That is very interesting, and somewhat unexpected. Thanks for the
    example. Where is this riscv core from?


    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.


    (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.)

    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.

    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.


    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).

    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.

    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.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Jun 25 18:29:13 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Jun 25 20:52:11 2026
    From Newsgroup: comp.lang.c

    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:


    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.

    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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Jun 25 21:30:23 2026
    From Newsgroup: comp.lang.c

    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]
    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.


    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?



    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 think we agree here. I have no doubts that you can have a "big"
    system, with the features and overheads that implies (like security, and running multiple programs rather than just multiple threads), without
    mixing tty's and serial ports.

    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.


    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.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Thu Jun 25 12:44:59 2026
    From Newsgroup: comp.lang.c

    On 6/24/2026 2:47 PM, Lawrence DrCOOliveiro wrote:
    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.

    Use only when you need it. Fair enough? ;^)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Thu Jun 25 22:53:49 2026
    From Newsgroup: comp.lang.c

    On Thu, 25 Jun 2026 18:29:13 GMT
    scott@slp53.sl.home (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:


    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 my STM32 designs it was possible (and easy) to take interupt
    moderation to its ultimate end, i.e. no interrupts at all. Their DMA
    is *that* good.
    Of course, my not very demanding requirements also helped.

    Unfortunately, for various reasons, both good and bad, after 2020 my
    Cortex-M MCUs tend to be from TI TIVA series rather than from STM32.
    TI DMA is not a total crap, but not in the STM class. I think, their DMA
    is based on some old ARM-supplied components, but not 100% sure
    about it. So, while on TiVa I have to make do with interrupt moderation instead of elimination.








    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Fri Jun 26 14:58:29 2026
    From Newsgroup: comp.lang.c

    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:


    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.

    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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Fri Jun 26 11:46:24 2026
    From Newsgroup: comp.lang.c

    On 6/26/2026 7:58 AM, Scott Lurndal wrote:
    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:


    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.

    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 :-)

    Well done. :^)


    But again, those are
    not things I have done myself.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Sat Jun 27 01:52:24 2026
    From Newsgroup: comp.lang.c

    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:
    [snip]
    Again, not something I was commenting on. Low(er) volume !=
    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.

    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.

    Yes, a long time ago: my statement was about the present, as was
    your judgement.

    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.

    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.

    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.

    Yes, all of which seemed to be based on an incorrect reading of,
    and follow ups to, his.

    [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?

    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 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.)

    Ok, fair points. I conress I find it somewhat difficult to
    follow your exact line of discussion becuase it jumps between seemingly-unrelated 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.

    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?

    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.

    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.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Sat Jun 27 01:57:30 2026
    From Newsgroup: comp.lang.c

    In article <111jtcr$8p9$1@dont-email.me>,
    David Brown <david.brown@hesbynett.no> wrote:
    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:


    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.

    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.

    It's important to understand that, when we talk about e.g. 100
    Gbps NICs, that is not measuring single-stream performance; that
    usually tops out well-below 100G. Rather, that's aggregated
    across all streams handled by the ASIC. Any given part has many
    queues, handling of those (and interrupt delivery) will be
    smeared across cores to minimize per-interrupt latency, and
    often a substantial amount of hardware offload is in play;
    everything from IP checksum offloads to automatic recognition of
    layer 4 protocols for hashing entire flows to dedicated queues
    (to maintain locality when handling a given stream).

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Sat Jun 27 02:22:34 2026
    From Newsgroup: comp.lang.c

    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]
    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.

    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.

    Ok, but that has nothing to do with the interface, but rather,
    the resources available to you to learn the interface. The two
    are qualitatively different.

    [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.

    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.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Sat Jun 27 19:46:41 2026
    From Newsgroup: comp.lang.c

    On 27/06/2026 03:52, 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:
    [snip]
    Again, not something I was commenting on. Low(er) volume !=
    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.

    OK. Yes, I agree that 16550 (or similar) UARTs will be fine for the
    tasks you'd expect on such systems.


    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.


    My experience also covers embedded Linux systems, but those have all
    been ARM (I've worked briefly with Coldfire, AVR32 and MIPs embedded
    Linux systems, but only very superficially, long ago). We have a
    customer that used some embedded Intel devices, and I have a few routers
    and firewalls lying around with x86 cores - but I have no reason to look
    at the UARTs on such systems.


    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.


    No, I have not used it or read anything about it.

    [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.


    Ok, fair points. I conress I find it somewhat difficult to
    follow your exact line of discussion becuase it jumps between seemingly-unrelated points.

    That in turn is a fair point. And we do seem to have lost C far behind.
    I'm trying to snip a bit, and not wander too far.

    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.


    Yes, that's an undeniable truth.

    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.


    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.

    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.

    That particular case was optimising for low jitter in the latency rather
    than absolute latency, though we wanted low absolute latency too.
    Throughput was not high, and was - most of the time - very stable.


    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?

    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 :-) )


    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.

    Then I withdraw all my objections!


    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.


    When I wrote "not a feature I have seen as useful", I was being
    subjective - it is not a statement or assumption about things that I
    have /not/ seen. Maybe other people do still find that kind of flow
    control useful, even in modern usage - I am not assuming it does not
    happen, merely saying that it is not something I have needed myself or
    seen used (in situations where I know the details) for a very long time.
    But given that I have made unwarranted extrapolations before, I can
    see how you might think I was doing so again.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Sat Jun 27 20:49:24 2026
    From Newsgroup: comp.lang.c

    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:
    [snip]
    Again, not something I was commenting on. Low(er) volume !=
    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?

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Sat Jun 27 18:50:14 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    In article <111jnmp$3tni8$1@dont-email.me>,
    David Brown <david.brown@hesbynett.no> wrote:

    <snip>

    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.

    Minor nit, DW (Designware) is synthesizable IP from Synopsys
    that is included typically in SoC (or BMC) designs. It's not
    a standalone part per se.

    https://www.synopsys.com/designware-ip/soc-infrastructure-ip/amba/amba-uart.html
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Sun Jun 28 00:15:20 2026
    From Newsgroup: comp.lang.c

    On 2026-06-24 23:21, Pierre Asselin wrote:
    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.

    Reminds me a simple service that the PTB (in DE) offered 30 years ago
    and that I was happily using to simply interrogate the UTC time from
    the command-line in a _minimalist_ textual form by just interrogating
    a PTB server at a specific port (and without specific protocol or tool)

    gawk '
    BEGIN {"/inet/tcp/0/www.ptb.de/5076" |& getline time ; print time }
    '

    Only a few years later they discontinued that nice simplistic service.

    Meanwhile they have a fancy GUI (https://uhr.ptb.de/ - nothing that I
    could interrogate and process as simply as with above script).

    A current alternative (but not exactly as simple as before) is going
    through NTP with the respective tool as in: ntpdate -q ptbtime1.ptb.de

    Janis
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Sun Jun 28 18:59:38 2026
    From Newsgroup: comp.lang.c

    On 27/06/2026 04:22, Dan Cross wrote:
    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.

    I would not want to either make or take such a bet - there is such a
    vast body of microcontroller software that there is no way to know. So
    I can only talk about code that I have seen (whether I wrote it or
    someone else did).

    It is certainly true that a lot of microcontroller programs don't use an
    RTOS - either because they have too few resources, because the
    programmers are not confident with them, or simply because the
    application doesn't need them. There are many advantages in writing
    software without multiple threads - your memory setup is far simpler and
    it is therefore easier to be sure it is correct, you have no race
    conditions, synchronisation, locking, or atomic access considerations
    (except in connection with interrupts, or hardware like DMA), and its
    easier to have a full track of what is going on. I think you are on
    fairly safe ground saying that most microcontroller software does not
    use an RTOS or multi-threading, but "the vast bulk" is a risky stretch.
    There is also no doubt that the use of RTOS's is much more common now
    than it used to be (helped enormously by the general move towards 32-bit microcontrollers with a good deal more ram).

    It is a lot less common (without giving any statistics or numbers here)
    for non-trivial microcontroller code to run without any interrupts. I
    know of a few microcontrollers that have no interrupt mechanisms, such
    as the PIC12x family, but they are not particularly common and long
    outdated (I hesitate to say "obsolete" - Microchip have a reputation for continuing to produce old devices, and they are still available to buy -
    but you will not see them in new designs). It is extremely common to
    have at least a regular timer interrupt, and interrupts for transfers of UARTs, SPI, I-#C, and ADC readings are found in a great many
    microcontroller programs.

    While, again, it is very difficult to get accurate information about
    what people use in their code, there is the time-honoured technique of following the money. When making a small microcontroller core,
    supporting interrupts is not free - it takes die space, design effort,
    and power. Devices which do not support interrupts at all are rare -
    even in the world of 4-bit microcontrollers, you often have interrupts
    (one of the few 4-bit families that was easily available to the masses
    was the Atmel Marc 4, and it had 8 interrupt lines with different
    priorities). If it were normal practice not to use the interrupts, I
    think you'd have seen a few more devices that saved money and
    power-usage by omitting them.

    So a solid proportion of microcontroller programs do not have threads,
    but do have interrupts. And they have a "main loop". Such "main loops" generally do several things - you very often see a "while (true)" or
    "for (;;)" loop with a series of "run_task1()", "run_task2()", type of function call. And yes, some of these will poll for hardware register
    bits to see what needs to be done. Many will be connected to a timer or
    too, so they run periodically. Some will just run this loop
    continuously, but another common pattern is to end with a "sleep" or "wait-for-interrupt" instruction to put to the core to sleep until an interrupt occurs. (I have had a few programs where the entire "main
    loop" was a sleep instruction - all work was done in interrupt functions.)

    Any discussion about "efficiency" or "sophistication" would have to be
    in view of the tasks being handled by the software. (I note that you
    did not say or imply that being inefficient or unsophisticated is
    necessarily a bad thing.) A simple list of "run_task1(); run_task2();
    ... " is not as "sophisticated" as having a dynamic scheduler with
    priority queues implemented as Fibonacci heaps, but it is vastly more efficient for a small number of fixed tasks. A simpler solution for a
    job might sometimes be less efficient in processor cycles than a more
    advanced one, but it might be more efficient in development time, or
    when looking at how you can be sure it is correct. ("Real-time"
    programming is not about doing things quickly or efficiently - it's
    about being sure that you do things within the required time limits.)
    And "efficiency" of processor cycles is relevant when cycles saved could
    be used for other purposes, or save energy, or let you use a cheaper or
    slower device. That is not always a relevant factor. A microcontroller
    might be trying to run on a battery for ten years, or it might be
    controlling a 10 kW motor - in the former case, saving processor cycles
    could mean saving money on battery sizes, but in the later case saving
    power is irrelevant.


    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.

    Yes, to some extent at least. Microcontrollers and "typical"
    microcontroller software are appropriate for different tasks than "big" processors and "big" OS's, and they do things differently. But
    sometimes there is enough similarity in a task that comparisons are
    possible (though not necessarily useful).

    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.

    "Efficiently" for a Linux system here is likely to have an emphasis on efficiency of throughput, rather than for smaller transfers. That is,
    of course, perfectly fine.


    [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.


    That's fair enough (and I've tried to be a bit more nuanced in this
    reply). Equally, however, you made some pretty categorical claims about microcontroller software being "terribly unsophisticated" and "wasting a
    lot of CPU cycles". But I think we have written enough on these things
    - unless we can find a way to bring it back to C!

    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.

    Okay. I am not sure it was clear that this was your point, but it is a
    point that I can agree with. Equally, I think it is obvious that a more general approach - however sophisticated the code may be - will not necessarily be more efficient. Generalisation usually comes at a cost compared to dedicated solutions, if the details of the task are fixed
    and known. (And in embedded systems - even embedded Linux systems - the
    task requirements are usually a lot more fixed than than in a general OS.)


    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.


    Again, I am not sure that was clear from what you wrote - but I agree
    with your point as you have rephrased it here.

    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.


    I am fully aware that there is a wide range in the embedded world - even
    if you restrict it to microcontrollers and exclude embedded Linux and
    the like. The smallest microcontroller I have worked with had no ram at
    all, only its 32 8-bit registers (I still programmed it in C, with
    gcc!), and I've seen speeds ranging from about 0.3 MIPs to 1000 MIPs
    (without specifying what each "instruction" here could do). So I would
    not want to make any bets about what the "vast bulk of microcontroller software" does.

    One thing you might not be aware of is the difference between what is generally termed a "Memory Protection Unit" (MPU) and a "Memory
    Management Unit" (MMU). With the proviso that the terms are not
    strictly defined and the there can be exceptions in both hardware and
    software usage, an MMU generally deals with translations of virtual
    addresses to physical addresses as well as controlling accesses (at
    either the virtual or physical address level). An MPU normally does not
    do any translation - it is for access control and determining address
    space characteristics like cacheability. In an RTOS on a
    microcontroller, the MPU is typically configured once at startup and not changed thereafter - including during context switches. There can be a distinction between some kind of "privileged", "supervisor" or "system"
    mode and "user", "problem" or "task" mode (terminology varies
    significantly), and also between "secure" and "non-secure" modes. But
    the MPU, together with any other security features, bus access blocks,
    etc., will normally have a single setup to say what memory and
    peripherals are accessible by code running in each mode. The MPU does
    not need changed between threads (with the exception of sometimes
    changing one window used for catching stack overflows in some setups),
    and does not have the kind of context switch overhead required between processes in a big system with virtual memory and security and
    protection between tasks.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Wed Jul 1 13:16:15 2026
    From Newsgroup: comp.lang.c

    In article <111p2a1$34arg$1@dont-email.me>,
    David Brown <david.brown@hesbynett.no> wrote:
    [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.

    My guess is that for the embedded market, they favor cost saving
    compounded by volume; at scale, a 5c difference in the cost of a microcontroller can add up. For application-profile cores, it's
    less of a consideration on the margins, so they favor
    standardization to leverage network effects around software
    ecosystems.

    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!

    For RPi, this was one of their first in-house designs, versus
    using one of Broadcom's offerings, wasn't it? Perhaps they went
    with off-the-shelf IP for the UART to minimize risk. For Zynq,
    I suspect the cost of the FPGA dwarfs whatever savings they'd
    get from their own UART, so they favor software compatibility.

    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.

    I agree, and I'm happy to have RISC-V boards to work with.
    However, compared to an RPi, it's not fast; maybe comparable to
    an RPi2 or RPi3. However, it has native NVMe and an M.2 slot at
    Gen2x4 and a real Ethernet PHY (not a USB bridge), that can
    eliminate some of the IO slowness of older RPi hardare.

    In terms of competative application cores available at scale,
    the RV64 ecosystem has a lot of work to do.

    [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.

    Agreed.

    [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 :-) )

    Huh. Well, ok; sounds challenging!

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Wed Jul 1 13:17:04 2026
    From Newsgroup: comp.lang.c

    In article <20260627204924.00002fef@yahoo.com>,
    Michael S <already5chosen@yahoo.com> wrote:
    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:
    [snip]
    Again, not something I was commenting on. Low(er) volume !=
    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?

    ...the registers and bits in them?

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2