|
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
|
|
|
|
|
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.
|
|
|
|
|
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
|
|
|
|
|
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.
|
|
|
|
|
I honestly don't know which one to react with, so
Most schedulers lack self-control and need to be disciplined!
|
|
|
|
|
honey the codewitch wrote: I propose that it is also meta-nondeterministic: You can not even count on it to be non-deterministic
I'd say they are non-deterministically deterministic...
|
|
|
|
|
If I understand the docs[^] correctly, FreeRTOS is quite limited with regard to multi-core support. I am certainly no FreeRTOS expert, but the docs seems to say that it can multi task using a single core well enough, but if you want to use multiple cores you in for some serious programming …
Since you have been writing quite a bit about it lately, I was starting to get interested in the thing - a nice tiny core with SMP support would certainly interesting. Are you actually getting true concurrency with the thing, or is the scheduler just using one core at a time? That could certainly explain the deterministic behavior.
Espen Harlinn
Senior Architect - Ulriken Consulting AS
The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.Edsger W.Dijkstra
|
|
|
|
|
I don't know if it's any kind of true or at least standardized SMP which is why I put it in quotes, but as long as it's compiled with it there are options like xTaskCreatePinnedToCore(). That said, I don't see them in that documentation. It appears that the documentation there might be out of date.
I can't profile it to determine what cores are really being utilized because while there are options where you can compile in profiling features like that, they are disabled for the ESP-IDF build, which is what I'm currently using, given my ESP_WROVER_KIT is sort of dependent on ESP-IDF, and I don't have say, an ARM based monster with JTAG debugging in the alternative. I'm left sort of having to trust the little OS more than I'd like.
That was one of the reasons I was hoping I'd get better results with this sample.
I *do* think it's using both cores based on my ability to create an idle priority thread on the second core and get spew back from it even when i spin a loop on the main core (causing the main core's idle thread to be starved), but I don't know how well it schedules, and I almost doubt it knows well enough to round robin threads across all cores. I'm not even sure offhand how to get the core count, and if I try to do the creation call pinned to a core that doesn't exist it crashes.
I *am* getting true concurrency from the looks of it. It's just badly scheduled concurrency. We'll see how it bakes out when I start doing I/O heavy stuff with it, because that's really where you'd want to use this library anyway.
I'm about to release a new article that builds on the stuff i recently wrote, only (hopefully) not specific to the ESP32 this time, and has more stuff like threads and thread pooling added to it.
Real programmers use butterflies
|
|
|
|
|
Quote: I am getting true concurrency from the looks of it.
Cool
Quote: I'm about to release a new article that builds on the stuff i recently wrote, only (hopefully) not specific to the ESP32 this time, and has more stuff like threads and thread pooling added to it
I'll read it with great interest
Espen Harlinn
Senior Architect - Ulriken Consulting AS
The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.Edsger W.Dijkstra
|
|
|
|
|
|
Quote: Here's that article.
Thanks, I will read it
Espen Harlinn
Senior Architect - Ulriken Consulting AS
The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.Edsger W.Dijkstra
|
|
|
|
|
Espen Harlinn wrote: If I understand the docs[^] correctly, FreeRTOS is quite limited with regard to multi-core support
ESP32 uses a modified version of FreeRTOS[^] with added symmetric multiprocessing support.
|
|
|
|
|
Oh, is that what that is?
I better put some conditional compiles in my code.
Real programmers use butterflies
|
|
|
|
|
Look up "lock convoying". It's a well-known problem with lock-based multithreading.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
I'm not explicitly using locks in my own test code, though I did notice that Serial.println() appears to be atomic.
Real programmers use butterflies
|
|
|
|
|
You may find that other parts of the O/S use locks.
For example, I/O in blocks larger than the maximum supported by the hardware may be divided into blocks which are serialised using some sort of queue or lock. It's not the way you'do do it in Windows or Linux, but it works.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
Yeah. That's what I was implying when I said Serial.print/println seemed atomic - other stuff locks.
Real programmers use butterflies
|
|
|
|
|
Use the overload that let's you specify a bool to indicate whether execution should be non-deterministic (default is false)
|
|
|
|
|
This is the predictability equivalent of a "Heisenbug".
|
|
|
|
|
How could instructions be non-deterministic when they share the same clock (even on different cores) ? Even random numbers generators are determinitic. I think that the only way to introduce some "chance" in a piece of code is to get information from "outside" : wait for something from a mechanical disk, a keyboard, an other computer...
|
|
|
|
|
I'm writing to an external serial port, and it waits for the writes to complete. That should give it some amount of non-determinism.
Real programmers use butterflies
|
|
|
|
|
Just remember the following and you'll do fine with multi-threading:
Variables and constants aren't.
|
|
|
|
|
I'm an admittedly rookie programmer who hasn't done much with multithreading. But wouldn't a Real Time Operating system always do things in the same order? Much like a processor on a PLC? I'm here to learn, so if you have the time to answer that would be great.
|
|
|
|
|
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
|
|
|
|
|