Prev: Free Live Voice and Video Chat!Connect with Over 4 Million Members download now
Next: high dimensional index structures for arbitrary distance/similarity functions (text mining)
From: Joe on 2 Jun 2010 11:47 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 2 Jun 2010 12:33 "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 2 Jun 2010 13:38 > >> 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 2 Jun 2010 13:23 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 2 Jun 2010 15:26
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. |