Re: [Lazarus] Weird object variables access - fpc issue?
On 24/10/17 12:59, Mattias Gaertner via Lazarus wrote: > ASystemTime is a stack variable. That's thread-safe. > > In fpc trunk it calls GetLocalTime on Unix, which fetches timezone > every time. No global var. So it should be thread safe. > >> because each thread instance would have its own local variables, right? >> so no thread would step on each others' toes; > > You have to check called code too. > > Mattias > On 24/10/17 13:06, Sven Barth via Lazarus wrote: > > ASystemTime is a local variable, so two threads won't influence each other > there thus at least on Windows Now() is threadsafe. > > Regards, > Sven > > MMMmmm... i can't exactly now but I will try to reproduce what I was seeing ... for now sorry for the noise... el es -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
Am 24.10.2017 13:41 schrieb "el es via Lazarus" < lazarus@lists.lazarus-ide.org>: On 24/10/17 10:04, Mattias Gaertner via Lazarus wrote: > On Tue, 24 Oct 2017 08:59:36 +0100 > el es via Lazarus wrote: > >> On 23/10/17 20:00, Giuliano Colla via Lazarus wrote: >> [snip] >> >> I don't remember if I was hitting AV using Now(), likely I wasn't - >> but due to 'normal' Now() being not thread safe, I was getting inconsistent >> timing results, when I used Now() both in main thread and in the thread; > > AFAIK Now is thread safe. On what platform and how did you test? > > Mattias > Now() is literally function Now : TDateTime; var ASystemTime : TSYSTEMTIME; begin GetSystemTime(ASystemTime); Result := SystemTimeToDateTime(ASystemTime); end; on my installation (lazarus 1.6.4 #54278, FPC 3.0.2) I'd say it's questionable to say it's thread-safe that way; It may be safe to use in main thread (where no 2 different contexts can mangle each others ASystemTime); ASystemTime is a local variable, so two threads won't influence each other there thus at least on Windows Now() is threadsafe. Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On Tue, 24 Oct 2017 12:41:11 +0100 el es via Lazarus wrote: >[...] > Now() is literally > > function Now : TDateTime; > var ASystemTime : TSYSTEMTIME; > begin >GetSystemTime(ASystemTime); >Result := SystemTimeToDateTime(ASystemTime); > end; > > on my installation (lazarus 1.6.4 #54278, FPC 3.0.2) > > I'd say it's questionable to say it's thread-safe that way; It may be safe to > use in > main thread (where no 2 different contexts can mangle each others > ASystemTime); ASystemTime is a stack variable. That's thread-safe. In fpc trunk it calls GetLocalTime on Unix, which fetches timezone every time. No global var. So it should be thread safe. > because each thread instance would have its own local variables, right? > so no thread would step on each others' toes; You have to check called code too. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On 24/10/17 10:04, Mattias Gaertner via Lazarus wrote: > On Tue, 24 Oct 2017 08:59:36 +0100 > el es via Lazarus wrote: > >> On 23/10/17 20:00, Giuliano Colla via Lazarus wrote: >> [snip] >> >> I don't remember if I was hitting AV using Now(), likely I wasn't - >> but due to 'normal' Now() being not thread safe, I was getting inconsistent >> timing results, when I used Now() both in main thread and in the thread; > > AFAIK Now is thread safe. On what platform and how did you test? > > Mattias > Now() is literally function Now : TDateTime; var ASystemTime : TSYSTEMTIME; begin GetSystemTime(ASystemTime); Result := SystemTimeToDateTime(ASystemTime); end; on my installation (lazarus 1.6.4 #54278, FPC 3.0.2) I'd say it's questionable to say it's thread-safe that way; It may be safe to use in main thread (where no 2 different contexts can mangle each others ASystemTime); But I had problems using Now() in main thread context (graphic) and in additional thread(s) _simultaneously_. I do not recall getting AV's, but I was getting mangled results when calls to Now() overlapped from 2 different thread contexts. (try it by calling Now() from a TTimer.OnTimer handler, simultaneously with a background thread also calling Now() in a loop.) I guess, simpler code for ThreadNow would be 'just' thread-local/nested to Execute() function containing just a pair of GetSystemTime(ASystemTime); Result := SystemTimeToDateTime(ASystemTime); (or literally a copy of Now(); ) because each thread instance would have its own local variables, right? so no thread would step on each others' toes; Hopefully this makes sense now ;) el es -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On 24/10/17 10:20, Michael Schnell via Lazarus wrote: > On 24.10.2017 10:48, el es via Lazarus wrote: >> [...] begin repeat until not ThreadNowInUse; // try ThreadNowInUse :=true; >>> > Busy wait actions are usually a very bad idea > > Better use a TTimer for such. > > -Michael > I suppose you'd need to look at the parent/my post, where it's in full code what this function does ;) tl/dr: it's a function that tries to get a time stamp in (maybe less) thread-safe / (I'd rather call it) reentrant way for use in thread timing and profiling. So no, TTimer not appropriate here. :) el es -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On Tue, 24 Oct 2017, Mattias Gaertner via Lazarus wrote: On Tue, 24 Oct 2017 11:11:15 +0200 (CEST) Michael Van Canneyt via Lazarus wrote: [...] From memory: The first call to Now is not necessarily thread-safe, because of the initialization of TZ info ? Please add this to the docs. After I've verified that my memory in this correct in this matter :) I know that there is some late TZ initialization, but I'm not 100% sure whether Now() invokes it. Michael. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On Tue, 24 Oct 2017 11:11:15 +0200 (CEST) Michael Van Canneyt via Lazarus wrote: >[...] > From memory: > The first call to Now is not necessarily thread-safe, because of the > initialization of TZ info ? Please add this to the docs. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On 24.10.2017 11:29, Mattias Gaertner via Lazarus wrote: Are you kidding? If this is not appropriate, I suppose the general design of that functionality should be reconsidered, doing anything that needs a fast reaction in the worker thread. -Michael -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On Tue, 24 Oct 2017 11:20:50 +0200 Michael Schnell via Lazarus wrote: > On 24.10.2017 10:48, el es via Lazarus wrote: > > [...] > >>> begin > >>>repeat > >>>until not ThreadNowInUse; // > >>> > >>>try > >>> ThreadNowInUse :=true; > >> >[...] > Better use a TTimer for such. Are you kidding? Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On 24.10.2017 10:48, el es via Lazarus wrote: [...] begin repeat until not ThreadNowInUse; // try ThreadNowInUse :=true; Busy wait actions are usually a very bad idea Better use a TTimer for such. -Michael -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On Tue, 24 Oct 2017, Mattias Gaertner via Lazarus wrote: On Tue, 24 Oct 2017 08:59:36 +0100 el es via Lazarus wrote: On 23/10/17 20:00, Giuliano Colla via Lazarus wrote: [snip] I don't remember if I was hitting AV using Now(), likely I wasn't - but due to 'normal' Now() being not thread safe, I was getting inconsistent timing results, when I used Now() both in main thread and in the thread; AFAIK Now is thread safe. On what platform and how did you test? From memory: The first call to Now is not necessarily thread-safe, because of the initialization of TZ info ? Michael. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On Tue, 24 Oct 2017 08:59:36 +0100 el es via Lazarus wrote: > On 23/10/17 20:00, Giuliano Colla via Lazarus wrote: > [snip] > > I don't remember if I was hitting AV using Now(), likely I wasn't - > but due to 'normal' Now() being not thread safe, I was getting inconsistent > timing results, when I used Now() both in main thread and in the thread; AFAIK Now is thread safe. On what platform and how did you test? Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
Am 24.10.2017 10:49 schrieb "el es via Lazarus" < lazarus@lists.lazarus-ide.org>: On 24/10/17 09:11, Mattias Gaertner via Lazarus wrote: > On Tue, 24 Oct 2017 08:59:36 +0100 > el es via Lazarus wrote: > >> [...] >> begin >> repeat >> until not ThreadNowInUse; // >> >> try >> ThreadNowInUse :=true; > > This is not thread safe. > > Mattias > Because separated by 'try' ? I see; Will it be enough to put it like try repeat until not ThreadNowInUse; ThreadNowInUse := true; ... ? You should look at InterlockedCompareExchange(), everything else is an accident waiting to happen (except for a critical section, but that would be overkill on the other hand). Regards, Sven I haven't ran into problems with my routine yet, but I wasn't really calling it in a very 'tight loop' (as it is used for timing/'profiling' the calls to hardware 'master node' routines and for deciding whether the thread should go to sleep; so there is always ample time between calls to ThreadNow() and it's only called in context of the thread; so the 'poor mans semaphore' isn't really that required - it's just a safeguard) (probably if I need timing measurements, every other type of thread I will ever define, will have their own ThreadNow call) I realize I could just use 'naked' GetSystemTime + SystemTimeToDateTime pair with a local variable; or define the above pair as a nested function in the thread, that'll serialize it enough... Anyone ever thought of a thread-safe global Now() call ? el es -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On 24/10/17 09:11, Mattias Gaertner via Lazarus wrote: > On Tue, 24 Oct 2017 08:59:36 +0100 > el es via Lazarus wrote: > >> [...] >> begin >> repeat >> until not ThreadNowInUse; // >> >> try >> ThreadNowInUse :=true; > > This is not thread safe. > > Mattias > Because separated by 'try' ? I see; Will it be enough to put it like try repeat until not ThreadNowInUse; ThreadNowInUse := true; ... ? I haven't ran into problems with my routine yet, but I wasn't really calling it in a very 'tight loop' (as it is used for timing/'profiling' the calls to hardware 'master node' routines and for deciding whether the thread should go to sleep; so there is always ample time between calls to ThreadNow() and it's only called in context of the thread; so the 'poor mans semaphore' isn't really that required - it's just a safeguard) (probably if I need timing measurements, every other type of thread I will ever define, will have their own ThreadNow call) I realize I could just use 'naked' GetSystemTime + SystemTimeToDateTime pair with a local variable; or define the above pair as a nested function in the thread, that'll serialize it enough... Anyone ever thought of a thread-safe global Now() call ? el es -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On Tue, 24 Oct 2017 08:59:36 +0100 el es via Lazarus wrote: >[...] > begin > repeat > until not ThreadNowInUse; // > > try > ThreadNowInUse :=true; This is not thread safe. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On 23/10/17 20:00, Giuliano Colla via Lazarus wrote: [snip] I don't remember if I was hitting AV using Now(), likely I wasn't - but due to 'normal' Now() being not thread safe, I was getting inconsistent timing results, when I used Now() both in main thread and in the thread; So with my application I ended up re-implementing Now() into ThreadNow : var ThreadNowInUse :boolean = false; // unit global 'just' above the function function TMyThread.ThreadNow: TDateTime; var ASystemTime : TSYSTEMTIME; // struct.inc, I'm under Windows begin repeat until not ThreadNowInUse; // try ThreadNowInUse :=true; GetSystemTime(ASystemTime); Result := SystemTimeToDateTime(ASystemTime); finally ThreadNowInUse := false; end; end; Hope this helps el es -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
On Mon, 23 Oct 2017 22:50:49 +0200 Giuliano Colla via Lazarus wrote: > Il 23/10/2017 21:33, Sven Barth via Lazarus ha scritto: > > How do you pass the SendMessage() method to your thread? And how does > > the code look that calls it? > > > The SendMessage() method belongs to the main thread only, and is > supposed to execute only in the main thread context. Check if 'Self' inside SendMessage is the right instance. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
Il 23/10/2017 21:33, Sven Barth via Lazarus ha scritto: How do you pass the SendMessage() method to your thread? And how does the code look that calls it? The SendMessage() method belongs to the main thread only, and is supposed to execute only in the main thread context. It fills up a buffer (TBuffer), and sets a SendLen value and an OkToSend boolean to true. The buffer and SendLen are written by the main thread and read from the serial thread. OkToSend is set by the main thread and reset by the serial thread. TBuffer, SendLen and OkToSend are public variables not belonging to any object. The code looks like that: .. TBuffer[J] := Etx; inc(J); SendLen := J; OKToSend := True; if not SendCreated then begin SendCreate; end; if Send.suspended then Send.Resume; Application.ProcessMessages; end; The serial thread checks for OkToSend, sets it to false, and takes care of sending the message and getting an answer. Once it's done it posts a message for the main thread and suspends itself. SendMessage() isn't invoked any more until the serial thread has managed to send the message, and to receive an answer, or the communication has timed out. Giuliano -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] Weird object variables access - fpc issue?
Am 23.10.2017 21:00 schrieb "Giuliano Colla via Lazarus" < lazarus@lists.lazarus-ide.org>: I'm doing something wrong, I'm missing something, or this is just a compiler bug? How do you pass the SendMessage() method to your thread? And how does the code look that calls it? Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
[Lazarus] Weird object variables access - fpc issue?
I have stumbled into what appears to me to be a compiler error, but before I post in the fpc list, I'd like to get expert advice. I have an application already in use since many years, which uses a thread to handle a serial line. I don't know if that second thread is related to the problem or not, but that is what I have. Now, in the main thread, which sends messages and receives answers, I wanted to measure the time from send to receive, therefore I added a TdateTime variable to do the job. The related snippets of code are as follows: TForm1 = class(TForm) procedure SendMessage(Tipo,Lung: Byte); public { Public declarations } LastMsgTime: TDateTime; end; var Form1: TForm1; .. procedure TForm1.SendMessage(Tipo,Lung: Byte); begin ... LastMsgTime:= Now; ... end; Now, whatever I do, with this code, I always get an access violation error for the LastMsgTime variable after a couple of messages have been sent and received. Suspecting that I could have some problems from the serial thread, I tried to change the way the main thread communicates with the main thread. I used a synchronize method to pass information from the serial thread to the main thread; I changed it with a message passing technique, i.e the serial thread uses a PostMessage to Form1.Handle but nothing changed. But I managed to make everything working perfectly if either: 1) I move the variable declaration out from the TForm1 Object type declaration: var Form1: TForm1; LastMsgTime: TDateTime; 2) I change the code in SendMessage like that: procedure TForm1.SendMessage(Tipo,Lung: Byte); begin ... Form1.LastMsgTime:= Now; ... end; Which appears to me to be rather crazy, because to make it work I need to qualify an identifier which doesn't need to be qualified. The assembler generated in for the two cases is different (which IMHO shouldn't be): ULprog.pas:641 LastMsgTime:= Now; 004FB500 e8bbc8feff callq 0x4e7dc0 004FB505 488b45e8 mov -0x18(%rbp),%rax 004FB509 f20f1180d008 movsd %xmm0,0x8d0(%rax) ULprog.pas:641 Form1.LastMsgTime:= Now; 004FB500 e8bbc8feff callq 0x4e7dc0 004FB505 488b050cce5000 mov 0x50ce0c(%rip),%rax # 0xa08318 004FB50C 488b00 mov (%rax),%rax 004FB50F f20f1180d008 movsd %xmm0,0x8d0(%rax) If in the first case I put a breakpont before the offending line, and I move the cursor to the variable name, the debugger tells that it cannot access memory at 0x8d0, in the second case everything works fine and the debugger just shows me the last value of LastMsgTime. I'm doing something wrong, I'm missing something, or this is just a compiler bug? Tested on a Linux platform, both with Lazarus 1.6 - fpc 3.0.0 and Lazarus 1.8 RC5 - fpc 3.1.1 Giuliano -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus