From: Joe on
I have a function defined as void foo(int* pIn, int* pOut). The function
gets some data via pointer pIn and calculates some output data which is
written to the array pointed to by pOut. In the calculation of the output,
some local variables defined in foo are used.

If I have two or more threads executing and these threads use foo, are there
any risks
that something might go wrong; like the output being screwed up and
deviating from what is expected?

Thanks


From: Ben Bacarisse on
"Joe" <Joe(a)NoSpammers.Com> writes:

> I have a function defined as void foo(int* pIn, int* pOut). The
> function gets some data via pointer pIn and calculates some output
> data which is written to the array pointed to by pOut. In the
> calculation of the output, some local variables defined in foo are
> used.
>
> If I have two or more threads executing and these threads use foo, are
> there any risks that something might go wrong; like the output being
> screwed up and deviating from what is expected?

Most definitely. For example, if two concurrent calls to foo in
different threads have output arrays that overlap (or an input array
overlapping an output array).

You might find comp.programming.threads to be more suitable as your
design gets more detailed.

--
Ben.
From: Joe on

>
>> I have a function defined as void foo(int* pIn, int* pOut). The
>> function gets some data via pointer pIn and calculates some output
>> data which is written to the array pointed to by pOut. In the
>> calculation of the output, some local variables defined in foo are
>> used.
>>
>> If I have two or more threads executing and these threads use foo, are
>> there any risks that something might go wrong; like the output being
>> screwed up and deviating from what is expected?
> Joe


> Most definitely. For example, if two concurrent calls to foo in
> different threads have output arrays that overlap (or an input array
> overlapping an output array).
>
> You might find comp.programming.threads to be more suitable as your
> design gets more detailed.
>
> --
> Ben.



Ok, maybe I should have been more specific. The assumption here is
that pIn and pOut are pointing to arrays which are not overlapped by
any other arrays. And just to clarify, foo() does not use any global
variables.

For example:

In thread #1 two local buffers are defined and the thread calls foo with
pIn pointing to one of the local buffers; and pOut pointing to the other
local buffer.

In thread #2 two local buffers are defined and the thread calls foo with
pIn pointing to one of the local buffers; and pOut pointing to the other
local buffer.

So to iterate my question and based on the above-mentioned assumption:

If I have two or more threads executing and these threads use foo, are
there any risks that something might go wrong; like the output being
screwed up and deviating from what is expected?



From: Daniel Pitts on
On 6/2/2010 8:47 AM, Joe wrote:
> I have a function defined as void foo(int* pIn, int* pOut). The function
> gets some data via pointer pIn and calculates some output data which is
> written to the array pointed to by pOut. In the calculation of the
> output, some local variables defined in foo are used.
>
> If I have two or more threads executing and these threads use foo, are
> there any risks
> that something might go wrong; like the output being screwed up and
> deviating from what is expected?
The danger exists only you use static data, or if pIn/pOut of one
invocation overlap with pIn or pOut of another (in which case, which
thread's input/output wins over whose).

If you know that none of the pIn and pOut are ever overlapping, and you
know that you aren't using global data, you should be fine.

For example, strtok actually uses a static variable to keep track of
state, so it is *not* thread-safe. strcpy on the other hand, is
(assuming you're not passing in shared char *'s)

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: robertwessel2 on
On Jun 2, 12:23 pm, Daniel Pitts
<newsgroup.spamfil...(a)virtualinfinity.net> wrote:
> The danger exists only you use static data, or if pIn/pOut of one
> invocation overlap with pIn or pOut of another (in which case, which
> thread's input/output wins over whose).


Just to expand on that a bit, if the pIn and pOut areas are adjacent,
or nearly so, you can run into an unexpected form of overlap because
the compiler may implement operations on (say) bytes using word sized
operations. That's called word tearing.

For example, let's say two pOut areas are allocated as part of the
same larger array of bytes. pOut1 uses positions 3-10, and pOut2 uses
positions 11-20. Your implementation may use (or even require*)
aligned word sized accesses to memory, which are then processed to
simulate byte sized accesses. So assuming that the parent array is
aligned, and the word size is four bytes, when one thread executes
pOut1[8] = 'x', the compiler may generate a load of four bytes from
positions 8-11 of the parent array, a modification of that word to
insert the 'x' into the third position, and then a store of four bytes
back to 8-11. Simultaneously another thread executing pOut2[0] = 'y'
can execute a load/modify/store sequence against those *same* four
bytes (but modifying only the fourth position of that word), which
obviously leads to a potential lost update.

Basically you need to ensure that your objects not only don't overlap,
but are not near enough (and that's dependent on alignment too) to
each other that word tearing will not occur. Exactly what that
requirement is, is quite implementation dependent, but the alignment
and separation of objects returned by malloc is usually sufficient.
IOW, two objects allocated by malloc will usually be safe, but if
you're processing two parts of the same object simultaneously, you may
have to consider word tearing.


*For example, some machines, like early Alpha's or some DSPs, don't
have *any* memory access instructions other than aligned word wide
accesses.