Re: [fpc-devel] volatile variables

2011-06-30 Thread Michael Schnell

On 06/29/2011 05:47 PM, Jonas Maebe wrote:

...


Thanks for the multiple pointers.

I was just trying to construct an example that

(a) is similar to stuff an normal user might think would be sure to work and
(b) if the cache-sync problems really exist in the way discussed is 
likely to fail on an SMP-machine so that it makes sense to do a test.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Hans-Peter Diettrich

Vinzent Höfler schrieb:

Question is, what makes one variable use read/write-through, while 
other variables can be read from the cache, with lazy-write?

 Synchronisation. Memory barriers. That's what they are for.


And this doesn't happen out of thin air. How else?


Ok, maybe I misunderstood your question. Normally, these days every
memory access is cached (and that's of course independent from compiler
optimizations).


This should be normal (speedy) behaviour.


But there are usually possibilities to define certain areas as
write-through (like the video frame buffer). But that's more a chip-set
thing than it has anything to do with concurrent programming.


I also thought about cache or page attributes (CONST vs. DATA sections), 
but these IMO don't offer the fine granularity, that would allow to 
separate synchronized from unsynchronized variables (class/record 
members!) in code. Even the memory manager would have to deal with two 
classes of un/synced memory then :-(



Apart from that you have to use the appropiate CPU instructions.


Seems to be the only solution.

Is this a compiler requirement, which has to enforce 
read/write-through for all volatile variables?

 No.  volatile (at least in C) does not mean that.


Can you provide a positive answer instead?


Ada2005 RM:

|C.6(16): For a volatile object all reads and updates of the object as
| a whole are performed directly to memory.
|C.6(20): The external effect [...] is defined to include each read and
| update of a volatile or atomic object. The implementation shall
| not generate any memory reads or updates of atomic or volatile
| objects other than those specified by the program.

That's Ada's definition of volatile. C's definition is less stronger, but
should basically have the same effect.

Is that positive enough for you? ;)


Much better ;-)

But what would this mean to FPC code in general (do we *need* such 
attributes?), and what will be their speed impact? This obviously 
depends on the effects of the specific synchronizing instructions, 
inserted by the compiler.



But if so, which variables (class fields...) can ever be treated as 
non-volatile, when they can be used from threads other than the main 
thread?

 Without explicit synchronisation? Actually, none.


Do you understand the implication of your answer?


I hope so. :)

When it's up to every coder, to insert explicit synchronization 
whenever required, how to determine the places where explicit code is 
required?


By careful analysis. Although there may exist tools which detect 
potentially

un-synchronised accesses to shared variables, there will be no tool that
inserts synchronisation code automatically for you.


I wouldn't like such tools, except the compiler itself :-(

Consider the shareable bi-linked list, where insertion requires code 
like this:

  list.Lock; //prevent concurrent access
  ... //determine affected list elements
  new.prev := prev; //prev must be guaranteed to be valid
  new.next := next;
  prev.next := new;
  next.prev := new;
  list.Unlock;
What can we expect from the Lock method/instruction - what kind of 
synchronizaton (memory barrier) can, will or should it provide?


My understanding of a *full* cache synchronization would slow down not 
only the current core and cache, but also all other caches?


If so, would it help to enclose above instructions in e.g.
  Synchronized begin
update the links...
  end;
so that the compiler can make all memory references (at least reads) 
occur read/write-through, inside such a code block? Eventually a global 
cache sync can be inserted on exit from such a block.


After these considerations I'd understand that using Interlocked 
instructions in the code would ensure such read/write-through, but 
merely as a side effect - they also lock the bus for every instruction, 
what's not required when concurrent access has been excluded by other 
means before.



Conclusion:

We need a documentation of the FPC specific means of cache 
synchronization, with their guaranteed effects on every target[1].


Furthermore we need concrete examples[2], how (to what extent) it's 
required to use these special instructions/procedures, in examples like 
above. When cache synchronization is a big issue, then the usage of 
related (thread-unaware) objects should be discussed as well, i.e. how 
to ensure that their use will cause no trouble, e.g. by invalidating the 
entire cache before.


[1] When the effects of the primitíves vary amongst targets, then 
either more specific documentation is required, or higher level 
target-insensitive procedures with a guaranteed behaviour. Eventually 
both, so that the experienced coder can use conditional code for the 
different handling on various targets.


[2] References to e.g. C code samples IMO is inappropriate, because the 
user cannot know what special handling such a different compiler will 
apply to its compiled code (see volatile).


DoDi


Re: [fpc-devel] volatile variables

2011-06-30 Thread Michael Schnell

On 06/29/2011 09:00 PM, Vinzent Höfler wrote:


POSIX: pthread_mutex_(un)lock()  Co.

Or, maybe I didn't understand the question...


I suppose, you did understand what I intended to say.

Regarding FPC, TCriticalSection is a decent encapsulation for 
pthread_mutex_... when used in this way.


But e.g. if you use a TThreadList instance myList with multiple 
threads it can't be the way to go to include any occurrence of 
myList.xxx by a critical section just to make sure that the cache 
synchronization has happened and the instance variable itself in fact is 
valid.


Moreover I don't think it can be the way to go to enforce the 
application programmer to plan his software in a way that somehow else 
he needs to make sure that such an instance variable arrives in the 
appropriate CPU's cache.


So I do hope that the constructors of the hardware, the OS and the 
libraries already somehow did take care of this issue O:-) ,


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Michael Schnell

On 06/29/2011 09:44 PM, Vinzent Höfler wrote:

On Wed, 29 Jun 2011 13:28:20 +0200, Hans-Peter Diettrich

Ada2005 RM:

|C.6(16): For a volatile object all reads and updates of the object as
| a whole are performed directly to memory.
|C.6(20): The external effect [...] is defined to include each read and
| update of a volatile or atomic object. The implementation shall
| not generate any memory reads or updates of atomic or volatile
| objects other than those specified by the program.

That's Ada's definition of volatile. C's definition is less 
stronger, but

should basically have the same effect.

Nice and what is the FPC definition ?

Thanks,
-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Nikolai Zhubr

30.06.2011 13:31, Hans-Peter Diettrich:

If so, would it help to enclose above instructions in e.g.
Synchronized begin
update the links...
end;
If by such hypothetical synchronized operator you mean just memory 
barriers and nothing else, then AFAICS this would not be of much use in 
practice, because in case of strictly one thread barriers are unneeded 
anyway, and in case of 2 or more threads barriers are typically 
insufficient (because most of the time threads would also need race 
protection, which is not provided by barriers alone).
If what you mean here is rather a full-blown critical section with just 
some more elegant and generic syntax (i.e. a replacement of 
EnterCriticalSection/LeaveCriticalSection a la java), then yes, it might 
be nice, but mostly aesthetic-wise.


Nikolai
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Jonas Maebe


On 30 Jun 2011, at 10:42, Michael Schnell wrote:


On 06/29/2011 09:44 PM, Vinzent Höfler wrote:
That's Ada's definition of volatile. C's definition is less  
stronger, but

should basically have the same effect.

Nice and what is the FPC definition ?


There is none. FPC has a volatile modifier in svn trunk, but it  
currently only affects the node tree optimizer. There are many other  
parts of the compiler that completely ignore it (from the inliner to  
the i386 assembler peephole optimizer), and hence it is probably not  
that useful in its current incarnation.


If such functionality were properly implemented, the final behaviour  
and definition would however probably be pretty much the same as the  
ADA definition Vinzent posted. However, as has been mentioned several  
times before: volatile has absolutely no use to make programs thread  
safe. Its only use is for memory mapped I/O.



Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Andrew Brunner
On Thu, Jun 30, 2011 at 4:31 AM, Hans-Peter Diettrich
drdiettri...@aol.com wrote:

 After these considerations I'd understand that using Interlocked
 instructions in the code would ensure such read/write-through, but merely as
 a side effect - they also lock the bus for every instruction, what's not
 required when concurrent access has been excluded by other means before.

I too have come to that conclusion.  It remains to be seen/decided
though, who's responsibility is it to ensure/enforce coherency?
Jonas was suggesting that the posix implementation (but he probably
meant kernel) was already doing that via CriticalSection.

 Furthermore we need concrete examples[2], how (to what extent) it's required
 to use these special instructions/procedures, in examples like above. When
 cache synchronization is a big issue, then the usage of related
 (thread-unaware) objects should be discussed as well, i.e. how to ensure
 that their use will cause no trouble, e.g. by invalidating the entire cache
 before.

Some FPC work may have been done in this area - intentional or not.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Michael Schnell

On 06/30/2011 11:52 AM, Jonas Maebe wrote:


On 30 Jun 2011, at 10:38, Michael Schnell wrote:

Regarding FPC, TCriticalSection is a decent encapsulation for 
pthread_mutex_... when used in this way.


But e.g. if you use a TThreadList instance myList with multiple 
threads it can't be the way to go to include any occurrence of 
myList.xxx by a critical section just to make sure that the cache 
synchronization has happened and the instance variable itself in fact 
is valid.


That's where optimization comes in,


Very wrong assumption.

Optimization is not the question here it's just working vs. not working.

In a previous post the claim was that if the variable is not in the 
cache of the appropriate CPU, a cache synchronization is not 
automatically done by the underling system (Hardware / OS / Libraries) 
and thus the variable has an erroneous value unless the application 
program uses some special means to provide coherency.


In fact I doubt this, but this was the claim and thus needs to be 
discussed here.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Michael Schnell

On 06/29/2011 09:44 PM, Vinzent Höfler wrote:


If they are accessed by only one thread, I'd assert that each core's view
on its own cache is not susceptible to memory ordering issues

I don't suppose this is that simple.

AFAIK, the cache does not work on byte addresses, but on entities of 
cache lines that are 128 byte or whatever.


So a cache can't see if a certain variable is accessed by another 
thread, but needs to store and reload a complete line.


Thus one CPU might modify a value and write back the cache line while 
another CPU modified a value of another variable in the same cache line.


As this situation obviously is handled by the hardware, I do suppose 
that the case of multiple CPUs modifying the same variable is handled, 
too (but of course without software considerations not regarding the 
hardcore cases like an atomic read-modify-write access or cycle-level 
memory ordering).


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Michael Schnell

On 06/30/2011 11:45 AM, Jonas Maebe wrote:


There is none. FPC has a volatile modifier in svn trunk, but it 
currently only affects the node tree optimizer.

...
 Its only use is for memory mapped I/O.

I don't suppose the node tree optimizer is memory mapped I/O ???

-Michael

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Michael Schnell

On 06/30/2011 11:31 AM, Hans-Peter Diettrich wrote:



Consider the shareable bi-linked list, where insertion requires code 
like this:

  list.Lock; //prevent concurrent access
  ... //determine affected list elements
  new.prev := prev; //prev must be guaranteed to be valid
  new.next := next;
  prev.next := new;
  next.prev := new;
  list.Unlock;
I really would like to see a test case proving my assumption wrong that 
this in fact just woks


We found that
 - my original volatile question is invalid, as the function calls 
done with list.lock and list.unlock are a volatile barrier preventing 
the compiler from caching some value inappropriately in a register, 
simply because they are function calls.
 - the MUTEX operations done with list.lock and list.unlock (at least 
on PCs in Linux and Windows) use library calls that includes memory 
barriers
 - if the potential cache incoherency would not be handled by Hardware 
/ OS / Libraries on behalf of user land programs, I feel that this would 
so disastrous and ubiquitous that it result in so many programs not 
working on SMP systems that it would be a really well known issue.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Andrew Brunner
On Thu, Jun 30, 2011 at 8:04 AM, Michael Schnell mschn...@lumino.de wrote:

 - if the potential cache incoherency would not be handled by Hardware / OS
 / Libraries on behalf of user land programs, I feel that this would so
 disastrous and ubiquitous that it result in so many programs not working on
 SMP systems that it would be a really well known issue.

I agree.  This problem when encountered was hidden during steady state
testing.  The list was consistently working as expected.  Where it
failed was when the core was ~80% usage and it walked - and it was on
my test system here using daily Ubuntu x64 builds - lord knows what
kernel it had those days.

Infact, it could possibly be an ubiquitous exploit waiting for
disaster when code normally running code encounters stale values
across cores.  You can imagine systems designed to never fail - fail
for no known reason at all...

In a case I observed, it did cause a significant problem to the
server.  Yes, it was disastrous, and ONLY evident during stress tests.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Michael Schnell

On 06/30/2011 03:29 PM, Andrew Brunner wrote:

In a case I observed, it did cause a significant problem to the
server.  Yes, it was disastrous, and ONLY evident during stress tests.
... which encourages me to suggest that it is a nasty bug _somewhere_. 
Maybe even in the hardware used.


I can't believe that the Posix specs allow for such problem to occur.

-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Sven Barth

Am 30.06.2011 14:53, schrieb Michael Schnell:

On 06/30/2011 11:45 AM, Jonas Maebe wrote:


There is none. FPC has a volatile modifier in svn trunk, but it
currently only affects the node tree optimizer.
...
Its only use is for memory mapped I/O.

I don't suppose the node tree optimizer is memory mapped I/O ???


No, but the node tree optimizer might optimize away two consecutive 
reads from or writes to a memory mapped variable which might be 
necessary for the hardware...


e.g. (theoretical pseudo code scenario)

=== source begin ===

var
  a: Integer; volatile; absolute $42;
  b: Integer;
begin
  b := a; // this might be necessary for the hardware, but the 
optimizer will remove the first statement if it doesn't know about 
volatile

  b := a;
end;

=== source end ===

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-30 Thread Jonas Maebe


On 30 Jun 2011, at 14:26, Michael Schnell wrote:


On 06/30/2011 11:52 AM, Jonas Maebe wrote:


On 30 Jun 2011, at 10:38, Michael Schnell wrote:

But e.g. if you use a TThreadList instance myList with multiple  
threads it can't be the way to go to include any occurrence of  
myList.xxx by a critical section just to make sure that the cache  
synchronization has happened and the instance variable itself in  
fact is valid.


That's where optimization comes in,


Very wrong assumption.


I simply misunderstood you (I thought you meant that there should be a  
solution to avoid having to use critical sections around all accesses  
to fields that may be accessed from multiple threads).


However, what is a wrong assumption on your part is that when I  
replied to fpc-other with you in CC, explicitly mentioning moved to  
fpc-other because unrelated to developing FPC, that it's ok to reply  
back to fpc-devel (moreover removing that remark in the process).


This thread has gone off topic for long enough now on this list, and  
further posts on this topic to this list will be rejected.



Jonas
FPC mailing lists admin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/28/2011 06:07 PM, Andrew Brunner wrote:

You can stick your head in the sand all you want, just don't run your
code on multi-core cpus and expect valid stability - and come back
here complaining on how unstable your multi-threaded application is
due to FPC design!
If a correctly done Posix compliant program does not run on some system 
there is a bug in the infrastructure.


This discussion is not about which programming paradigm is better, but 
it is only sensible because an  example of a not correctly working Posix 
compliant program had been offered and thus it's necessary to localize 
the bug and - if same is not in the user software - request a patch.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/28/2011 06:33 PM, Andrew Brunner wrote:

Remember ***cores!=threads*** people.

Wrong regarding the issue in question (see the message by Jonas).

I'm at a loss for words.  So you equate threads to cores?

A (Posix compliant) user software needs to consider each thread as 
running on it's own CPU and thus any concurrency to be allowed (e.g. 
expecting that a higher priority thread is not interrupted by a lower 
priority thread has to be considered erroneous.)


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/28/2011 10:25 PM, Hans-Peter Diettrich wrote:


Can you run your test again, assuring that only one thread can access 
the list at the same time, but *without* the Interlocked updates?



This would be a very nice move of Andrew's !!!

If he uses a single TCriticalSection instance to protect all accesses to 
the variables (seemingly a set of pointer structures used to create a 
double linked list) this is bound to work correctly on any hardware with 
any count of cores under all circumstances.


Otherwise there is some bug.

And this bug needs to be located.

If it is in the user software, Andrew will be able to fix it.
If is is in the RTL/LCL we need to issue a patch request here.
If it is in the Linux infrastructure (libraries or OS) an appropriate 
patch request can be generated as well

If it is in the Windows infrastructure we are out of luck.
If it is in the hardware, same needs to go  to the trash bin

BTW. The fact that the current code with interlocked instructions works 
on a higher core-count engine than the code without, does not mean that 
it in fact is correct or even better, as this drastically changes the 
timing and might just by chance prevent concurrency from occurring. In 
fact, IMHO, interlocked instructions are not appropriate here, anyway, 
as same are constructed to ensure single-Word variable atomic behavior 
(necessary e.g. to construct a MUTEX or Semaphore). But here, 
multi-variable atomicity is necessary and same is only possible using a 
critical section of some kind (and within same - by Posix definition -  
atomicity and concurrency-protection is granted anyway, thus interlocked 
instructions do nothing but slow down the code and with that change the 
thread-related behavior of the code ).


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Henry Vermaak

On 28/06/11 15:15, Andrew Brunner wrote:

On Tue, Jun 28, 2011 at 9:00 AM, Henry Vermaakhenry.verm...@gmail.com  wrote:

On 28/06/11 14:23, Andrew Brunner wrote:


There is no problem no need for volatile variables.  Compare and Swap
or Interlocked mechanisms will solve any problems.


Nope.  You still need to prevent the cpu from reordering instructions with
memory barriers.  I'm starting to sound like a broken record.  If you don't
understand this, use the threading primitives provided by your operating
system like everyone else.

Henry


You've got your list particiapants mixed up.  It was me who suggested
order is important (at least on the lazarus discussion).


No, I was talking to you.


And I am am 100% correct.  Interlocked / CAS happen in one shot.  They
don't need barriers.  They are protected.
I think you have my conversations mixed up.


The reason for my comment is that I get the idea that you think you can 
only use atomic operations to implement thread safe code.  Please 
correct me if I'm misunderstanding you.


If this is the case, you are mistaken.  Your code then probably only 
works on x86 and amd64 (with some luck), since on those architectures 
atomic instructions aren't reordered with loads or stores.  In fact, x86 
and amd64 _only_ reorders stores after loads.  Architectures like later 
ARM/POWER can reorder _anything_ for you, including atomic operations. 
You will need memory barriers in addition to atomic instructions, even 
on x86/amd64 in all but the simplest cases.


This is basically what pthread_mutex and windows critical sections 
already do for you (spinlock + barrier).  If they're not working for 
you, you are using them incorrectly.


Henry
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Hans-Peter Diettrich

Vinzent Höfler schrieb:

Question is, what makes one variable use read/write-through, while 
other variables can be read from the cache, with lazy-write?


Synchronisation. Memory barriers. That's what they are for.


And this doesn't happen out of thin air. How else?

Is this a compiler requirement, which has to enforce 
read/write-through for all volatile variables?


No.  volatile (at least in C) does not mean that.


Can you provide a positive answer instead?

I meant volatile as read/write-through, not related to C. Read as 
synchronized, if you ar more comfortable with that term ;-)


But if so, which variables (class fields...) can ever be treated as 
non-volatile, when they can be used from threads other than the main 
thread?


Without explicit synchronisation? Actually, none.


Do you understand the implication of your answer?

When it's up to every coder, to insert explicit synchronization whenever 
required, how to determine the places where explicit code is required?


Aren't we then in the unpleasant situation, that *every* expression can 
be evaluated using unsynchronized values, unless the compiler uses 
synchronized read instructions to obtain *every* value [except from stack]?


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/28/2011 06:42 PM, Hans-Peter Diettrich wrote:



I could not find a definition of the mutex struct, to determine 
whether it contains any user-alterable values. When the value is 
declared outside the mutex struct, it will be accessible also 
*without* locking the mutex first.


What do you mean by Mutex struct. The Data structure a Mutex 
internally uses is in Kernel space and invisible to the user program. 
With appropriate archs (such as X86 and modern ARM), in fact pthreadlib 
uses FUTEX instead of MUTEX, here a data structure in user land memory 
is allocated by the library, but a user program never should access it.


When using a MUTEX or FUTEX as a critical section it protects all the 
data that only is accessed by instructions issued after doing the 
enter and before doing the leave call. So it's entirely up to the 
user program to define what data is protected.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Nikolai Zhubr

29.06.2011 15:28, Hans-Peter Diettrich:

But if so, which variables (class fields...) can ever be treated as
non-volatile, when they can be used from threads other than the main
thread?


Without explicit synchronisation? Actually, none.


Do you understand the implication of your answer?

When it's up to every coder, to insert explicit synchronization whenever
required, how to determine the places where explicit code is required?


All places where any non-readonly data could be accessed by 2 or more 
threads should be protected. Thats it.

Main thread is no special in this regard.

In order to reduce potential collisions, different critical section 
objects (mutexes) can be used to protect different (think unrelated) 
blocks of data in more fine-grained way.


Nikolai



Aren't we then in the unpleasant situation, that *every* expression can
be evaluated using unsynchronized values, unless the compiler uses
synchronized read instructions to obtain *every* value [except from stack]?

DoDi

___
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel




___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/28/2011 08:09 PM, Hans-Peter Diettrich wrote:



When you have a look at TThreadList.LockList/UnlockList, then you'll 
see that LockList enters the critical section, and UnlockList leaves it. 

Yep This is how a CS works.
All code executed in between such two calls is absolutely ignorant of 
the state of the CS, there is no in/outside.


The State (relevant to this thread) of CS does not change when some 
code of the thread is between enter and leave. So it is not ignorant 
but it does know that it owns the CS and is the only thread that is 
inside.


(You could say, regarding a certain thread the possible CS states are 
I'm outside, I'm inside, and I'm waiting for entry. The states of 
the CS regarding other threads is not of interest for this thread, other 
that they are known not to be inside if this thread is inside.)


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/28/2011 07:05 PM, Vinzent Höfler wrote:
On Tue, 28 Jun 2011 15:54:35 +0200, Michael Schnell 
mschn...@lumino.de wrote:


No, it can't. volatile just ensures that accessing the variable 
results in
actual memory accesses. That does not mean cache-coherence, so another 
core

may still see other (as in older) values.
This is done by the hardware (but not aggressive enough to ensure atomic 
instructions to work without additional bus-locking)

It should not.
Right you are. We found that a compiler needs to consider any function 
call as a volatile barrier and is not allowed to cache any 
memory-value in a register as the called function might somehow know the 
address and access that variable (even in a single threaded application).


As a CS Enter and Leave is done as a function call this aspect of my 
original question is solved.


Thanks,
-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/29/2011 01:06 AM, Vinzent Höfler wrote:


Without explicit synchronisation? Actually, none.

How to do such synchronization with normal portable user-program 
programming (aka Posix means).


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/29/2011 01:28 PM, Hans-Peter Diettrich wrote:


Do you understand the implication of your answer?

Regarding Objects it would mean that it's forbidden to create an object 
in one thread and use it in another one. This is done very often.I can't 
believe that the hardware is that bad.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Jonas Maebe


On 28 Jun 2011, at 22:25, Hans-Peter Diettrich wrote:


Andrew Brunner schrieb:
Wrong.  Sigh... Order of execution is paramount just about  
everywhere.

It can be disastrous if not understood.
Remember ***cores!=threads*** people.


If your experience is really that chaotic, I think it's worth some  
deeper investigation.


1) Can one thread be executed on multiple cores, at the same time?


Not unless a speculative parallel execution environment is used  
(either in software or hardware), but because of their speculative  
nature those are by design transparent to the software (and afaik all  
of them are still only in research stages).


If so, shouldn't there exist means (flags...) to tell the OS, that  
FPC executables are not (yet) ready for such automatic parallelism?


Such flags don't exist because there is no need for them.

2) When a thread wanders around, from one core to another one,  
shouldn't be the starting conditions (CPU state, caches) exactly in  
the state when the thread was stopped on the previous core?


Yes. That is the job of the operating system (which will do this by  
inserting memory barriers, cache flushes etc).


You seem to assume that the cache of the previous core may contain  
some updated data, that was not yet written back into RAM when the  
thread is resumed on a different core, whose cache happens to  
contain other values? This really would be a very big problem :-(

[So big that I cannot believe that it really exists]


Indeed, it does not exist, unless there is a bug in the kernel of his  
machine.


3) When above cache inconsistencies can occur, how can even a single- 
threaded program work correctly?


Indeed.


Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/29/2011 03:17 PM, Nikolai Zhubr wrote:


All places where any non-readonly data could be accessed by 2 or more 
threads should be protected. Thats it.

So this is not supposed to work:

Main thread:

  myThread := TmyThread.Create(True);
  while not myThread.Suspended sleep(0); //give up time slice to 
allow the worker thread to start
  myList := TThreadlist.Create; // set the variable 
in cache 1

  myThread.Suspended := False;
  sleep(100);   // have the 
worker thread run

  


Worker Thread:

procedure TmyTherad.Execute;
begin
  myList := NIL;  // set the variable in the 
cache 2

  Suspended := True;
  myList.Add(.   //has the variable been 
synchronized from the other cache 



Here the variable myList is not protected.

As assigning a value to myList in one thread is only a very short time 
before the other thread reads it, it's very likely that the wrong value 
is still be in the cache of the worker thread's processor and make it 
crash.


But is is just a very extreme example of a behavior that mostly is 
assumed to work and according to your wording would be bound to fail.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Andrew Brunner
Here is a nice example of one that actually works...

http://wiki.lazarus.freepascal.org/Manager_Worker_Threads_System

Granted I wrote this sample and Wiki a long time ago, but you may want
to read this ;-)
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/29/2011 04:33 PM, Andrew Brunner wrote:

Here is a nice example of one that actually works...

http://wiki.lazarus.freepascal.org/Manager_Worker_Threads_System


Nice.

But actually what we need is an example that does not work and shows a 
case that the cache incoherency in fact is not handled by the hardware 
in a way a dummy would assume it would.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Hans-Peter Diettrich

Michael Schnell schrieb:

All code executed in between such two calls is absolutely ignorant of 
the state of the CS, there is no in/outside.


The State (relevant to this thread) of CS does not change when some 
code of the thread is between enter and leave. So it is not ignorant 
but it does know that it owns the CS and is the only thread that is 
inside.


The code in a called subroutine doesn't know about the CS. [It usually 
also doesn't care about from which exact thread it was called]


This means that possible recursion must be prevented in all related code 
in a CS, or (safer) that the CS must be recursive (spinlock?) on all 
platforms.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Hans-Peter Diettrich

Nikolai Zhubr schrieb:

29.06.2011 15:28, Hans-Peter Diettrich:

But if so, which variables (class fields...) can ever be treated as
non-volatile, when they can be used from threads other than the main
thread?


Without explicit synchronisation? Actually, none.


Do you understand the implication of your answer?

When it's up to every coder, to insert explicit synchronization whenever
required, how to determine the places where explicit code is required?


All places where any non-readonly data could be accessed by 2 or more 
threads should be protected. Thats it.


Consider what this means to the RTL and other libraries. That code 
typically is not thread-safe, so that it cannot be called safely from 
threads. Doesn't this imply that in detail all application specific 
objects must be either local to an thread, or must be protected against 
concurrent access (shareable)?


This means that a simplified version of TThreadList would be nice, that 
allows to wrap a single shareable object and make it usable in an 
thread-safe way.


Possibly the language could be extended to help in the determination of 
thread-(un)safe procedures. E.g. references to shareable objects could 
be allowed only as const or in parameters, so that the compiler can 
disallow persistent copies of such references. But like the C const 
modifier, such a strict attribute may be problematic in many cases.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Nikolai Zhubr

29.06.2011 18:31, Michael Schnell:
[...]

So this is not supposed to work:

Main thread:

myThread := TmyThread.Create(True);
while not myThread.Suspended sleep(0); //give up time slice to allow the
worker thread to start
myList := TThreadlist.Create; // set the variable in cache 1
myThread.Suspended := False;
sleep(100); // have the worker thread run



Worker Thread:

procedure TmyTherad.Execute;
begin
myList := NIL; // set the variable in the cache 2
Suspended := True;
myList.Add(. //has the variable been synchronized from the other
cache 


Here the variable myList is not protected.


I think this code will work fine (at least on win32) because your main 
thread issues Sleep() and (implicitely) ResumeThread(), and your worker 
thread issues Sleep() and (implicitely) SuspendThread(). I somehow doubt 
that passing these system calls could let something remain unflushed in 
the cache, as the OS will most probably have to do some synchronization 
inside these calls for internal bookkeeping, but this is IMHO kind of 
side-effect.


If it was my program I'd use critical section explicitely anyway to be 
sure.


Nikolai



As assigning a value to myList in one thread is only a very short time
before the other thread reads it, it's very likely that the wrong value
is still be in the cache of the worker thread's processor and make it
crash.

But is is just a very extreme example of a behavior that mostly is
assumed to work and according to your wording would be bound to fail.

-Michael
___
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel




___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/29/2011 05:28 PM, Hans-Peter Diettrich wrote:


The code in a called subroutine doesn't know about the CS. [It usually 
also doesn't care about from which exact thread it was called]


This means that possible recursion must be prevented in all related 
code in a CS, or (safer) that the CS must be recursive (spinlock?) 
on all platforms.




I was taking about the CS Enter and Leave procedures themselves, not 
about calling functions within a CS


I feel that calling a subroutine within a CS is a bad idea anyway as the 
point of CSes is to hold them as short as possible not to increase the 
latency of the other threads.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/29/2011 05:57 PM, Hans-Peter Diettrich wrote:



This means that a simplified version of TThreadList would be nice, 
that allows to wrap a single shareable object and make it usable in an 
thread-safe way.


IMHO just TList is OH for this purpose. It (supposedly) is per-instance 
thread safe: if an instance is used just by a single thread, the code 
is safe, if the same instance is used by multiple threads the code is 
not safe.


The necessity of a more complex definition of thread safety for Objects 
(as a tribute to the hidden self parameter that is not considered as an 
input by the average user) was the starting point of the discussion in 
the Lazarus list.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Nikolai Zhubr

29.06.2011 19:57, Hans-Peter Diettrich:
[...]

imply that in detail all application specific
objects must be either local to an thread, or must be protected against
concurrent access (shareable)?

IMHO yes.

[...]

Possibly the language could be extended to help in the determination of
thread-(un)safe procedures. E.g. references to shareable objects could
Well yes, but its probably hard to inject such safety into a general 
purpose language. After all, pointers are not quite safe even in a 
single-threaded application!


Nikolai
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Michael Schnell

On 06/29/2011 05:29 PM, Nikolai Zhubr wrote:


. I somehow doubt that passing these system calls could let something 
remain unflushed in the cache, as the OS will most probably have to do 
some synchronization inside these calls for internal bookkeeping, but 
this is IMHO kind of side-effect.
Today the cache is huge and flushing it is very expensive (as it likely 
will need to be refilled with the same data).


Thus I don't suppose the OS will flush the cache unless absolutely 
necessary. On x86 the cache works on hardware addresses (not on virtual 
process addresses) and thus reassigning a thread to the same CPU (which 
with Linux is a preferred strategy) after intermediately running some 
other process, would in fact at best find the cache filled with much of 
the old data.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Jonas Maebe

On 29 Jun 2011, at 17:29, Nikolai Zhubr wrote:

 29.06.2011 18:31, Michael Schnell:
 [...]
 So this is not supposed to work:
 
 Main thread:
 
 myThread := TmyThread.Create(True);
 while not myThread.Suspended sleep(0); //give up time slice to allow the
 worker thread to start

sleep(0) does not give up the current time slice on all operating systems. Use 
ThreadSwitch() instead.

 myList := TThreadlist.Create; // set the variable in cache 1
 myThread.Suspended := False;
 sleep(100); // have the worker thread run
 
 
 
 Worker Thread:
 
 procedure TmyTherad.Execute;
 begin
 myList := NIL; // set the variable in the cache 2
 Suspended := True;

In case this supposed to be a tthread descendent: setting its suspended field 
to true does not suspend the thread. Call 

 myList.Add(. //has the variable been synchronized from the other
 cache 
 
 Here the variable myList is not protected.
 
 I think this code will work fine (at least on win32) because your main thread 
 issues Sleep() and (implicitely) ResumeThread(), and your worker thread 
 issues Sleep() and (implicitely) SuspendThread(). I somehow doubt that 
 passing these system calls could let something remain unflushed in the cache, 
 as the OS will most probably have to do some synchronization inside these 
 calls for internal bookkeeping, but this is IMHO kind of side-effect.

The sleep(100) in the main thread may not happen before the child thread 
accesses myList. And if it does: the above code is definitely completely thread 
unsafe and requires memory barriers if the programmer refuses to use a proper 
synchronization primitive. You cannot use booleans instead of mutexes and 
expect things to work.

Of course, that does not mean that it is not supposed to work, as the first 
quoted sentence above states. It's only not *guaranteed* to work. It may very 
well work 100 out 100 times you try to actually execute it. But there are 
definitely circumstances under which it will fail.

Maybe we should create a new list called multithreading, because these 
discussions have absolutely nothing to do with developing FPC.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: *** GMX Spamverdacht *** Re: [fpc-devel] volatile variables

2011-06-29 Thread Vinzent Höfler
On Wed, 29 Jun 2011 16:31:32 +0200, Michael Schnell mschn...@lumino.de  
wrote:



On 06/29/2011 03:17 PM, Nikolai Zhubr wrote:


All places where any non-readonly data could be accessed by 2 or more  
threads should be protected. Thats it.

So this is not supposed to work:


Precisely, it is not /guaranteed/ to work if that's what you meant.

(Please also note that give up time slice does not mean very much on a
multi-core/CPU system when the threads are running on different cores/CPUs
and thus in real parallelity. But I suppose you know that.)

As assigning a value to myList in one thread is only a very short time  
before the other thread reads it, it's very likely that the wrong value  
is still be in the cache of the worker thread's processor and make it  
crash.


But is is just a very extreme example of a behavior that mostly is  
assumed to work and according to your wording would be bound to fail.


Ass-U-Me. You know. ;) - Yes, this is bound to fail.


Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Vinzent Höfler

On Wed, 29 Jun 2011 15:57:15 +0200, Michael Schnell mschn...@lumino.de
wrote:


On 06/29/2011 01:06 AM, Vinzent Höfler wrote:


Without explicit synchronisation? Actually, none.

How to do such synchronization with normal portable user-program  
programming (aka Posix means).


POSIX: pthread_mutex_(un)lock()  Co.

Or, maybe I didn't understand the question...


Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-29 Thread Vinzent Höfler

On Wed, 29 Jun 2011 13:28:20 +0200, Hans-Peter Diettrich
drdiettri...@aol.com wrote:


Vinzent Höfler schrieb:

Question is, what makes one variable use read/write-through, while  
other variables can be read from the cache, with lazy-write?

 Synchronisation. Memory barriers. That's what they are for.


And this doesn't happen out of thin air. How else?


Ok, maybe I misunderstood your question. Normally, these days every
memory access is cached (and that's of course independent from compiler
optimizations).
But there are usually possibilities to define certain areas as
write-through (like the video frame buffer). But that's more a chip-set
thing than it has anything to do with concurrent programming.

Apart from that you have to use the appropiate CPU instructions.

Is this a compiler requirement, which has to enforce  
read/write-through for all volatile variables?

 No.  volatile (at least in C) does not mean that.


Can you provide a positive answer instead?


Ada2005 RM:

|C.6(16): For a volatile object all reads and updates of the object as
| a whole are performed directly to memory.
|C.6(20): The external effect [...] is defined to include each read and
| update of a volatile or atomic object. The implementation shall
| not generate any memory reads or updates of atomic or volatile
| objects other than those specified by the program.

That's Ada's definition of volatile. C's definition is less stronger, but
should basically have the same effect.

Is that positive enough for you? ;)

I meant volatile as read/write-through, not related to C. Read as  
synchronized, if you ar more comfortable with that term ;-)


In that case, there is no such requirement for a compiler. At least not
for the ones I know of.

But if so, which variables (class fields...) can ever be treated as  
non-volatile, when they can be used from threads other than the main  
thread?

 Without explicit synchronisation? Actually, none.


Do you understand the implication of your answer?


I hope so. :)

When it's up to every coder, to insert explicit synchronization whenever  
required, how to determine the places where explicit code is required?


By careful analysis. Although there may exist tools which detect  
potentially

un-synchronised accesses to shared variables, there will be no tool that
inserts synchronisation code automatically for you. If there were, the  
Linux

community wouldn't have such big trouble to get rid of their BKL (big
kernel lock) from the days, where the Linux kernel was made preemptible.

Aren't we then in the unpleasant situation, that *every* expression can  
be evaluated using unsynchronized values, unless the compiler uses  
synchronized read instructions to obtain *every* value [except from  
stack]?


If they are accessed by only one thread, I'd assert that each core's view
on its own cache is not susceptible to memory ordering issues. So each
thread on its own can be treated like the single-CPU case (i.e. nothing
special needed). Synchronisation is only required if different threads of
execution may need access to the same, shared variable.

But in that case you should synchronise anyway, although in the single-core
case you could get away with using types which were guaranteed to be  
atomic.

I've done that a couple of times, but I am well aware that this will break
any time soon.


Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 01:20 PM, Henry Vermaak wrote:



Operations on volatile variables are not atomic,

That is of course known.
nor do they establish a proper happens-before relationship for threading. 

I see. So maybe part of my question is invalid.

But as pthread_mutex (and the appropriate Windows stuff) contains a 
memory barrier, same does enforce memory ordering even in an SMP 
environment, regarding cache operations and with CPUs that do on-the fly 
reordering.


So, regarding C, I understand that (even in a single CPU environment):

If all accesses to a variable are protected by a MUTEX, multiple threads 
will use the variable as expected, only if it is defined as volatile. 
Otherwise is might be cached in registers and one thread's writing to (i 
C code but not compiled that way) it might be unnoticed by the other thread.


Now how is the volatile state defined in Pascal and how can a heap 
variable be defined to be handled as volatile ?


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 6:14 AM, Michael Schnell mschn...@lumino.de wrote:

 For variables not defined as volatile, (e.g.) pthread_mutex (and similar
 stuff on Windows) can be used to protect them.


A mutex may be able to atomically block access because of its own
memory barrier, but I would suggest that employing such a technique on
multi-core systems will not ensure an accurate value.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Jonas Maebe


On 28 Jun 2011, at 14:58, Andrew Brunner wrote:

On Tue, Jun 28, 2011 at 6:14 AM, Michael Schnell  
mschn...@lumino.de wrote:


For variables not defined as volatile, (e.g.) pthread_mutex (and  
similar

stuff on Windows) can be used to protect them.


A mutex may be able to atomically block access because of its own
memory barrier, but I would suggest that employing such a technique on
multi-core systems will not ensure an accurate value.


pthread_mutex() does guarantee that. I don't know about the Windows  
equivalents.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 8:00 AM, Jonas Maebe jonas.ma...@elis.ugent.be wrote:

 On 28 Jun 2011, at 14:58, Andrew Brunner wrote:

 On Tue, Jun 28, 2011 at 6:14 AM, Michael Schnell mschn...@lumino.de
 wrote:

 For variables not defined as volatile, (e.g.) pthread_mutex (and similar
 stuff on Windows) can be used to protect them.

 A mutex may be able to atomically block access because of its own
 memory barrier, but I would suggest that employing such a technique on
 multi-core systems will not ensure an accurate value.

 pthread_mutex() does guarantee that. I don't know about the Windows
 equivalents.


Specification just describes standard mutex.  What makes pthreads
specification different to include ordering?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Jonas Maebe


On 28 Jun 2011, at 15:05, Andrew Brunner wrote:

On Tue, Jun 28, 2011 at 8:00 AM, Jonas Maebe jonas.ma...@elis.ugent.be 
 wrote:


On 28 Jun 2011, at 14:58, Andrew Brunner wrote:


A mutex may be able to atomically block access because of its own
memory barrier, but I would suggest that employing such a  
technique on

multi-core systems will not ensure an accurate value.


pthread_mutex() does guarantee that. I don't know about the Windows
equivalents.


Specification just describes standard mutex.  What makes pthreads
specification different to include ordering?


http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ 
V1_chap04.html (point 4.11)



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Henry Vermaak

On 28/06/11 14:00, Jonas Maebe wrote:


On 28 Jun 2011, at 14:58, Andrew Brunner wrote:


On Tue, Jun 28, 2011 at 6:14 AM, Michael Schnell mschn...@lumino.de
wrote:


For variables not defined as volatile, (e.g.) pthread_mutex (and similar
stuff on Windows) can be used to protect them.


A mutex may be able to atomically block access because of its own
memory barrier, but I would suggest that employing such a technique on
multi-core systems will not ensure an accurate value.


pthread_mutex() does guarantee that. I don't know about the Windows
equivalents.


I've found this earlier:

http://msdn.microsoft.com/en-us/library/ms686355%28v=VS.85%29.aspx

Henry
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Jonas Maebe


On 28 Jun 2011, at 14:32, Michael Schnell wrote:


So, regarding C, I understand that (even in a single CPU environment):

If all accesses to a variable are protected by a MUTEX, multiple  
threads will use the variable as expected, only if it is defined as  
volatile. Otherwise is might be cached in registers and one thread's  
writing to (i C code but not compiled that way) it might be  
unnoticed by the other thread.


The C (or Pascal) compiler has no idea whether or not the global  
variable will be accessed by the pthread_mutex_lock()/unlock()  
function. As a result, it will never cache it in a register across  
function calls, and the call to the mutex function by itself  
guarantees that the variable's value will be written back.


So you don't need volatile. Even if it's a local variable you don't  
need it, because as soon as you take the address of a local variable  
and it can escape the current function (and hence the current thread),  
the compiler again has to assume that any called function may modify  
it via an indirect access.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 02:58 PM, Andrew Brunner wrote:

A mutex may be able to atomically block access because of its own
memory barrier, but I would suggest that employing such a technique on
multi-core systems will not ensure an accurate value.


If this is true, how can any multithreaded be done ?

Only the ordering decision inside vs outside of the critical section 
is necessary for threaded user application. If both Enter and Leave do a 
full fence barrier, I suppose we are safe.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 8:11 AM, Jonas Maebe jonas.ma...@elis.ugent.be wrote:

 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html
 (point 4.11)

Nope.  Nothing about order - just access - and that is entirely on the
application level - not system.

1.) Code execution on die is not controlled by pthreads implemention -
as it is unaware at that level.
2.) Blocking access as described in 4.11 does not address execution order.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 8:16 AM, Jonas Maebe jonas.ma...@elis.ugent.be wrote:
 The C (or Pascal) compiler has no idea whether or not the global variable
 will be accessed by the pthread_mutex_lock()/unlock() function. As a result,
 it will never cache it in a register across function calls, and the call to
 the mutex function by itself guarantees that the variable's value will be
 written back.

Agreed.  And you can make such access atomic.  Getting developers to
chose the right tool for the job is the key here.  But understanding
the core issues (pun intented ;-) is the key.


 So you don't need volatile. Even if it's a local variable you don't need it,
 because as soon as you take the address of a local variable and it can
 escape the current function (and hence the current thread), the compiler
 again has to assume that any called function may modify it via an indirect
 access.


There is no problem no need for volatile variables.  Compare and Swap
or Interlocked mechanisms will solve any problems.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 03:00 PM, Jonas Maebe wrote:

. I don't know about the Windows equivalents.

see

http://msdn.microsoft.com/en-us/library/ms686355%28v=VS.85%29.aspx

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Jonas Maebe


On 28 Jun 2011, at 15:20, Andrew Brunner wrote:

On Tue, Jun 28, 2011 at 8:11 AM, Jonas Maebe jonas.ma...@elis.ugent.be 
 wrote:



http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html
(point 4.11)


Nope.  Nothing about order - just access - and that is entirely on the
application level - not system.

1.) Code execution on die is not controlled by pthreads implemention -
as it is unaware at that level.


I have no idea what you mean by this. What would code execution off  
die be as opposed to code execution on die?


2.) Blocking access as described in 4.11 does not address execution  
order.


It does guarantee that if T1 locks the mutex, changes the value,  
unlocks the mutex and then T2 acquires the mutex (either on another  
cpu or not is irrelevant), then T2 will observe strict memory ordering  
with respect to T1 as far as this memory location is concerned (i.e.,  
it will see any changes to that memory location performed by T1 that  
were protected by the mutex).


If by execution ordering you mean that there is no guarantee  
regarding which thread will acquire the mutex first, then that's true,  
but synchonrization races are unrelated to memory ordering issues.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 8:28 AM, Jonas Maebe jonas.ma...@elis.ugent.be wrote:

 1.) Code execution on die is not controlled by pthreads implemention -
 as it is unaware at that level.


 I have no idea what you mean by this. What would code execution off die be
 as opposed to code execution on die?

on die image was meant to take you to the code on the actual core
being executed.  That is to say the core itself is ignorant of what
just executed before and will just take the code and execute it.

 2.) Blocking access as described in 4.11 does not address execution order.

 It does guarantee that if T1 locks the mutex, changes the value, unlocks the
 mutex and then T2 acquires the mutex (either on another cpu or not is
 irrelevant), then T2 will observe strict memory ordering with respect to T1
 as far as this memory location is concerned (i.e., it will see any changes
 to that memory location performed by T1 that were protected by the mutex).

Sort of right.  6 core system. Core 1 locks code block.  Code block
should still use interlocked statements to make memory assignments so
that when Core 1 releases lock - Core 2 can have a real-time image of
variable.  Otherwise Core 2 may see a stale copy of the variable.

 If by execution ordering you mean that there is no guarantee regarding
 which thread will acquire the mutex first, then that's true, but
 synchonrization races are unrelated to memory ordering issues.

Don't bother looking that deep.  The topic the poster raised is about
variable volatility with respect to thread safe code.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Jonas Maebe


On 28 Jun 2011, at 15:39, Andrew Brunner wrote:

On Tue, Jun 28, 2011 at 8:28 AM, Jonas Maebe jonas.ma...@elis.ugent.be 
 wrote:


1.) Code execution on die is not controlled by pthreads  
implemention -

as it is unaware at that level.


I have no idea what you mean by this. What would code execution  
off die be

as opposed to code execution on die?


on die image was meant to take you to the code on the actual core
being executed.  That is to say the core itself is ignorant of what
just executed before and will just take the code and execute it.


That's why libpthread includes memory barriers.

It does guarantee that if T1 locks the mutex, changes the value,  
unlocks the

mutex and then T2 acquires the mutex (either on another cpu or not is
irrelevant), then T2 will observe strict memory ordering with  
respect to T1
as far as this memory location is concerned (i.e., it will see any  
changes
to that memory location performed by T1 that were protected by the  
mutex).


Sort of right.  6 core system. Core 1 locks code block.  Code block
should still use interlocked statements to make memory assignments so
that when Core 1 releases lock - Core 2 can have a real-time image of
variable.  Otherwise Core 2 may see a stale copy of the variable.


No, that is impossible. That's the whole point of using libraries such  
as libpthread. They abstract such issues away. Using atomic operations  
inside mutex sections only slows down your program unnecessarily  
(unless you also access the target memory location from code not  
guarded by that mutex, and also use atomic operations in those  
alternate cases -- or if you are using a synchronization primitive  
from a library that does not observe the same semantics as libpthread,  
but that would be a really strange design decision).


If what you write above would be true, almost no program using  
libpthread for synchronization would consistently work on multi-core  
systems. How many programs do you know that exclusively use atomic  
operations to access shared memory locations inside code regions  
guarded by a pthread_mutex?



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 03:16 PM, Jonas Maebe wrote:


The C (or Pascal) compiler has no idea whether or not the global 
variable will be accessed by the pthread_mutex_lock()/unlock() 
function. As a result, it will never cache it in a register across 
function calls, and the call to the mutex function by itself 
guarantees that the variable's value will be written back.

If in C you do

static int x;
void play_with_x(void) {
  for (i=1; i0; i--) {
x += 1;
  };
  x = 0;
};

the compiler will see that x is just defined to be 0 in the end and 
optimize out thge complete loop.


But if you do the same with

volatile static int x;

the code will stay and another thread can watch x growing in a time 
sharing system.


I believe that inserting some ptherad_mutex... calls will not force the 
compiler to bother about some intermediate values of a non volatile 
variable.



I believe that with FPC global variables are assumed to be volatile and 
not optimized away or cashed in registers. But what about heap-variables ?




 Even if it's a local variable you don't need it,
Of course not as they can't be accessed by anybody but the running 
thread anyway.


  the compiler again has to assume that any called function may modify 
it via an indirect access.
... if same gets the address (which of course is possible with a global 
variable)


Thus true for global variables, not necessary true for static variables 
as they can't be accessed by a function defined in another module (I 
don't know whether the C compiler makes a difference)


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 03:23 PM, Andrew Brunner wrote:

Getting developers to
chose the right tool for the job is the key here.
Regarding normal user application there is only one option: Posix. Ans 
same happily is encapsulated in the RTL/LCL for FPC/Lazarus programmers.


Advanced (non-portable) programming of course can be necessary in 
certain projects.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 03:23 PM, Andrew Brunner wrote:

There is no problem no need for volatile variables.  Compare and Swap
or Interlocked mechanisms will solve any problems.

volatile is a directive to the compiler on how to handle a variable.

Variables that are not handled by the compiler but handled by non 
portable low level assembler functions of course are volatile on their 
own account.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Henry Vermaak

On 28/06/11 14:20, Andrew Brunner wrote:

On Tue, Jun 28, 2011 at 8:11 AM, Jonas Maebejonas.ma...@elis.ugent.be  wrote:


http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html
(point 4.11)


Nope.  Nothing about order - just access - and that is entirely on the
application level - not system.

1.) Code execution on die is not controlled by pthreads implemention -
as it is unaware at that level.


Of course it is.  They issue a hardware memory barrier.  This stops the 
cpu from reordering operations.  How do you think anything using 
pthreads will work if they didn't?


Henry
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Henry Vermaak

On 28/06/11 14:23, Andrew Brunner wrote:


There is no problem no need for volatile variables.  Compare and Swap
or Interlocked mechanisms will solve any problems.


Nope.  You still need to prevent the cpu from reordering instructions 
with memory barriers.  I'm starting to sound like a broken record.  If 
you don't understand this, use the threading primitives provided by your 
operating system like everyone else.


Henry
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
 No, that is impossible. That's the whole point of using libraries such as
 libpthread. They abstract such issues away. Using atomic operations inside
 mutex sections only slows down your program unnecessarily (unless you also
 access the target memory location from code not guarded by that mutex, and
 also use atomic operations in those alternate cases -- or if you are using a
 synchronization primitive from a library that does not observe the same
 semantics as libpthread, but that would be a really strange design
 decision).

Two issues with what you are suggesting Jonas.

Issue 1.) libpthread is just a posix implementation.
it does not AUTOMATICALLY resolve issues inherent with present day
multi-core memory access with respect to cores.  It is by definition a
thread implementation that includes atomic locks.

Issue 2.) Telling people that it is poor design to exclude posix
threads implementation is ignorant.  FPC is cross platform.  Posix
threads specification is mainly to offer windows like threadding to
unix/linux flavors.

 If what you write above would be true, almost no program using libpthread
 for synchronization would consistently work on multi-core systems. How many
 programs do you know that exclusively use atomic operations to access shared
 memory locations inside code regions guarded by a pthread_mutex?

Access vs. Order.  This is what makes a variable volatile across cores
(not threads).
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
 Of course it is.  They issue a hardware memory barrier.  This stops the cpu
 from reordering operations.  How do you think anything using pthreads will
 work if they didn't?

Documentation please?  If what you are saying is accurate just point
me to the documentation?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 9:00 AM, Henry Vermaak henry.verm...@gmail.com wrote:
 On 28/06/11 14:23, Andrew Brunner wrote:

 There is no problem no need for volatile variables.  Compare and Swap
 or Interlocked mechanisms will solve any problems.

 Nope.  You still need to prevent the cpu from reordering instructions with
 memory barriers.  I'm starting to sound like a broken record.  If you don't
 understand this, use the threading primitives provided by your operating
 system like everyone else.

 Henry

You've got your list particiapants mixed up.  It was me who suggested
order is important (at least on the lazarus discussion).

And I am am 100% correct.  Interlocked / CAS happen in one shot.  They
don't need barriers.  They are protected.
I think you have my conversations mixed up.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Henry Vermaak

On 28/06/11 15:09, Andrew Brunner wrote:

Of course it is.  They issue a hardware memory barrier.  This stops the cpu
from reordering operations.  How do you think anything using pthreads will
work if they didn't?


Documentation please?  If what you are saying is accurate just point
me to the documentation?


Jonas already pointed you to it:

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11

Applications shall ensure that access to any memory location by more 
than one thread of control (threads or processes) is restricted such 
that no thread of control can read or modify a memory location while 
another thread of control may be modifying it.


Please note the read or modify.  If you fail to understand this, you 
can read the source of a posix threads implementation, e.g. nptl (which 
is part of libc).


Henry
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Jonas Maebe


On 28 Jun 2011, at 15:54, Michael Schnell wrote:


static int x;
void play_with_x(void) {
 for (i=1; i0; i--) {
   x += 1;
 };
 x = 0;
};

the compiler will see that x is just defined to be 0 in the end and  
optimize out thge complete loop.


But if you do the same with

volatile static int x;

the code will stay and another thread can watch x growing in a time  
sharing system.


I believe that inserting some ptherad_mutex... calls will not force  
the compiler to bother about some intermediate values of a non  
volatile variable.


You believe wrongly.


Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
 Jonas already pointed you to it:

 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11

 Applications shall ensure that access to any memory location by more than
 one thread of control (threads or processes) is restricted such that no
 thread of control can read or modify a memory location while another thread
 of control may be modifying it.

 Please note the read or modify.  If you fail to understand this, you can
 read the source of a posix threads implementation, e.g. nptl (which is part
 of libc).

I honestly don't believe that by the above statement has anything to
do with what we're talking about here.  And I'm thinking it's because
of the two issues.

One is threads.  One is cores.  I think we need to focus to get to the
bottom of what we're all trying to say.

I have been following and it is completely agreed that thread locks
are NOT what we are trying to discuss.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 04:23 PM, Jonas Maebe wrote:


On 28 Jun 2011, at 15:54, Michael Schnell wrote:



I believe that inserting some ptherad_mutex... calls will not force 
the compiler to bother about some intermediate values of a non 
volatile variable.


You believe wrongly.

As the compiler does not know anything about what pthread_mutex does 
just the existence of a function call at that location can trigger that 
it behaves different from the case that no function call is done.


And this has been discussed in the other message: If the variable in 
fact is global the compiler needs to avoid caching it, if it is static 
and the function is in another module it might still decide to cache it, 
but you are right: it is not likely that it does make this difference.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 9:23 AM, Jonas Maebe jonas.ma...@elis.ugent.be wrote:

On topic, Jonas can you take a few moments to describe how developers
can force code execution in order w/o using a third party library?  Is
there a compiler directive we can use?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 04:31 PM, Andrew Brunner wrote:

  how developers
can force code execution in order w/o using a third party library?
Execution in order only makes sense when there is another thread that 
relies on this order.


So if both threads use the same critical section for accessing all 
variables that an ordering is necessary with, the actual ordering used 
completely within the critical section in fact is irrelevant as no other 
thread can get in the way at that point. So the high level Posix 
interface that is provided as TCriticalSection in the RTL/LCL should be 
workable (but not high performance).


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 9:33 AM, Michael Schnell mschn...@lumino.de wrote:

 And this has been discussed in the other message: If the variable in fact is
 global the compiler needs to avoid caching it, if it is static and the
 function is in another module it might still decide to cache it, but you are
 right: it is not likely that it does make this difference.

Well, I think one issue is that each core has it's own cache.

1.) How can we get the core to not relent and have the code handed off
to another core until we're finished?
2.) How can we get the core to have a synchronised copy of a
particular variable (aside from CAS)?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Jonas Maebe


On 28 Jun 2011, at 16:28, Andrew Brunner wrote:


Jonas already pointed you to it:

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11

Applications shall ensure that access to any memory location by  
more than
one thread of control (threads or processes) is restricted such  
that no
thread of control can read or modify a memory location while  
another thread

of control may be modifying it.

Please note the read or modify.  If you fail to understand this,  
you can
read the source of a posix threads implementation, e.g. nptl (which  
is part

of libc).


I honestly don't believe that by the above statement has anything to
do with what we're talking about here.  And I'm thinking it's because
of the two issues.

One is threads.  One is cores.  I think we need to focus to get to the
bottom of what we're all trying to say.


The Posix specification (and the Win32 api documentation referred to  
in this thread) doesn't care whether all threads are executed by the  
same or by different cores, and/or whether separate threads are  
rescheduled to different cores at different time slices. The specified  
behaviour is guaranteed to be the same under all circumstances exactly  
because it is defined at the level of threads rather than cores.  
That's the whole point of having abstractions such as threads and  
specifying their behaviour.


Even if you would create a libpthread implementation that works on top  
of MPI and which distributes threads over an entire cluster of  
different machines, then still the same behaviour would have to be  
guaranteed (because the *threads* have to comply to the specified  
behaviour, not specifically pipelines, cores, processors, machines,  
accelerator cards, ...).



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 9:43 AM, Michael Schnell mschn...@lumino.de wrote:
 On 06/28/2011 04:31 PM, Andrew Brunner wrote:

  how developers
 can force code execution in order w/o using a third party library?

 Execution in order only makes sense when there is another thread that relies
 on this order.

Wrong.  Sigh... Order of execution is paramount just about everywhere.
 It can be disastrous if not understood.
Remember ***cores!=threads*** people.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 04:38 PM, Andrew Brunner wrote:


1.) How can we get the core to not relent and have the code handed off
to another core until we're finished?
2.) How can we get the core to have a synchronised copy of a
particular variable (aside from CAS)?
I suppose you need to ask these questions the hardware designers at 
Intel or AMD (or read the appropriate docs).


If cache synchronization would not be done (even without forcing it by 
atomic interlocked instructions or memory barriers) regarding the huge 
cache provide with modern CPUs a thread would _never_ see what another 
thread writes into memory. But (unless some kind of atomicness or 
ordering is required) there are no issues on that behalf.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Michael Schnell

On 06/28/2011 05:02 PM, Andrew Brunner wrote:


Wrong.  Sigh... Order of execution is paramount just about everywhere.
  It can be disastrous if not understood.

You still did not give an example

Remember ***cores!=threads*** people.

Wrong regarding the issue in question (see the message by Jonas).

User programs are not supposed to bother about anything beyond threads 
that are a well defined arch independent paradigm.


-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
You can stick your head in the sand all you want, just don't run your
code on multi-core cpus and expect valid stability - and come back
here complaining on how unstable your multi-threaded application is
due to FPC design!

 User programs are not supposed to bother about anything beyond threads that
 are a well defined arch independent paradigm.

Wrong again... Sigh... Think interlocked variables in your code and
you will be fine.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 10:17 AM, Michael Schnell mschn...@lumino.de wrote:

 You still did not give an example

Don't take my word.  Just look at the wikipedia link I already posted
which indicates otherwise.


 Remember ***cores!=threads*** people.

 Wrong regarding the issue in question (see the message by Jonas).

I'm at a loss for words.  So you equate threads to cores?

You know what forget it.  Don't bother.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Vinzent Höfler
On Tue, 28 Jun 2011 15:54:35 +0200, Michael Schnell mschn...@lumino.de  
wrote:



But if you do the same with

volatile static int x;

the code will stay and another thread can watch x growing in a time  
sharing system.


No, it can't. volatile just ensures that accessing the variable results  
in

actual memory accesses. That does not mean cache-coherence, so another core
may still see other (as in older) values.

I believe that inserting some ptherad_mutex... calls will not force the  
compiler to bother about some intermediate values of a non volatile  
variable.


Well, then it's probably overly aggressive or buggy.

I believe that with FPC global variables are assumed to be volatile and  
not optimized away or cashed in registers. But what about heap-variables  
?


They are not volatile, I'd guess. And I don't see the need to assume they
are. You would always need proper synchronisation constructs here.

Thus true for global variables, not necessary true for static variables  
as they can't be accessed by a function defined in another module (I  
don't know whether the C compiler makes a difference)


It should not. It can't possibly assume that a call to pthread_...()  
wouldn't

result in a recursive call back to the caller... ;)


Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Vinzent Höfler
On Tue, 28 Jun 2011 15:20:22 +0200, Andrew Brunner  
andrew.t.brun...@gmail.com wrote:


On Tue, Jun 28, 2011 at 8:11 AM, Jonas Maebe jonas.ma...@elis.ugent.be  
wrote:



http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html
(point 4.11)


Nope.  Nothing about order - just access - and that is entirely on the
application level - not system.


|synchronize thread execution and also synchronize memory with respect to  
other threads.


How do you interpret synchronise memory with respect to other threads  
then?



Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Hans-Peter Diettrich

Jonas Maebe schrieb:

2.) Blocking access as described in 4.11 does not address execution 
order.


It does guarantee that if T1 locks the mutex, changes the value, unlocks 
the mutex [...]


Can you explain please, to what changes the value applies?

I could not find a definition of the mutex struct, to determine whether 
it contains any user-alterable values. When the value is declared 
outside the mutex struct, it will be accessible also *without* locking 
the mutex first.


However I can imagine that some mutex derived *class* (TCriticalSection) 
can have additional fields, that are inaccessible until some code 
obtains the mutex (similar to TThreadList). Otherwise a mutex cannot 
protect anything but itself.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Hans-Peter Diettrich

Andrew Brunner schrieb:

On Tue, Jun 28, 2011 at 9:23 AM, Jonas Maebe jonas.ma...@elis.ugent.be wrote:

On topic, Jonas can you take a few moments to describe how developers
can force code execution in order w/o using a third party library?  Is
there a compiler directive we can use?


I think that you should give at least an example, where instruction 
reordering makes a difference. Neither a compiler nor a processor is 
allowed to reorder instructions in a way, that breaks the def/use 
(produce/consume...) chain (see SSA - Single Static Assignment).


No library will prevent you from implementing undetectable side-effects, 
or to use alias.


When in this code snippet
  list.Add(x);
  i := list.Count;
the statements cannot be executed out-of-sequence, or in parallel, then 
I assume that every subroutine call will disallow to move instructions 
from after the call to before it. Everything else would be insane.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Hans-Peter Diettrich

Michael Schnell schrieb:

Only the ordering decision inside vs outside of the critical section 
is necessary for threaded user application. If both Enter and Leave do a 
full fence barrier, I suppose we are safe.


Since the condition is only stored *inside* the CS or mutex, no other 
code will know about it, unless it *explicitly* queries the state of the 
object.


When you have a look at TThreadList.LockList/UnlockList, then you'll see 
that LockList enters the critical section, and UnlockList leaves it. All 
code executed in between such two calls is absolutely ignorant of the 
state of the CS, there is no in/outside.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Nikolai Zhubr

28.06.2011 19:42, Hans-Peter Diettrich wrote:

Jonas Maebe schrieb:


2.) Blocking access as described in 4.11 does not address execution
order.


It does guarantee that if T1 locks the mutex, changes the value,
unlocks the mutex [...]


Can you explain please, to what changes the value applies?

To some variable, not explicitly named here, but not to the mutex.



I could not find a definition of the mutex struct, to determine whether
it contains any user-alterable values. When the value is declared
outside the mutex struct, it will be accessible also *without* locking
the mutex first.
A mutex is usually treated as opaque. It is only used when 
entering/leaving critical section, not for storing any user-accessible data.




However I can imagine that some mutex derived *class* (TCriticalSection)
can have additional fields, that are inaccessible until some code
obtains the mutex (similar to TThreadList). Otherwise a mutex cannot
protect anything but itself.
It is responsibility of a programmer to ensure that all accesses to the 
variable in question is surrounded by proper enter/leave constructs 
involving some mutex. Such proper constructs are not enforced by pascal 
language automatically (like say in java), so mistakes are quite 
possible (and sometimes do happen).


Nikolai



DoDi

___
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel




___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Vinzent Höfler
On Tue, 28 Jun 2011 20:09:18 +0200, Hans-Peter Diettrich  
drdiettri...@aol.com wrote:


When you have a look at TThreadList.LockList/UnlockList, then you'll see  
that LockList enters the critical section, and UnlockList leaves it. All  
code executed in between such two calls is absolutely ignorant of the  
state of the CS, there is no in/outside.


Of course, why should it bother? The call to unlock should ensures  
whatever

memory synchronisation is required.


Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Vinzent Höfler
On Tue, 28 Jun 2011 18:11:29 +0200, Hans-Peter Diettrich  
drdiettri...@aol.com wrote:


I think that you should give at least an example, where instruction  
reordering makes a difference. Neither a compiler nor a processor is  
allowed to reorder instructions in a way, that breaks the def/use  
(produce/consume...) chain (see SSA - Single Static Assignment).


Well, yes. But multiple processors are actually allowed to do that.

That's why the double-lock idiom for Singletons is bound to break on
multi-cores.


Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Vinzent Höfler
On Tue, 28 Jun 2011 20:34:19 +0200, Nikolai Zhubr n-a-zh...@yandex.ru  
wrote:


involving some mutex. Such proper constructs are not enforced by pascal  
language automatically (like say in java), so mistakes are quite  
possible (and sometimes do happen).


JFTR, but they aren't /enforced/ in Java, neither.


Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Sven Barth
At beginning of June I've found the following link on the ReactOS 
mailing list when they were discussing about memory ordering and 
volatile as well: 
http://kernel.org/doc/Documentation/volatile-considered-harmful.txt


For those interested the following is the link to the starting 
discussion: 
http://www.reactos.org/archives/public/ros-dev/2011-June/014277.html (I 
hope the mail thread works in the web view as well as in my mail client)


Regards,
Sven

On 28.06.2011 13:14, Michael Schnell wrote:

A similar discussion is going on in Lazarus-develop, but this obviously
is a compiler question.


In C, there is the volatile keyword that ensures that after the code
sequence enters the next C instruction after that which modified this
variable, another thread sees the correct state of the variable.

This is ensured by not caching the value in registers and on SMP systems
additionally by low level stuff like memory barriers.

Of course this does not protect concurrent read-modify-write accesses
(same need to be protected by low level atomic instructions or MUTEX and
friend).

For variables not defined as volatile, (e.g.) pthread_mutex (and similar
stuff on Windows) can be used to protect them.

AFAIK, in Pascal all Global (Static) variables are considered to be
handled as volatile, so no problem here (other than handling all of them
them as volatiles might decrease performance slightly).

But what about variables on the heap ? If class instance variables or -
say - a liked list done with records created by new are accessed by
multiple threads, how can said consistency be enforced ?

Even if you use a critical section to do the protection, this does not
help if the compiler decides to cache the variable in a register while
entering or exiting the critical section.

But even without dedicated protection, a volatile variable should be
able to be be monitored from another thread. Can this be enforced in
Pascal for help variables ?

-Michael
___
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Nikolai Zhubr

28.06.2011 22:38, Vinzent Höfler wrote:

involving some mutex. Such proper constructs are not enforced by
pascal language automatically (like say in java), so mistakes are
quite possible (and sometimes do happen).


JFTR, but they aren't /enforced/ in Java, neither.
Well, ok, I didn't mean that synchronize is enforced, but rather that 
it is provisioned with such (simple) syntax that enforces some sanity 
and hides most complications (so that one can not forget to leave the 
protected block, or try to use some invalid mutex or try to modify the 
mutex directly etc...)


(That said, I'm personally quite happy with pascal though)

Nikolai



Vinzent.
___
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel




___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Hans-Peter Diettrich

Andrew Brunner schrieb:

On Tue, Jun 28, 2011 at 9:43 AM, Michael Schnell mschn...@lumino.de wrote:

On 06/28/2011 04:31 PM, Andrew Brunner wrote:

 how developers
can force code execution in order w/o using a third party library?

Execution in order only makes sense when there is another thread that relies
on this order.


Wrong.  Sigh... Order of execution is paramount just about everywhere.
 It can be disastrous if not understood.
Remember ***cores!=threads*** people.


If your experience is really that chaotic, I think it's worth some 
deeper investigation.


1) Can one thread be executed on multiple cores, at the same time?

If so, shouldn't there exist means (flags...) to tell the OS, that FPC 
executables are not (yet) ready for such automatic parallelism?


2) When a thread wanders around, from one core to another one, shouldn't 
be the starting conditions (CPU state, caches) exactly in the state when 
the thread was stopped on the previous core?


Isn't that effect caused by your monitor, that forces the thread into 
suspended state frequently?


You seem to assume that the cache of the previous core may contain some 
updated data, that was not yet written back into RAM when the thread is 
resumed on a different core, whose cache happens to contain other 
values? This really would be a very big problem :-(

[So big that I cannot believe that it really exists]

3) When above cache inconsistencies can occur, how can even a 
single-threaded program work correctly?


A little chance exists, that an thread moves so often between two cores, 
that both caches contain copies of the process-local data. But this 
never should cause trouble, because single-threaded code was never 
required to use Interlocked access to its private data.


3.1) Chances are higher for a multi-threaded application, where the 
caches can contain any number of copies of shared (main thread) memory 
areas.


But what would this mean to threaded code in general? I cannot believe 
that thread-aware code must use Interlocked access to *all* variables, 
even in the main thread, because no procedure can know from which thread 
it is actually called, in which core.



That said I have some doubts, regarding your conclusions. Can you run 
your test again, assuring that only one thread can access the list at 
the same time, but *without* the Interlocked updates?


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Hans-Peter Diettrich

Vinzent Höfler schrieb:
On Tue, 28 Jun 2011 15:54:35 +0200, Michael Schnell mschn...@lumino.de 
wrote:



But if you do the same with

volatile static int x;

the code will stay and another thread can watch x growing in a time 
sharing system.


No, it can't. volatile just ensures that accessing the variable 
results in

actual memory accesses. That does not mean cache-coherence, so another core
may still see other (as in older) values.


I dare to disagree. When reading a volatile variable requires a memory 
(RAM) read in one core, it will require the same read in any other core, 
and updates have to occur in write-through into the RAM.


A difference could occur only, when the memory access may end up in 
the cache instead of in RAM. Question is, what makes one variable use 
read/write-through, while other variables can be read from the cache, 
with lazy-write? Is this a compiler requirement, which has to enforce 
read/write-through for all volatile variables? But if so, which 
variables (class fields...) can ever be treated as non-volatile, when 
they can be used from threads other than the main thread?


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Hans-Peter Diettrich

Andrew Brunner schrieb:

On Tue, Jun 28, 2011 at 9:33 AM, Michael Schnell mschn...@lumino.de wrote:


And this has been discussed in the other message: If the variable in fact is
global the compiler needs to avoid caching it, if it is static and the
function is in another module it might still decide to cache it, but you are
right: it is not likely that it does make this difference.


Well, I think one issue is that each core has it's own cache.

1.) How can we get the core to not relent and have the code handed off
to another core until we're finished?


Never, in a preemptive multi-tasking environment.
It's easier to *encourage* such swapping, by inserting Sleep calls.


2.) How can we get the core to have a synchronised copy of a
particular variable (aside from CAS)?


How can we get *unsynchronized* copies of the same variable, to prove 
the need for explicit synchronization? And how to prove that the copies 
*are* different, with means that do not happen to enforce synchronicity 
themselves?


Please note that we'll have to restrict the sample code in a way, that 
leaves *no* room for *accidental* concurrent access, bypassing the 
one-thread-only access protection.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] volatile variables

2011-06-28 Thread Vinzent Höfler
On Tue, 28 Jun 2011 23:29:52 +0200, Hans-Peter Diettrich  
drdiettri...@aol.com wrote:



Vinzent Höfler schrieb:

 No, it can't. volatile just ensures that accessing the variable  
results in
actual memory accesses. That does not mean cache-coherence, so another  
core may still see other (as in older) values.


I dare to disagree. When reading a volatile variable requires a memory  
(RAM) read in one core, it will require the same read in any other core,  
and updates have to occur in write-through into the RAM.


Sorry, no. Memory access does not mean RAM here, it simply means that the
compiler is not allowed to keep the value in a register or collapse  
multiple
writes to the same location into a single one. (Ages ago, this happened to  
me

on a memory-mapped i8254, where the counter register requires two 8-bit
accesses to the same (memory-mapped) address and the compiler simply  
removed

the first write).

So, memory access /might/ be the local cache of the core, unless the actual
memory region is write-through (because it's memory-mapped I/O, which was
the original intent of volatile. See above.).

A difference could occur only, when the memory access may end up in  
the cache instead of in RAM.


But that's precisely what would happen.

Question is, what makes one variable use read/write-through, while other  
variables can be read from the cache, with lazy-write?


Synchronisation. Memory barriers. That's what they are for.

Is this a compiler requirement, which has to enforce read/write-through  
for all volatile variables?


No. volatile (at least in C) does not mean that. It was never intended
for synchronisation between threads, cores, or even multiple processors.

This is a misconception probably stemming from the fact that it was used
to synchronise accesses to global variables within interrupt-handlers
and the like where this is totally valid as long as there's only one single
processor running all the code. The picture immediately changes if such an
interrupt-handler (e.g. another thread) is executed on a different
processor/core/whatchamacallit.

But if so, which variables (class fields...) can ever be treated as  
non-volatile, when they can be used from threads other than the main  
thread?


Without explicit synchronisation? Actually, none.


Vinzent.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel