Saturday, March 16, 2019

Digest for comp.lang.c++@googlegroups.com - 15 updates in 3 topics

"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Mar 15 08:20PM -0700

On 3/14/2019 10:12 AM, Bonita Montero wrote:
>> thread will arrive at wait() before the main thread has called
>> notify_one().
 
> That's intended and this might result in a spurious wakeup of a thread.
 
Indeed.
 
> I.e. the wakeup might be consumed by another thread. Because of that
> the flag is checked in a loop to detect this kind of wakeups.
 
Ditto.
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Mar 15 08:23PM -0700

> hangs and the thread never leaves the wait() called? My understanding is that
> wait() should exit immediately upon receiving a notification but this doesn't
> happen.
[...]
 
A condition needs a predicate. Loop on it while waiting on the condvar.
Mutate the predicate under protection of the mutex, signal or broadcast
depending on what your state is designed to do.
 
Fwiw, there are some interesting places where one needs to use broadcast
instead of signal. A signal can go to any thread. A lot of people over
the years really do miss the predicate in the condvar wait. They seem to
mistakenly treat like some sort of event.
 
Imvvho, read the following book several times:
 
https://www.amazon.com/Programming-POSIX-Threads-David-Butenhof/dp/0201633922
 
Then, read it again... ;^)
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 16 01:17PM +0100

On 16.03.2019 04:23, Chris M. Thomasson wrote:
> mistakenly treat like some sort of event.
 
> Imvvho, read the following book several times:
 
> https://www.amazon.com/Programming-POSIX-Threads-David-Butenhof/dp/0201633922
 
I expressed the first program, on page 14 of the 1997 edition, in C++:
 
 
-----------------------------------------------------------------------------
// A C++ version of "alarm.c" on page 14 of "Programming with Posix
threads" 1997.
 
#include <cppx-core/_all_.hpp> //
https://github.com/alf-p-steinbach/cppx-core
$use_std( streambuf, cin, cout, cerr, endl, istream, string, getline, ws );
$use_namespace_names_in( std, chrono, this_thread );
 
void clear( istream& stream )
{
stream.clear();
stream.sync();
streambuf* p_buf = stream.rdbuf();
while( p_buf->in_avail() > 0 ) { p_buf->sbumpc(); }
}
 
auto main()
-> int
{
for( ;; )
{
cout << "Alarm> ";
int n_seconds;
string message;
const bool ok_input = (cin >> n_seconds >> ws and getline( cin,
message ));
if( not ok_input )
{
cerr << "Bad command" << endl;
clear( cin );
continue;
}
this_thread::sleep_for( chrono::seconds( n_seconds ) );
cout << "(" << n_seconds << ") " << message << endl;
}
}
-----------------------------------------------------------------------------
 
 
Not sure if I'm going on with the idea of expressing all those programs
in C++.
 
It may be very slow going.
 
 
Cheers!,
 
- Alf
johnbenny@nowhere.co.uk: Mar 16 12:46PM

On Fri, 15 Mar 2019 18:36:36 +0000
>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);
 
I know.
 
 
> while (!pred()) {
> wait(lock);
> }
 
And that solves what? If its going to spin on a predicate you might just as
well write your own flag based spin loop and not bother with condition
variables in the first place.
Bo Persson <bo@bo-persson.se>: Mar 16 02:08PM +0100


> And that solves what? If its going to spin on a predicate you might just as
> well write your own flag based spin loop and not bother with condition
> variables in the first place.
 
It still waits on the lock, but rechecks the condition when it wakes up.
 
 
Bo Persson
Sam <sam@email-scan.com>: Mar 16 09:22AM -0400

> 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.
 
Should you have to write a long and complicated C++ program to do a
particular task, correctly? Why can't you just #include some header file,
and have everything happen, by magic!
 
> >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
 
So, go ahead and do it. There is no law that says you can't create a pipe,
have one of your threads write to it, and the other one of your threads read
from it.

> about with control variables and mutexes. When data arrives the function
> exits
> whether that data was written before it was entered or after.
 
This is how threads, mutexes, and condition variables work. You can either
use them correctly, or bitch about them on Usenet to anyone who cares. Your
choice. Sometimes life is not fair, and simple things become difficult, or
there are complications. Most people learn that by their late teens.
 
Most people also learn that if they find it difficult to turn a screw by
hand, they can go and get a tool called a "screwdriver". Similarly, there's
a shitload of C++ libraries out there that implement tools to wrap C++
thread primitives into higher-level constructs, that one can use directly.
 
C++ is not a kitchen sink programming language, full of magic buttons one
needs to only push, and have everything happen correctly. The C++ library
provides basic primitives, and one needs to learn how to use them correctly.
C++ never had a reputation for instant gratification, and is the most
complex general purpose programming language in use today.
 
Why there are even libraries out there that implement design patterns that
force you, by contract, to lock a mutex before being able to access a mutex-
protected object, and have the related condition variable notifiable only
when holding a lock on the mutex; and basically make it logically impossible
to use mutexes and condition variables incorrectly.
 
Isn't modern technology great?
Paavo Helde <myfirstname@osa.pri.ee>: Mar 16 03:53PM +0200


> And that solves what? If its going to spin on a predicate you might just as
> well write your own flag based spin loop and not bother with condition
> variables in the first place.
 
You could, but your program would consume 100% CPU with spinning, versus
0% with wait.
 
Why don't you try out different variants by yourself and see how they
behave? You are just banging your head against the wall now.
scott@slp53.sl.home (Scott Lurndal): Mar 16 04:11PM


>And that solves what? If its going to spin on a predicate you might just as
>well write your own flag based spin loop and not bother with condition
>variables in the first place.
 
The difference, of course, is that 'wait' will cause the host operating system
schedulerr to schedule something else on that core/hardware thread (or put it
in a low-power state during the wait). A spin loop both prevents other processes
from getting CPU time as well as burns power.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 16 08:38PM

On Sat, 16 Mar 2019 12:46:24 +0000 (UTC)
 
> And that solves what? If its going to spin on a predicate you might just as
> well write your own flag based spin loop and not bother with condition
> variables in the first place.
 
You completely misunderstand this I am afraid.
 
First, you need to check when you begin the wait whether the condition
is already fulfilled, so you require as a minimum an if statement.
That was your original coding mistake. Secondly, in a perfect world,
having an if block would be enough, but it is specifically documented
by both POSIX and C++11 that a condition variable may spuriously wake
up for efficiency of implementation reasons. It happens very rarely,
but it can happen. So you use a while loop.
 
The while loop does not imply spinning as you seem to think.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 16 08:50PM

On Sat, 16 Mar 2019 20:38:09 +0000
Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
[snip]
> by both POSIX and C++11 that a condition variable may spuriously wake
> up for efficiency of implementation reasons. It happens very rarely,
> but it can happen. So you use a while loop.
 
Add to this that it is also documented that signalling a condition
variable may wake up more than one thread - so you need a while loop
for that reason also if more than one thread may be waiting on the
variable. (And a broadcast is also obliged to wake up all threads
waiting on the condition variable, irrespective of whether the
condition is satisfied for all the waiting threads.)
 
David Brown <david.brown@hesbynett.no>: Mar 16 01:19PM +0100

On 15/03/2019 16:50, Peabody wrote:
> 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.
 
There is no problem with having Python installed on the user's machines.
If they have Linux, they have Python. If they have Windows, you can
build an exe file with all the bits of Python that are needed. (That
exe file is going to be massively bigger than a C++ sourced exe file -
but do you really care about that?)
 
You don't even need to touch a line of Python code normally - the tools
already handle many use-cases.
 
<https://pypi.org/project/python-msp430-tools/>
 
There are other ready-made tools and libraries on TI's website (not just
the Python ones):
 
<http://www.ti.com/tool/MSPBSL>
 
 
The point is, don't try to program this stuff yourself unless you really
have to. Use existing programs.
 
 
> 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.
 
The Python solution has been working fine for developers and end-users
for long before TI thought it might be an idea to release programs
themselves.
 
Don't get me wrong here - the Python tools are not the only way to do
this, and Python is not necessarily the best solution for all BSL cases.
I simply want you to think more clearly about the situation. Don't
think "I know a little bit of C, therefore the C++ code is the way to
go". Don't think "I don't know much about Python, I can't use it".
Don't think about the limitations you are imagining, but think of a wide
variety of possible solutions before deciding. If you end up using the
C++ code, do so because you have worked through this and seen C++ as the
shortest route to your goals.
Peabody <waybackNO584SPAM44@yahoo.com>: Mar 16 09:18AM -0500

David Brown says...
 
> normally - the tools already handle many use-cases.
 
> There are other ready-made tools and libraries on TI's
> website (not just the Python ones):
 
I've looked through TI's stuff more than once, and there's
nothing there that addresses the problem. This comes up
repeatedly on the TI forum - Can I flash firmware to an F4xx
(or any of the newer parts) using an FT232 USB-to-UART
adapter with TI's Windows flashing software? Not an
unreasonable question.
 
And the answer from TI is always - No, we don't support
that. You'll need to use an MSP-FET [$115] or a "Rocket"
[$15]. A generic USB adapter [$1.20] won't work.
 
As I see it, the problem is really very simple. I don't
need to write a new program. TI has already written and
made available, with source code, software that works
perfectly, so long as you use their proprietary and
expensive hardware interface. Of course there are other
solutions, such as writing your own BSL for the chip. And as
you say, a Python solution may exist. But it just seems
that the obvious solution is to take TI's source code and
make a few minor changes, then recompile, and then it *WILL*
work with those adapters.
 
I've already done this for the older parts that use BSLDEMO.
It was literally just adding options to invert the polarity
of DTR and RTS. But that was a simple program, written in
C, and I was able to use LCC-Win32 to compile it with a
fairly short learning curve. No BOOST involved.
 
But BSL-Scripter for the newer parts is more difficult. The
code changes are not really the problem. I think I now
understand the functions that change the state of DTR and
RTS, and last night I finished the changes I needed to add
the option to generate the hardware invoke pattern. It's
just a few lines in four of the 57 source code files. The
problem now is in compiling it.
 
Here's what I'm up against:
 
https://github.com/drcrane/bslscripter-windows
 
I read through the README, and I just have no idea what it
means. The is not LCC, and I don't do this stuff for a
living. I don't have Visual C++, Boost, or any of the other
libraries, nor do I have any idea of how all this works. I
was hoping the process would be less obscure, but I would
spend days, or more likely weeks, learning how all this
works - just to get the existing code to compile, and I
really don't want to do that just for this, particularly
with no prospect of ever needing to use it again.
 
So maybe the guy who did the repo will compile my changes
for me, but if not, I will probably drop it. If there's an
existing Python solution, people can use that with no input
from me. And there's always a chance that TI will do the
right thing and make this change themselves, which of course
is what really should happen, and which I've asked them to
do.
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Mar 16 02:10PM -0600

On Sat, 16 Mar 2019 09:18:46 -0500, Peabody
>right thing and make this change themselves, which of course
>is what really should happen, and which I've asked them to
>do.
 
There are TI product forums: https://e2e.ti.com/support/
 
Maybe someone on one of those has built the tool.
 
Louis
wyniijj@gmail.com: Mar 15 09:49PM -0700

I'm trying implementing a fixed-size matrix class. But before that,
I should implement a fixed size 'vector' class template.
From the very begining of the impl., I feel copy ctor and linitializer_list
ctor are somewhat inefficient because they use loop instead of direct
element-wise copy which I thought might be possible(or not? because C array
is not assignable). Do I have to do it this way?
 
template<typename T, size_t N>
class Vect {
T m_arr[N];
 
public:
Vect() {};
Vect(const Vect& s) {
for(size_t i=0; i<N; ++i) {
m_arr[i]=s.m_arr[i];
}
};
Vect(std::initializer_list<T> s) {
T* wptr=m_arr;
for(const T* iptr=s.begin(); iptr<s.end(); ++iptr) {
*wptr=*iptr; ++wptr;
}
};
 
Vect& operator=(const Vect& s) { /*same as ctor */ };
Vect& operator=(std::initializer_list<T> s) { /*same as cotr*/ };
};
 
E.g.
Vect<float,3> arr{1,2,3},arr2(arr);
arr={3,4,5}; // assignment has the same efficiency issue
arr=arr2;
 
The second problem is when T is integer type or float type, can I use
memcpy from the argument s?
 
E.g.
Vect(const Vect& s) {
memcpy(m_arr,s.m_arr,sizeof(m_arr));
};
Vect(std::initializer_list<T> s) {
memcpy(m_arr,s.begin,sizeof(m_arr));
};
Juha Nieminen <nospam@thanks.invalid>: Mar 16 05:04PM

> because C array is not assignable
 
If you want an assignable C-style static array, use std::array.
(It has all the same characteristics as a "raw" array, except
that it's directly copyable and assignable.)
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
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: