- Need help understanding code segment - 6 Updates
- C++ condition variable confusion - 12 Updates
- Need help understanding code segment - 2 Updates
- binary tree: how did you learn it? - 1 Update
- Available C++ Libraries FAQ - 1 Update
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Mar 14 05:45PM -0600 On Thu, 14 Mar 2019 18:15:02 -0500, Peabody > return error; > }; >}; I haven't got a clue, but you might want to look at these: https://www.boost.org/doc/libs/1_69_0/boost/asio/serial_port_base.hpp https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_dcb You might want to search the code for "fDtrControl". Louis |
Paavo Helde <myfirstname@osa.pri.ee>: Mar 15 07:55AM +0200 On 15.03.2019 1:15, Peabody wrote: > I believe is ENABLED, so I think that means initState is zero. But I don't > know where that comes from. Also, I don't know what calls all this stuff. > Any clarifications will be appreciated. This code just saves and reads a single integer, it does not do anything substantial. 'initState' is the name of a local parameter, it's natural it does not show up elsewhere. If TESTControl doesn't either, then it's possible it is just some mockup class used only for testing purposes and is not a part of the real program. |
David Brown <david.brown@hesbynett.no>: Mar 15 01:03PM +0100 On 15/03/2019 00:15, Peabody wrote: > lines low when it runs. I would like to at least get it to leave DTR high, > or if possible actually generate the pattern itself so a generic USB-to- > Serial adapter can be used as the hardware interface. Let's take a step back, and ask what you are actually trying to achieve. If you are trying to program msp430 microcontrollers using the BSL, then fiddling with this C++ code when you don't know any C++ is almost certainly the most difficult way to do it. There are several existing solutions for working with the BSL - in particular, there are libraries and programs in Python for the job. If you don't know Python, and you don't know C++, then you'll get further faster by starting with the Python code than with the C++ code. |
Peabody <waybackNO584SPAM44@yahoo.com>: Mar 15 10:50AM -0500 David Brown says... > for the job. If you don't know Python, and you don't > know C++, then you'll get further faster by starting > with the Python code than with the C++ code. That's a fair point, and I may be approaching this wrong. But the idea is to have a way to flash firmware updates in the field, so that people who don't know anything about electronics, and don't have Python installed on their computers, can update firmware with a USB cable and a cheap USB adapter, or possibly just the cable since the adapter can be embedded on the project's board as in Arduinos. I've modified the BSLDEMO program used to flash older MSP430 parts so they can now be flashed with a generic adapter, and I just wanted to do the same for the newer parts that use BSL-Scripter. Of course TI should be doing this, and I've suggested as much to them, but to no avail so far. The benefit of modifying Scripter is that the ultimate user only needs one file to do the updates, in addition to installing the adapter's VCP driver if it's not already included in their OS. I'm just not sure a Python solution works as well for the general public. |
Peabody <waybackNO584SPAM44@yahoo.com>: Mar 15 11:29AM -0500 Paavo Helde says... > This code just saves and reads a single integer, it does > not do anything substantial. I found this thread going back to 2010. The third post contains code that looks very similar to what I'm working with, and the author says it works fine. So while I don't understand it, it appears that this code lets you change the state of the RTS line. And similarly for DTR. http://boost.2283326.n4.nabble.com/get-set-RTS-on-serial-port-td2598718.html > If TESTControl doesn't either, then it's possible it is > just some mockup class used only for testing purposes > and is not a part of the real program. I understand now about initState. But if TESTControl isn't called from anywhere in the source, then something else is causing DTR and RTS to be brought low. Perhaps that's just the way Boost opens serial ports if FlowControl is None. In any case, it also seems that my changes could simply call TESTControl and RESETControl with the appropriate argument to change the state of these lines. |
James Moe <jimoeDESPAM@sohnen-moe.com>: Mar 15 12:50PM -0700 On 14/03/2019 4.15 PM, Peabody wrote: > I don't know anything about BOOST. It appears that something called > "initState" is key to what's going on here, [...] Not really. "TESTControl(uint16_t initState)" offers a way to initialize the internal variable "state" when an instance of TESTControl is created. I note there is no default constructor; "state" would then be undefined. Since you cannot find an instance of TESTControl, I would assume it is unused. -- James Moe jmm-list at sohnen-moe dot com Think. |
Paavo Helde <myfirstname@osa.pri.ee>: Mar 14 08:48PM +0200 >> That's why you check for the flag also *before* the waiting. > I don't think this will work. It still does not guarantee that the child > thread will arrive at wait() before the main thread has called notify_one(). That's true, but this guarantee is not needed for anything. If the flag is already raised when the thread first comes around to lock the mutex, then it will know it has been already notified, and will not call wait() at all. Maybe you are thinking that thread synchronizations can be done by notify() and wait() only. Nope, for reliable synchronization you need the share a data state and communicate the data state (a single bit flag in this simple example). Mutexes, notifications and waits are just helpers for making this data sharing fast and reliable. |
johnbenny@nowhere.co.uk: Mar 15 09:58AM On Thu, 14 Mar 2019 20:48:35 +0200 >the share a data state and communicate the data state (a single bit flag >in this simple example). Mutexes, notifications and waits are just >helpers for making this data sharing fast and reliable. Fair enough, but given that you can reliably synchronise seperate processes using signals and/or IPC only it seems a pity the same can't be done with threads just using system calls instead of having to rely on polling flags too. |
Sam <sam@email-scan.com>: Mar 15 07:09AM -0400 > using signals and/or IPC only it seems a pity the same can't be done with > threads just using system calls instead of having to rely on polling flags > too. Signals are not thread safe. Apples and oranges. And you'll be surprised to learn that IPC works in exactly the same way: use an internal shared state variable, and the same mutexes and condition variables to coordinate the activity between the threads. If you really wish to call a single function to notify a thread, and another function to wait for a notification, there is no law that says you can't. Your first function simply has to a lock the mutex, increment a counter variable, signal a condition variable, and return (and unlock the mutex). Your second function has to lock the mutex, check if the shared counter is 0, and if so wait for the condition variable and go back to the previous step; and when the shared counter is not 0, reset it back to 0 and return the number of times it's been signaled (also after unlocking the mutex). Abra-cadabra! Presenting: a single function for notifying a thread, and a single function to reliably wait for the notification, if it hasn't been already, and if the thread's already been notified, it returns the number of times it's been notified. Now, you can feel free to pretend that's how threads get notified in your entire application. |
"Öö Tiib" <ootiib@hot.ee>: Mar 15 05:44AM -0700 > using signals and/or IPC only it seems a pity the same can't be done with > threads just using system calls instead of having to rely on polling flags > too. What you mean by IPC? It usually means things like message queues, sockets and/or pipes. These work great with threads as well. Basically it is possible that such (thread safe) message queues (pipe can be viewed as one to one message queue and socket as two pipes in opposite directions) to be the only way to transfer data between threads. No data has to be shared otherwise. It simplifies lot of things and we can use condition variable for building such thread safe message queues but it is not working like message queue on its own (like your OP code seemed to expect). |
Paavo Helde <myfirstname@osa.pri.ee>: Mar 15 03:09PM +0200 >> helpers for making this data sharing fast and reliable. > Fair enough, but given that you can reliably synchronise seperate processes > using signals and/or IPC only I'm not so familiar with signals, but isn't it so that in a single-threaded app a typical (non-fatal) signal handler sets a *flag* which is periodically *polled* by the main app? Also, when starting up a new process, how do you know how long you have to wait for it to set up the signal handlers, before you can send signals to it? Seems a harder problem to me with processes than with threads. > it seems a pity the same can't be done with > threads just using system calls instead of having to rely on polling flags > too. Wait+notify is usually not called polling; instead, it is a mechanism to avoid polling. It's also important what it is not: it is not a mechanism for encoding the program state, the program state is still best encoded by data variables. So when one receives a notification one has to go and study the program state to decide what to do next. For example, you complained that std::condition_variable notifications are not queued. Queuing a notification would not be so useful as there may be several different notifications in general and one would not know which notifications exactly are in the queue, not to speak about spurious wake-ups which would look like ghost notifications. Instead, in C++ you can easily build your own inter-thread queue, holding custom notification aka event objects, potentially containing tons of attached data. Such a queue can be built e.g. by using a std::deque object, a mutex and a condition variable. The deque would constitute the shared data state which I'm talking about all the time. As usual, the C++ core language gives you the tools to build things, not ready-made solutions. The notify mechanism is intentionally minimal (notifications can be lost or appear from a thin air, no data attached to the notifications, etc.) in order to not get in the way of implementing solutions on top of it. |
"Öö Tiib" <ootiib@hot.ee>: Mar 15 06:34AM -0700 On Friday, 15 March 2019 15:10:12 UTC+2, Paavo Helde wrote: > I'm not so familiar with signals, but isn't it so that in a > single-threaded app a typical (non-fatal) signal handler sets a *flag* > which is periodically *polled* by the main app? From https://en.wikipedia.org/wiki/Signal_(IPC) "When a signal is sent, the operating system interrupts the target process' normal flow of execution to deliver the signal. Execution can be interrupted during any non-atomic instruction. If the process has previously registered a signal handler, that routine is executed. Otherwise, the default signal handler is executed." |
Bonita Montero <Bonita.Montero@gmail.com>: Mar 15 02:35PM +0100 > using signals and/or IPC only it seems a pity the same can't be done with > threads just using system calls instead of having to rely on polling flags > too. Thread-synchronization with condition-variables in the manner you've been presented here is usually magnitudes more efficient than relying only on kernel-facilities. The downside of the usual condition-variables in this way is just that there might be spurious or stolen wakeups; but this happens not very often. |
scott@slp53.sl.home (Scott Lurndal): Mar 15 01:36PM >using signals and/or IPC only it seems a pity the same can't be done with >threads just using system calls instead of having to rely on polling flags >too. Perhaps you should instead investigate using sem_post(2)/sem_wait(2)? |
scott@slp53.sl.home (Scott Lurndal): Mar 15 02:32PM > interrupted during any non-atomic instruction. If the process has previously > registered a signal handler, that routine is executed. Otherwise, the > default signal handler is executed." And "deliver the signal" means run the registered (signal(2) or sigaction(2)) handler. Which often sets a flag that is polled by the app main loop. |
johnbenny@nowhere.co.uk: Mar 15 04:17PM On Fri, 15 Mar 2019 05:44:01 -0700 (PDT) >> too. >What you mean by IPC? It usually means things like message queues, sockets >and/or pipes. These work great with threads as well. They do, but using them means you get the extra complexity of their API without the safety that seperate processes provide. |
johnbenny@nowhere.co.uk: Mar 15 04:24PM On Fri, 15 Mar 2019 07:09:03 -0400 >learn that IPC works in exactly the same way: use an internal shared state >variable, and the same mutexes and condition variables to coordinate the >activity between the threads. How a subsystem works internally is irrelevant , its what the application programmer has to do that matters. >If you really wish to call a single function to notify a thread, and another >function to wait for a notification, there is no law that says you can't. Sure, but should I have to? If I write data to a pipe or a message queue or a socket it doesn't vanish into a black hole if the receiver doesn't immediately read from it. It stays there until a read occurs so avoiding data loss and race conditions. I don't see why the thread notify can't be the same. >already, and if the thread's already been notified, it returns the number of >times it's been notified. Now, you can feel free to pretend that's how >threads get notified in your entire application. Meanwhile with socket & pipe based IPC I can just sit in a select(). No faffing about with control variables and mutexes. When data arrives the function exits whether that data was written before it was entered or after. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 15 06:36PM On Thu, 14 Mar 2019 12:45:51 +0000 (UTC) > variable is subject to race conditions and so is calling sleep() unless you > set it to sleep for 10 seconds or something to be absolutely sure the thread > has reached wait()? You have received a number of answers about how to correct your code with a while loop and a flag. However, you might care to note that C++11 comes with a convenience overload for std::condition_variable::wait() which takes a predicate and so avoids the need to code your own while loop, namely: void wait(std::unique_lock<std::mutex>& lock, Predicate pred); This: wait(lock, pred) is equivalent to: while (!pred()) { wait(lock); } Condition variables are called "condition" variables for a reason, which is that they require a predicate. Your code failed to provide one. |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 14 11:37PM >I don't know anything about BOOST. It appears that something called >"initState" is key to what's going on here, but I don't find that in any >other source code file, or any occurrence of "TESTControl" either. "initState" is a parameter whose scope is just the above constructor body. Often, one cannot "just quickly" understand and modify a C++ program without having properly learned C++. |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 15 11:45AM >>other source code file, or any occurrence of "TESTControl" either. >"initState" is a parameter whose scope is just the above >constructor body. Of course, such an initialization in the body might give away that the author has not received special C++ education because otherwise he would have used a member initialization list! |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Mar 15 08:28AM +0100 Am 10.03.19 um 09:17 schrieb Jorgen Grahn: >> I'm interested in is firstly: how did you learn to program a binary >> tree in C++? Specifically, what implementation were you taught? > I never did. Same here. I took a short look at the concept and decided that overhead of /binary/ trees is by far too high and probably never used them anymore. This applies to all kinds ob binary trees like R-B trees or AVL. I prefer B-Trees, or for certain applications maybe a Trie. > In C++ I've never needed anything that the standard containers > couldn't give me, e.g. the features of a search tree exposed by > std::map, or the std::make_heap stuff if that counts. From my point of view a B-Tree is missing in C++ (and many other languages). I closed this gap at least in C++, Java and C# projects. Marcel |
Nikki Locke <nikki@trumphurst.com>: Mar 14 11:23PM Available C++ Libraries FAQ URL: http://www.trumphurst.com/cpplibs/ This is a searchable list of libraries and utilities (both free and commercial) available to C++ programmers. If you know of a library which is not in the list, why not fill in the form at http://www.trumphurst.com/cpplibs/cppsub.php Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment