Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. And when you depend on multithreading to be unpredictable, it isn't!

And when you depend on multithreading to be unpredictable, it isn't!

Scheduled Pinned Locked Moved The Lounge
asp-nethelptutorial
48 Posts 15 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H honey the codewitch

    1. I don't write my own concurrency safe queues because FreeRTOS has one and so does .NET so I've not had the need. 2. Yeah, when I wrote a ring buffer in C# I did that 3. I don't know a good reason to use that over say, std::atomic. In my experience, anything that won't support std::atomic won't support atomic CMPXCHG operations at the CPU level anyway, at least not that way. With the atMega2560 for example, IIRC it doesn't have one, forcing you to disable interrupts and then reenable them after the operation is complete. Don't quote me on the mega's capabilities, I'm not an AVR expert. It might be a bad example. Particularly, #3 is curious to me. Why wouldn't you use for example, std::atomic_int? Is it because it's a C++ thing? I use C++ even on 8-bit machines with 4kb of RAM. I just severely limit my use of things like The STL to the bare minimum. std::atomic is one area I use. std::chrono is another. Why? Because writing cross platform CMPXCHNG and timer code is error prone and i don't have access to all that hardware.

    Real programmers use butterflies

    U Offline
    U Offline
    User 13269747
    wrote on last edited by
    #29

    Yes, it's because it's a C++ thing, and my queueing library is a C thing (My mention of pthreads should have given it away :-))

    H 1 Reply Last reply
    0
    • U User 13269747

      Yes, it's because it's a C++ thing, and my queueing library is a C thing (My mention of pthreads should have given it away :-))

      H Offline
      H Offline
      honey the codewitch
      wrote on last edited by
      #30

      I've used pthreads from C++, so it didn't give it away for me. I was about to write a top level post pondering the overall utility of writing *new* code in C. I love C, but I just can't think of any hardware I've coded for (and i code for little devices) that can't at least host a binary compiled with a C++ compiler. Given that I don't use *most* of C++ (like the STL) when I'm targeting an 8 bit monster, but classes and RAII still help with code management, for example.

      Real programmers use butterflies

      U 1 Reply Last reply
      0
      • H honey the codewitch

        Not if there's I/O or something involved, but otherwise, yes, it "probably" will. The reason I say probably is because when you're dealing with multiple cores, they don't run in lockstep with one another. There's a small amount of non-determinism just in the fact that the cores keep their own schedulers and may not have started at precisely the same moment nor even work together*** *** they might synchronize with each other - it's a FreeRTOS-ESP32variant implementation detail I haven't looked into. But that aside, there's also the issue of I/O, which when dealing with an external device, can introduce non-determinism. In my code, I'm outputting to a serial UART, that's connected through an FTDI built bus/USB-bridge controller to a windows PC. Any latency introduced by the PC will ripple back to the thread that's running waiting on I/O.

        Real programmers use butterflies

        M Offline
        M Offline
        milo xml
        wrote on last edited by
        #31

        Thank you!

        1 Reply Last reply
        0
        • H honey the codewitch

          I've used pthreads from C++, so it didn't give it away for me. I was about to write a top level post pondering the overall utility of writing *new* code in C. I love C, but I just can't think of any hardware I've coded for (and i code for little devices) that can't at least host a binary compiled with a C++ compiler. Given that I don't use *most* of C++ (like the STL) when I'm targeting an 8 bit monster, but classes and RAII still help with code management, for example.

          Real programmers use butterflies

          U Offline
          U Offline
          User 13269747
          wrote on last edited by
          #32

          Quote:

          I was about to write a top level post pondering the overall utility of writing *new* code in C.

          The overall utility is in the reuse. Writing a library in C means that it can be reused from Python, C++, Java, Perl, Rust, C#, Php, Go, Tcl, Delphi/Lazarus, Pascal, etc. Libraries in C++ can be reused by making C-compatible wrappers around functions, not exposing classes, suppressing exceptions, typedefing structs and prefixing all functions with 'extern "C"'. But then you lose a lot of the value of C++. Lets say you come up with something new and truly useful: a new uber-compression alorithm, or a quantum-computer-proof elliptic curve cryptography. You go ahead and write it in Haskell, or Clojure, or Scala, etc. It definitelywon't take off until someone clones it into a reusable library. Right now we are in a period of computing where it is fashionable to rewrite everything (and also fashionable to pretend that C is the great evil). As far as I can tell, though, the new systems languages are taking a bite out of the C++ mindshare, not out of the C mindshare. C will die the usual way, simply due to attrition as those that know it die off :-)

          H 1 Reply Last reply
          0
          • U User 13269747

            Quote:

            I was about to write a top level post pondering the overall utility of writing *new* code in C.

            The overall utility is in the reuse. Writing a library in C means that it can be reused from Python, C++, Java, Perl, Rust, C#, Php, Go, Tcl, Delphi/Lazarus, Pascal, etc. Libraries in C++ can be reused by making C-compatible wrappers around functions, not exposing classes, suppressing exceptions, typedefing structs and prefixing all functions with 'extern "C"'. But then you lose a lot of the value of C++. Lets say you come up with something new and truly useful: a new uber-compression alorithm, or a quantum-computer-proof elliptic curve cryptography. You go ahead and write it in Haskell, or Clojure, or Scala, etc. It definitelywon't take off until someone clones it into a reusable library. Right now we are in a period of computing where it is fashionable to rewrite everything (and also fashionable to pretend that C is the great evil). As far as I can tell, though, the new systems languages are taking a bite out of the C++ mindshare, not out of the C mindshare. C will die the usual way, simply due to attrition as those that know it die off :-)

            H Offline
            H Offline
            honey the codewitch
            wrote on last edited by
            #33

            The simplicity of it for expressing algorithms one has developed is certainly a win, but honestly, I'd rather read it in C# than C if I was going to port it. In practice, I've ported C# stuff to C++ on IoT things several times - everything from a thread synchronization library to a streaming JSON parser with a less than 4kB footprint not tied to document size. C# is just easy to read, IMO but that's just one dev's opinion based on dev's experience. Some of that could have easily been made into C. I don't think wrapping things with extern loses you valuable C++, but exporting C also is kind of like writing new code for "C" so it wasn't something that was on my radar when I responded. Importing code that's compiled in C is another matter. I don't think "C" is evil, so maybe I'm just not fashionable. I'm just seeing less of a point for it these days. The beauty of C++ is you *don't* have to rewrite all that C code. You can use it at the source or binary level in your C++ apps.

            Real programmers use butterflies

            U 1 Reply Last reply
            0
            • H honey the codewitch

              It's bad enough that multithreaded code is nondeterministic. I propose that it is also meta-nondeterministic: You can not even count on it to be non-deterministic :-\ When you need it to be unpredictable, the scheduler will inexplicably run your timeslices the exact same way, even when threads are executing on different cores, and even reboot to reboot. I'm stuck on creating an *example* simply because I cannot create a situation wherein two secondary threads appear to be in competition (with the third thread being the main application thread) on a dual core ESP32 running FreeRTOS. I can do it where one thread is in competition with the primary thread, but it's as if the scheduler is just a dog when it comes to scheduling between two threads on the same core or something. Grrr. It's bizarre.

              Real programmers use butterflies

              S Offline
              S Offline
              Stuart Dootson
              wrote on last edited by
              #34

              What scheduling algorithm is being used? IIRC, FreeRTOS has multiple scheduling algorithms you can choose between, which might affect the amount of non-determinism?

              Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

              H 1 Reply Last reply
              0
              • S Stuart Dootson

                What scheduling algorithm is being used? IIRC, FreeRTOS has multiple scheduling algorithms you can choose between, which might affect the amount of non-determinism?

                Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                H Offline
                H Offline
                honey the codewitch
                wrote on last edited by
                #35

                Hmm. The one I'm using is a variant ported to the ESP32 to use the ESP-IDF, by Espressif. Their forums, and the FreeRTOS documentation I've encountered online both suggest that round robin is used for any thread created on the same priority level on the same scheduler (core) This leads to starvation. The forums warn of it particularly, but so does setting different priorities, just for slightly different reasons. There's no "salting" done in their scheduler according to any of the documentation I've encountered.

                Real programmers use butterflies

                S 1 Reply Last reply
                0
                • H honey the codewitch

                  Hmm. The one I'm using is a variant ported to the ESP32 to use the ESP-IDF, by Espressif. Their forums, and the FreeRTOS documentation I've encountered online both suggest that round robin is used for any thread created on the same priority level on the same scheduler (core) This leads to starvation. The forums warn of it particularly, but so does setting different priorities, just for slightly different reasons. There's no "salting" done in their scheduler according to any of the documentation I've encountered.

                  Real programmers use butterflies

                  S Offline
                  S Offline
                  Stuart Dootson
                  wrote on last edited by
                  #36

                  I was under the impression that round robin scheduling would guarantee equal time for pre-emptive tasks with the same priority (presuming no higher priority task preempts *them*), which should mean no starvation. Guess I was under the wrong impression.

                  Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                  H 1 Reply Last reply
                  0
                  • S Stuart Dootson

                    I was under the impression that round robin scheduling would guarantee equal time for pre-emptive tasks with the same priority (presuming no higher priority task preempts *them*), which should mean no starvation. Guess I was under the wrong impression.

                    Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                    H Offline
                    H Offline
                    honey the codewitch
                    wrote on last edited by
                    #37

                    In the case where thread A and thread B operate at the same priority, everything works until we start looking at who to unblock. It will always unblock the next thread in the round robin list. if thread A is coded where it sleeps twice for every time thread B sleeps once, I think it will lead to one of them being starved. I'm not entirely confident in that without testing it, but it's easy for me to starve a thread in the wild on this OS. If it were me i would have stored the machine tick based timestamp on the last time the thread was unsuspended. all priorities considered equal, i would use that to determine which to wake up next, and then if further disambiguation was necessary (doubtful) it could round robin, but i don't think that's even necessary.

                    Real programmers use butterflies

                    1 Reply Last reply
                    0
                    • H honey the codewitch

                      The simplicity of it for expressing algorithms one has developed is certainly a win, but honestly, I'd rather read it in C# than C if I was going to port it. In practice, I've ported C# stuff to C++ on IoT things several times - everything from a thread synchronization library to a streaming JSON parser with a less than 4kB footprint not tied to document size. C# is just easy to read, IMO but that's just one dev's opinion based on dev's experience. Some of that could have easily been made into C. I don't think wrapping things with extern loses you valuable C++, but exporting C also is kind of like writing new code for "C" so it wasn't something that was on my radar when I responded. Importing code that's compiled in C is another matter. I don't think "C" is evil, so maybe I'm just not fashionable. I'm just seeing less of a point for it these days. The beauty of C++ is you *don't* have to rewrite all that C code. You can use it at the source or binary level in your C++ apps.

                      Real programmers use butterflies

                      U Offline
                      U Offline
                      User 13269747
                      wrote on last edited by
                      #38

                      Quote:

                      The beauty of C++ is you *don't* have to rewrite all that C code. You can use it at the source or binary level in your C++ apps.

                      But that was my point, sort of... anything I write that I want to reuse has to be written in C (or, lately, Rust). If I write it in C I can use it from anywhere and any language. If I write in in C++ I can't. If I write in C# I have even fewer opportunities to reuse.

                      H 1 Reply Last reply
                      0
                      • U User 13269747

                        Quote:

                        The beauty of C++ is you *don't* have to rewrite all that C code. You can use it at the source or binary level in your C++ apps.

                        But that was my point, sort of... anything I write that I want to reuse has to be written in C (or, lately, Rust). If I write it in C I can use it from anywhere and any language. If I write in in C++ I can't. If I write in C# I have even fewer opportunities to reuse.

                        H Offline
                        H Offline
                        honey the codewitch
                        wrote on last edited by
                        #39

                        I think we're talking about two different things because time after time I have a much easier go of porting C# to C than the other way around.

                        Real programmers use butterflies

                        U 1 Reply Last reply
                        0
                        • H honey the codewitch

                          I think we're talking about two different things because time after time I have a much easier go of porting C# to C than the other way around.

                          Real programmers use butterflies

                          U Offline
                          U Offline
                          User 13269747
                          wrote on last edited by
                          #40

                          Quote:

                          I think we're talking about two different things because time after time I have a much easier go of porting C# to C than the other way around.

                          You're correct, I am not talking about porting, I am talking about using. Anything you write in C# can only be used inside the .net runtime. If you want to use it elsewhere yo have to port it. With C, and some care, anything written can be used by any other language without porting ... like libpng (usable by all languages without porting, or libzip, or almost anything else in my system (yours too, probably). A good example is SQLite (the most-used and most deployed library in the world according to the statistics from MS): if it were written in C#, or in C++, or in anything else other than C, it would not be as useful as it is because it would not be usable from all languages.

                          H 1 Reply Last reply
                          0
                          • U User 13269747

                            Quote:

                            I think we're talking about two different things because time after time I have a much easier go of porting C# to C than the other way around.

                            You're correct, I am not talking about porting, I am talking about using. Anything you write in C# can only be used inside the .net runtime. If you want to use it elsewhere yo have to port it. With C, and some care, anything written can be used by any other language without porting ... like libpng (usable by all languages without porting, or libzip, or almost anything else in my system (yours too, probably). A good example is SQLite (the most-used and most deployed library in the world according to the statistics from MS): if it were written in C#, or in C++, or in anything else other than C, it would not be as useful as it is because it would not be usable from all languages.

                            H Offline
                            H Offline
                            honey the codewitch
                            wrote on last edited by
                            #41

                            That's weird because my JSON parser was ported from C# and it doesn't require the .NET runtimes. Same with my threading and synchronization library (also originally written in C#) And the only place you can run C without porting is C++, and even that is not always true. Furthermore, as soon you declare int* foo; Or any "array" of indeterminate size in C you've pretty much nixed any dream of making it work on anything without pointers- "without porting" sorry, but what are you even talking about?

                            Real programmers use butterflies

                            U 1 Reply Last reply
                            0
                            • H honey the codewitch

                              That's weird because my JSON parser was ported from C# and it doesn't require the .NET runtimes. Same with my threading and synchronization library (also originally written in C#) And the only place you can run C without porting is C++, and even that is not always true. Furthermore, as soon you declare int* foo; Or any "array" of indeterminate size in C you've pretty much nixed any dream of making it work on anything without pointers- "without porting" sorry, but what are you even talking about?

                              Real programmers use butterflies

                              U Offline
                              U Offline
                              User 13269747
                              wrote on last edited by
                              #42

                              Like I said, I'm not talking about porting. Take, for example, SQLite. You can access it from any language without porting.

                              H 1 Reply Last reply
                              0
                              • U User 13269747

                                Like I said, I'm not talking about porting. Take, for example, SQLite. You can access it from any language without porting.

                                H Offline
                                H Offline
                                honey the codewitch
                                wrote on last edited by
                                #43

                                As long as you're willing to write a wrapper for any language that isn't C++. If you don't count that. Funny, if I don't count the work involved it takes to do something, how it suddenly doesn't take any work at all.

                                Real programmers use butterflies

                                U 1 Reply Last reply
                                0
                                • H honey the codewitch

                                  As long as you're willing to write a wrapper for any language that isn't C++. If you don't count that. Funny, if I don't count the work involved it takes to do something, how it suddenly doesn't take any work at all.

                                  Real programmers use butterflies

                                  U Offline
                                  U Offline
                                  User 13269747
                                  wrote on last edited by
                                  #44

                                  Quote:

                                  As long as you're willing to write a wrapper for any language that isn't C++. If you don't count that.

                                  Generally, since it is usually trivial to write those wrappers, you don't count that (also, I think you mean "C", not "C++"). Porting SQLite so that Python programs can use it would mean re-implementing a few 100s of thousands of lines of code and a decade or so of manpower. Writing the wrappers takes ~2000 and can be done in a weekend for Python. If SQLite was written in C#, your only option would be to rewrite a few 100s of thousands of lines of code, you don't get the option of sitting down in a weekend and writing the interface for it.

                                  Quote:

                                  Funny, if I don't count the work involved it takes to do something, how it suddenly doesn't take any work at all.

                                  It's just a preference I have when I write software - I prefer to write it only once and never have to port because I prefer reuse. You obviously have a different preference. More power to you, but stop pretending that a weekends work writing wrappers is equivalent to a few decades by experts in the field (Dr Hipp is the main author of SQLite, and a recognised database expert). You feel that reuse is useless, fine, stop pretending it doesn't exist.

                                  H 1 Reply Last reply
                                  0
                                  • U User 13269747

                                    Quote:

                                    As long as you're willing to write a wrapper for any language that isn't C++. If you don't count that.

                                    Generally, since it is usually trivial to write those wrappers, you don't count that (also, I think you mean "C", not "C++"). Porting SQLite so that Python programs can use it would mean re-implementing a few 100s of thousands of lines of code and a decade or so of manpower. Writing the wrappers takes ~2000 and can be done in a weekend for Python. If SQLite was written in C#, your only option would be to rewrite a few 100s of thousands of lines of code, you don't get the option of sitting down in a weekend and writing the interface for it.

                                    Quote:

                                    Funny, if I don't count the work involved it takes to do something, how it suddenly doesn't take any work at all.

                                    It's just a preference I have when I write software - I prefer to write it only once and never have to port because I prefer reuse. You obviously have a different preference. More power to you, but stop pretending that a weekends work writing wrappers is equivalent to a few decades by experts in the field (Dr Hipp is the main author of SQLite, and a recognised database expert). You feel that reuse is useless, fine, stop pretending it doesn't exist.

                                    H Offline
                                    H Offline
                                    honey the codewitch
                                    wrote on last edited by
                                    #45

                                    I didn't say reuse is useless. In fact, all I've maintained is that you're wrong in trying to paint C as write once, use anywhere. It's not. Your code still has to interface with other languages and other languages do not in fact speak "extern 'C'" out of the box unless they are C++ I can write code just easily in C++ that exports the exact same way you do in C. But I could just as easily expose something as COM, using some other programming language, and other languages that spoke COM, including C, could use it. There's nothing magic about C. It's yet another language. It doesn't just interface with everything out there.

                                    Real programmers use butterflies

                                    U 1 Reply Last reply
                                    0
                                    • H honey the codewitch

                                      I didn't say reuse is useless. In fact, all I've maintained is that you're wrong in trying to paint C as write once, use anywhere. It's not. Your code still has to interface with other languages and other languages do not in fact speak "extern 'C'" out of the box unless they are C++ I can write code just easily in C++ that exports the exact same way you do in C. But I could just as easily expose something as COM, using some other programming language, and other languages that spoke COM, including C, could use it. There's nothing magic about C. It's yet another language. It doesn't just interface with everything out there.

                                      Real programmers use butterflies

                                      U Offline
                                      U Offline
                                      User 13269747
                                      wrote on last edited by
                                      #46

                                      Quote:

                                      I didn't say reuse is useless. In fact, all I've maintained is that you're wrong in trying to paint C as write once, use anywhere. It's not.

                                      No, all you're done is say that you can port stuff, which is irrelevant.

                                      Quote:

                                      I can write code just easily in C++ that exports the exact same way you do in C.

                                      But I already said that.

                                      Quote:

                                      I was about to write a top level post pondering the overall utility of writing *new* code in C.

                                      Libraries in C++ can be reused by making C-compatible wrappers around functions, not exposing classes, suppressing exceptions, typedefing structs and prefixing all functions with 'extern "C"'. But then you lose a lot of the value of C++.

                                      Except you thought I was talking about porting :-/

                                      Quote:

                                      But I could just as easily expose something as COM, using some other programming language, and other languages that spoke COM, including C, could use it.

                                      I dunno, last I checked COM didn't work on anythe systems I target. You live in an all-windows world, don't you?

                                      Quote:

                                      There's nothing magic about C. It's yet another language. It doesn't just interface with everything out there.

                                      Maybe, but it interfaces to more systems than any other language. Rust is a new possibility that can somewhat do the same thing, but so far it still supports fewer systems than C. A good example of C being foundational in almost all software is the recent trouble over the cryptography library in Python - the dependency (which was in C) was rewritten in Rust, and that broke multiple distributions that did not run on x86/64.

                                      H 1 Reply Last reply
                                      0
                                      • U User 13269747

                                        Quote:

                                        I didn't say reuse is useless. In fact, all I've maintained is that you're wrong in trying to paint C as write once, use anywhere. It's not.

                                        No, all you're done is say that you can port stuff, which is irrelevant.

                                        Quote:

                                        I can write code just easily in C++ that exports the exact same way you do in C.

                                        But I already said that.

                                        Quote:

                                        I was about to write a top level post pondering the overall utility of writing *new* code in C.

                                        Libraries in C++ can be reused by making C-compatible wrappers around functions, not exposing classes, suppressing exceptions, typedefing structs and prefixing all functions with 'extern "C"'. But then you lose a lot of the value of C++.

                                        Except you thought I was talking about porting :-/

                                        Quote:

                                        But I could just as easily expose something as COM, using some other programming language, and other languages that spoke COM, including C, could use it.

                                        I dunno, last I checked COM didn't work on anythe systems I target. You live in an all-windows world, don't you?

                                        Quote:

                                        There's nothing magic about C. It's yet another language. It doesn't just interface with everything out there.

                                        Maybe, but it interfaces to more systems than any other language. Rust is a new possibility that can somewhat do the same thing, but so far it still supports fewer systems than C. A good example of C being foundational in almost all software is the recent trouble over the cryptography library in Python - the dependency (which was in C) was rewritten in Rust, and that broke multiple distributions that did not run on x86/64.

                                        H Offline
                                        H Offline
                                        honey the codewitch
                                        wrote on last edited by
                                        #47

                                        I'm pretty sure I know what I said, but just in case I went back and looked at what I wrote, and indeed what I said was what I said. Since you've reduced yourself to lying about me and what I've said, we're done here. I just don't have the stomach to watch someone get so angry they humiliate themselves like that.

                                        Real programmers use butterflies

                                        U 1 Reply Last reply
                                        0
                                        • H honey the codewitch

                                          I'm pretty sure I know what I said, but just in case I went back and looked at what I wrote, and indeed what I said was what I said. Since you've reduced yourself to lying about me and what I've said, we're done here. I just don't have the stomach to watch someone get so angry they humiliate themselves like that.

                                          Real programmers use butterflies

                                          U Offline
                                          U Offline
                                          User 13269747
                                          wrote on last edited by
                                          #48

                                          Quote:

                                          I'm pretty sure I know what I said, but just in case I went back and looked at what I wrote, and indeed what I said was what I said. Since you've reduced yourself to lying about me and what I've said, we're done here. I just don't have the stomach to watch someone get so angry they humiliate themselves like that.

                                          I quoted what you wrote in my replies to you. You had real trouble understanding that I wasn't talking about porting. You spent a good 4 responses about porting, and for each one I kept saying that I wasn't referring to porting. In your second-last post, when the light finally came on for you, you switched from "It is still work to port" to "well, you still need to write wrappers"; that post indicates that the light finally went on. Nevertheless, the fact remains that unless you want to rewrite (sorry, "port") everything when you switch languages, C is a viable choice for **new** development.

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups