Re: [fpc-pascal] Compiling the compiler
Vincent Snijders wrote: Andreas Berger schreef: Andreas Berger wrote: I have a problem compiling the compiler. After a lot of compilation it attempts to compile pp.pas and I get the following error: pp.pas(213,1) Error: Entrypoint start not defined. I downloaded todays snapshot and had the same problem. Then I compiled using "make all" + "make install" instead of "make cycle" and it worked. Is this correct? What does "make cycle" do exactly? There is at least one difference. If you do make cycle in the compiler directory, the fpc.cfg file is used. If you do make all or make compiler_cycle in the fpc source directory (that contains a compiler subdirectory), then no fpc.cfg file is used. So maybe you should try make cycle OPT="-n" Sorry, it gave the same error. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Compiling the compiler
I am using the v20 base compiler with the v21 source. It should create a v21 compiler. I get the same error compiling under DOS, Win98 and Win2K Regards, Andreas Lee, John wrote: This is a known error - I get it too - but I only get when using the v2.1.1 compiler to start make. Do you get it when starting with the v2.0.2 release compiler released too? What about trying a snapshot of v20 compiler eg base_go32_v20.zip or similar. You can get more info with "opt=-va" on CL - If there is any more useful info in that send the lines to us. What system are you using for these makes? Dos? Win9x? I have a problem compiling the compiler. After a lot of compilation it attempts to compile pp.pas and I get the following error: pp.pas(213,1) Error: Entrypoint start not defined. Regards, Andreas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] linking an fpc .o file without common symbols?
At 22:18 24-7-2006, you wrote: I'm new to free-pascal, and have searched for a few hours without finding an answer to my question. I hope someone on the list could please help point me in the right direction. I've been using a couple of encryption/decryption units that are written in Pascal that I've been using in a userspace networking tool for some time. For performance reasons, I want to move those routines out of userspace and implement an iptables match (Linux kernel module) and invoke the pascal routine. After much trial and error, I have successfully compiled a Linux kernel module, my fpc-generated .o file, system.o and objpas.o together. However, when I load the module, the kernel refuses it because it contains common symbols, and suggests that I recompile with the "-fno-common" flag (gcc flag?). After some research, nm system.o shows 30 or so symbols marked as ' C ', for common. Is there any way for me to tell the fpc compiler to re-compile system.o and initialize the 30 or so symbols so that they won't be marked as "common"? There is no option for it. Peter ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
RE: [fpc-pascal] Compiling the compiler
This is a known error - I get it too - but I only get when using the v2.1.1 compiler to start make. Do you get it when starting with the v2.0.2 release compiler released too? What about trying a snapshot of v20 compiler eg base_go32_v20.zip or similar. You can get more info with "opt=-va" on CL - If there is any more useful info in that send the lines to us. What system are you using for these makes? Dos? Win9x? Regards John > -Original Message- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] Behalf Of Andreas > Berger > Sent: 24 July 2006 23:29 > To: FPC-Pascal users discussions > Subject: Re: [fpc-pascal] Compiling the compiler > > > I have a problem compiling the compiler. After a lot of > compilation it > attempts to compile pp.pas and I get the following error: > pp.pas(213,1) Error: Entrypoint start not defined. > > Regards, > Andreas > > ___ > fpc-pascal maillist - fpc-pascal@lists.freepascal.org > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
On Tuesday 25 July 2006 14:51, Micha Nelissen wrote: > Vinzent Hoefler wrote: > > Ok, there's a glitch: The read and write of self.ThreadId is > > required to be atomic, so that a thread entering may either see "0" > > or the owner's thread id when checking, otherwise it could be > > possible, it sees its own thread_id due to a partial update and > > *then* it goes really wrong. > > It's not a glitch but an assumption I'd say. Well, it will become a glitch, if the assumption about the atomic read/ write turns out to be wrong. ;-) > The compiler devels should be able to answer whether we can assume > this, or not ? Well, I suppose so. But in the end it depends on the target architecture, not the compiler in general. That's BTW, one of the reasons I'd like to have a Pascal's equivalent of Ada's "Pragma Atomic(...)" and "Pragma Volatile(...)" for certain types and variables. Vinzent. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
Vinzent Hoefler wrote: > Ok, there's a glitch: The read and write of self.ThreadId is required to > be atomic, so that a thread entering may either see "0" or the owner's > thread id when checking, otherwise it could be possible, it sees its > own thread_id due to a partial update and *then* it goes really wrong. It's not a glitch but an assumption I'd say. The compiler devels should be able to answer whether we can assume this, or not ? Micha ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Initializing threading
On Tue, 25 Jul 2006, Andreas Berger wrote: In order to initialize threading under DOS I must create a separate unit since I need the initialization and finalization clause. I thought of using a cthreads.pp unit like in unix. However, the TThread implementation resides in the TThread.inc file which is an include in the implementation section of the system.pp unit which is always loaded. This is not correct. TThread is in the classes unit. This causes the following problem: If someone creates a TThread, the constructor does not know if threading has been initialized (via cthreads) since I can not add a "uses cthreads" clause in the .inc file. Does anyone have any idea how I can resolve this? You don't need to resolve this. The application will stop with an error if you forget to add cthreads and try to start a thread. There is nothing else it can do. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Initializing threading
On Tuesday 25 July 2006 14:18, Andreas Berger wrote: > In order to initialize threading under DOS I must create a separate > unit since I need the initialization and finalization clause. I > thought of using a cthreads.pp unit like in unix. However, the > TThread > implementation resides in the TThread.inc file which is an include in > the implementation section of the system.pp unit which is always > loaded. AFAIR the TThread implementation makes use of the ThreadManager (it calls BeginThread and all that stuff). > This causes the following problem: If someone creates a > TThread, the constructor does not know if threading has been > initialized (via cthreads) since I can not add a "uses cthreads" > clause in the .inc file. > > Does anyone have any idea how I can resolve this? Initialize is it in the BeginThread subroutine of your ThreadManager as it is done for all other targets that need special initialization. There is a global variable System.IsMultThread for exactly that purpose, I think. Vinzent. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Initializing threading
In order to initialize threading under DOS I must create a separate unit since I need the initialization and finalization clause. I thought of using a cthreads.pp unit like in unix. However, the TThread implementation resides in the TThread.inc file which is an include in the implementation section of the system.pp unit which is always loaded. This causes the following problem: If someone creates a TThread, the constructor does not know if threading has been initialized (via cthreads) since I can not add a "uses cthreads" clause in the .inc file. Does anyone have any idea how I can resolve this? regards, Andreas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] TThreadManager
On Tue, 25 Jul 2006, Andreas Berger wrote: What is this for? Although most threading implementations set this record, it does not seem to be used by the system. It is most definitely used by the system :-) All systhrdh.inc(systhrd.inc) functions use it. The only implementation that even calls the functions set is the unix implementation, and it does it internally. The implementation is general. Do I need to use this if I implement threading in DOS? Yes. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] TThreadManager
What is this for? Although most threading implementations set this record, it does not seem to be used by the system. The only implementation that even calls the functions set is the unix implementation, and it does it internally. Do I need to use this if I implement threading in DOS? ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Compiling the compiler
Andreas Berger schreef: Andreas Berger wrote: I have a problem compiling the compiler. After a lot of compilation it attempts to compile pp.pas and I get the following error: pp.pas(213,1) Error: Entrypoint start not defined. I downloaded todays snapshot and had the same problem. Then I compiled using "make all" + "make install" instead of "make cycle" and it worked. Is this correct? What does "make cycle" do exactly? There is at least one difference. If you do make cycle in the compiler directory, the fpc.cfg file is used. If you do make all or make compiler_cycle in the fpc source directory (that contains a compiler subdirectory), then no fpc.cfg file is used. So maybe you should try make cycle OPT="-n" Vincent ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Compiling the compiler
Andreas Berger wrote: I have a problem compiling the compiler. After a lot of compilation it attempts to compile pp.pas and I get the following error: pp.pas(213,1) Error: Entrypoint start not defined. I downloaded todays snapshot and had the same problem. Then I compiled using "make all" + "make install" instead of "make cycle" and it worked. Is this correct? What does "make cycle" do exactly? ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
Am Dienstag, 25. Juli 2006 11:59 schrieb Vinzent Hoefler: > On Tuesday 25 July 2006 09:04, Burkhard Carstens wrote: > > Am Dienstag, 25. Juli 2006 10:46 schrieb Micha Nelissen: > > > function Recursive_Mutex.Lock:...; > > > begin > > >// Owned by current thread? > > >if CurrentThreadId <> self.ThreadId then > > >begin > > > result := pthread_mutex_lock (self...); > > > if result <> 0 then exit; > > > self.ThreadId := CurrentThreadId; > > > self.Count := 1; > > >end else begin > > > Inc(self.Count); > > >end; > > >result := SUCCESS; > > > end {Mutex.Lock}; > > > > > > function Recursive_Mutex.Unlock: ...; > > > begin > > > if CurrentThreadId <> self.ThreadId then > > > exit(ENOTOWN); > > > assert(self.Count > 0); > > > dec(self.Count); > > > if self.Count = 0 then > > > begin > > > self.ThreadId := 0; // a threadid that does not occur in > > > system pthread_mutex_unlock(self...); > > > end; > > > result := SUCCESS; > > > end; > > > > > > I don't see the need for Owner_Check_Lock anymore ? :-) > > > > You have to prevent that 2 concurrent threads call lock > > simultanously, > > No. That's not a problem. See the explanation below. > > Perhaps the line "if result <> 0 then exit;" may be kind of > superfluous, or even dangerous, because it would return from the lock > operation without actually locking it, but well - if it goes wrong > here, we're screwed anyway. At least the caller could check, if it > did. > > > so you have to take an internal lock before touching > > internal vars like self.ThreadID ? > > First I thought that, too. But after looking at and thinking about it > a while, the race you mention could only occur if the *same* thread > would call Lock() simultaneously, and that can't happen. > > In the case two different threads enter here, they may both still see > "0" and are trying to continue then, but only one of them will > acquire the mutex sucessfully, leaving the other suspended. Once the > suspended thread continues, it actually owns the mutex, so > everything's ok then. > > Ok, there's a glitch: The read and write of self.ThreadId is required > to be atomic, so that a thread entering may either see "0" or the > owner's thread id when checking, otherwise it could be possible, it > sees its own thread_id due to a partial update and *then* it goes > really wrong. To prevent this very rare but indeed possible case, just use interlockedexchange to assign anything to self.threadid ? Beside this, I like this implementation! This way, we have a recursive mutex, without depending on pthread recursive extension. Burkhard ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
On Tuesday 25 July 2006 08:46, Micha Nelissen wrote: > Vinzent Hoefler wrote: > >> Ehm, no. > > > > Ehm, yes. I was being ironic here. Of course, the action of > > checking the counter and locking/unlocking the associated mutex > > must be atomic. > > But here they are not associated, they're protected by owner_lock, as > you said. Yes. That's what would have made the whole operation atomic. > I mean the idea for the recursive locking is ok. Well, in the end it's functionality that counts. Ideas I got. Lots. > I was confused by the whole 'owning' part. Locks don't own threads in > my mind, so I assumed you got that right. Yes, that's right, locks don't own threads. But threads own locks. :) > Alas, no :-). Also problematic is posting > only partly updates to a function. Then we forget the other, also > critical part. Yepp. It wasn't yet meant to be committed to svn, you know? ;) > function Recursive_Mutex.Lock:...; [...] > > function Recursive_Mutex.Unlock: ...; [...] > > I don't see the need for Owner_Check_Lock anymore ? :-) Yes, that looks about right. ;-) Except perhaps for the possible glitch I mentioned in my other mail. Don't know, if we can ignore it for now or simply assume that (up to) 32-Bit-variables always *are* atomic types. Vinzent. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
On Tuesday 25 July 2006 09:04, Burkhard Carstens wrote: > Am Dienstag, 25. Juli 2006 10:46 schrieb Micha Nelissen: > > > function Recursive_Mutex.Lock:...; > > begin > >// Owned by current thread? > >if CurrentThreadId <> self.ThreadId then > >begin > > result := pthread_mutex_lock (self...); > > if result <> 0 then exit; > > self.ThreadId := CurrentThreadId; > > self.Count := 1; > >end else begin > > Inc(self.Count); > >end; > >result := SUCCESS; > > end {Mutex.Lock}; > > > > function Recursive_Mutex.Unlock: ...; > > begin > > if CurrentThreadId <> self.ThreadId then > > exit(ENOTOWN); > > assert(self.Count > 0); > > dec(self.Count); > > if self.Count = 0 then > > begin > > self.ThreadId := 0; // a threadid that does not occur in system > > pthread_mutex_unlock(self...); > > end; > > result := SUCCESS; > > end; > > > > I don't see the need for Owner_Check_Lock anymore ? :-) > > You have to prevent that 2 concurrent threads call lock > simultanously, No. That's not a problem. See the explanation below. Perhaps the line "if result <> 0 then exit;" may be kind of superfluous, or even dangerous, because it would return from the lock operation without actually locking it, but well - if it goes wrong here, we're screwed anyway. At least the caller could check, if it did. > so you have to take an internal lock before touching > internal vars like self.ThreadID ? First I thought that, too. But after looking at and thinking about it a while, the race you mention could only occur if the *same* thread would call Lock() simultaneously, and that can't happen. In the case two different threads enter here, they may both still see "0" and are trying to continue then, but only one of them will acquire the mutex sucessfully, leaving the other suspended. Once the suspended thread continues, it actually owns the mutex, so everything's ok then. Ok, there's a glitch: The read and write of self.ThreadId is required to be atomic, so that a thread entering may either see "0" or the owner's thread id when checking, otherwise it could be possible, it sees its own thread_id due to a partial update and *then* it goes really wrong. Vinzent. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] enlarge or shrink a TRect by x pixels
That's the one!! Thanks. Graeme. On 7/25/06, Micha Nelissen <[EMAIL PROTECTED]> wrote: Graeme Geldenhuys wrote: > Hi, > > For the life of me I cant remember what the functions are called to > enlarge or shrink a TRect by x pixels. Can anybody help me out? (I > know there was such functions in Delphi) InflateRect ? Micha ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal -- There's no place like 127.0.0.1 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] enlarge or shrink a TRect by x pixels
Graeme Geldenhuys wrote: > Hi, > > For the life of me I cant remember what the functions are called to > enlarge or shrink a TRect by x pixels. Can anybody help me out? (I > know there was such functions in Delphi) InflateRect ? Micha ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] enlarge or shrink a TRect by x pixels
Hi, For the life of me I cant remember what the functions are called to enlarge or shrink a TRect by x pixels. Can anybody help me out? (I know there was such functions in Delphi) Regards, Graeme. -- There's no place like 127.0.0.1 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
[...] coffee, pencil and stuff ;-) off course, the local procedure "internalEnter" in Leave is a copy'n'paste rubbish. Just remove .. TCriticalSection.Leave; begin internal.lock; try if OwnerThread <> GetCurrentThreadID then begin //we are not // allowed to leave, because we don't own it! raise exception.create('leave on a foreign critical section'); end else begin //we are the owner if fLockCount = 0 then begin raise exception.create('leave on a unlocked section'); end else begin dec(fLockCount); if fLockCount=0 then rtlSetEvent(fExternalLock); end; end; finally internal.unlock; end; end; ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
Burkhard Carstens wrote: >> I don't see the need for Owner_Check_Lock anymore ? :-) > > You have to prevent that 2 concurrent threads call lock simultanously, No, why? > so you have to take an internal lock before touching internal vars like > self.ThreadID ? No, why ? This is a common misconception I think. (Multi-threaded) Programs are about state, not about touching internal variables. Micha ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
Am Dienstag, 25. Juli 2006 10:46 schrieb Micha Nelissen: > Vinzent Hoefler wrote: > >> Ehm, no. > > > > Ehm, yes. I was being ironic here. Of course, the action of > > checking the counter and locking/unlocking the associated mutex > > must be atomic. > > But here they are not associated, they're protected by owner_lock, as > you said. > > >> Got confused a bit :-). Reread the thread, and think your > >> latest implementation as posted here is ok. > > > > No, it's not. As usually I should sit down with pencil, paper, a > > cup of > > I mean the idea for the recursive locking is ok. I was confused by > the whole 'owning' part. Locks don't own threads in my mind, so I > assumed you got that right. Alas, no :-). Also problematic is posting > only partly updates to a function. Then we forget the other, also > critical part. > > function Recursive_Mutex.Lock:...; > begin >// Owned by current thread? >if CurrentThreadId <> self.ThreadId then >begin > result := pthread_mutex_lock (self...); > if result <> 0 then exit; > self.ThreadId := CurrentThreadId; > self.Count := 1; >end else begin > Inc(self.Count); >end; >result := SUCCESS; > end {Mutex.Lock}; > > function Recursive_Mutex.Unlock: ...; > begin > if CurrentThreadId <> self.ThreadId then > exit(ENOTOWN); > assert(self.Count > 0); > dec(self.Count); > if self.Count = 0 then > begin > self.ThreadId := 0; // a threadid that does not occur in system > pthread_mutex_unlock(self...); > end; > result := SUCCESS; > end; > > I don't see the need for Owner_Check_Lock anymore ? :-) You have to prevent that 2 concurrent threads call lock simultanously, so you have to take an internal lock before touching internal vars like self.ThreadID ? Burkhard ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
Am Montag, 24. Juli 2006 23:38 schrieb Vinzent Höfler: > Vinzent Höfler wrote: > > Hmm. So we'd need a mutex inside a mutex. Now I know why they call > > it recursive. ;) So it'll be something like that: > > > > function Recursive_Mutex.Lock : ...; > > begin > >// Lock mutex inside mutex. > >self.Owner_Check_Lock.Lock; > > > >// Owned by current thread? > >if CurrentThreadId <> self.ThreadId then > >begin > > // Nope! Get the hell outta here. > > self.Owner_Check_Lock.Unlock; > > exit (NOT_OWNED); > >end {if}; > > > >// Now try locking the real mutex. > >if pthread_mutex_lock (self...) = 0 then > >begin > > self.Count := self.Count + 1; > > self.Owner_Check.Unlock; > > exit (SUCCESS); > >end {if}; > > > >self.Owner_Check.Unlock; > >exit (FAILURE); > > end {Mutex.Lock}; > > > > Something like that. Don't nail me on that, it's quite late and the > > heat is still killing me. ;) > > I knew it. Of course this is wrong. We can only lock the mutex once, > because we assume it's non-recursive, that was the whole point. So we > should *first* check the count and then may lock/unlock the mutex > accordingly. * It's early, and I didn't dink enough coffee yet, so excuse me, if I overlook something ;-) some points: * In windows, I never used mutexes, as I didn't see the point. Usually, CriticalSections do what I want, except for IPC ... So I don't know if windows mutexes are recursive. However, IMO a CriticalSection should be recursive, so I stick to it here * pthread-Mutexes may not be used asynchronously (signal handlers are mentioned in the man page), so if we take that as basic rule, things get pretty simple: the same code is never executed simultanously from the same thread. * rtleventStartWait should have a counterpart rtlEventDoneWait, which unlocks the internal mutex of a rtlevent. * rtlWaitEvent should get a parameter telling it whether to call rtlEventDoneWait or not. (currently, it simply does it) * protect any method of a TCriticalSection with a internal critical section (a simple, non-recursive form should do the job) TCriticalSection.Enter; procedure internalEnter; begin OwnerThread:=GetCurrentThreadID; fLockCount:=1; ExternelLock.lock; end; begin internal.lock; if OwnerThread = 0 then begin //not locked yet internalEnter; end else begin //allready locked if OwnerThread=GetCurrentThreadID then //we are the owner inc(fLockCount) else begin //other thread owns the cs rtlEventStartWait(fExternalLock); internallock.unlock; rtlEventWaitFor(fExternalLock,DontAutoReleaseRTLEventMutex); internalLock.lock; rtlEventDoneWait(fExternalLock); internalEnter; end; end; internal.unlock; end; TCriticalSection.Leave; procedure internalEnter; begin OwnerThread:=GetCurrentThreadID; fLockCount:=1; ExternelLock.lock; end; begin internal.lock; try if OwnerThread <> GetCurrentThreadID then begin //we are not allowed //to leave, because we don't own it!not locked yet raise exception.create('leave on a foreign critical section'); end else begin //we are the owner if fLockCount = 0 then begin raise exception.create('leave on a unlocked section'); end else begin dec(fLockCount); if fLockCount=0 then rtlSetEvent(fExternalLock); end; end; finally internal.unlock; end; end; * just a quick draft. This one should be pretty much the same as a recursive mutex, i think .. * have to leave now, bbl. Maybe we meet in IRC later and/or setup a wiki page about this topic to collect and discuss proposals Regards, Burkhard ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
Vinzent Hoefler wrote: >> Ehm, no. > > Ehm, yes. I was being ironic here. Of course, the action of checking the > counter and locking/unlocking the associated mutex must be atomic. But here they are not associated, they're protected by owner_lock, as you said. >> Got confused a bit :-). Reread the thread, and think your >> latest implementation as posted here is ok. > > No, it's not. As usually I should sit down with pencil, paper, a cup of I mean the idea for the recursive locking is ok. I was confused by the whole 'owning' part. Locks don't own threads in my mind, so I assumed you got that right. Alas, no :-). Also problematic is posting only partly updates to a function. Then we forget the other, also critical part. function Recursive_Mutex.Lock:...; begin // Owned by current thread? if CurrentThreadId <> self.ThreadId then begin result := pthread_mutex_lock (self...); if result <> 0 then exit; self.ThreadId := CurrentThreadId; self.Count := 1; end else begin Inc(self.Count); end; result := SUCCESS; end {Mutex.Lock}; function Recursive_Mutex.Unlock: ...; begin if CurrentThreadId <> self.ThreadId then exit(ENOTOWN); assert(self.Count > 0); dec(self.Count); if self.Count = 0 then begin self.ThreadId := 0; // a threadid that does not occur in system pthread_mutex_unlock(self...); end; result := SUCCESS; end; I don't see the need for Owner_Check_Lock anymore ? :-) Micha ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
On Tuesday 25 July 2006 07:46, Micha Nelissen wrote: > Vinzent Hoefler wrote: > > On Tuesday 25 July 2006 06:40, Micha Nelissen wrote: > >> Vinzent Höfler wrote: > >>> because we assume it's non-recursive, that was the whole point. > >>> So we should *first* check the count and then may lock/unlock the > >>> mutex accordingly. > >> > >> Note that these two actions must be atomic. > > > > Oh, really? > > Ehm, no. Ehm, yes. I was being ironic here. Of course, the action of checking the counter and locking/unlocking the associated mutex must be atomic. > Got confused a bit :-). Reread the thread, and think your > latest implementation as posted here is ok. No, it's not. As usually I should sit down with pencil, paper, a cup of coffee and a cigarette before writing code. Anything else is hacking and takes more time and changes. (Why the hell don't I listen to myself?) Despite the fact that some minor details may be still missing, like setting the owner's ThreadId, for example, this implementation has one very major flaw. It doesn't suspend the calling thread if it's not already owned by it and if it is, it doesn't do that either, becaus it shouldn't. That makes it kind of useless, I think. :) Instead of exiting with (NOT_OWNED) the mutex should be locked, of course. But before doing that, the Owner_Check_Lock must be released. And now I start smelling a race condition. Back to the drawing board, I guess. Vinzent. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
Vinzent Hoefler wrote: > On Tuesday 25 July 2006 06:40, Micha Nelissen wrote: >> Vinzent Höfler wrote: >>> because we assume it's non-recursive, that was the whole point. So >>> we should *first* check the count and then may lock/unlock the >>> mutex accordingly. >> Note that these two actions must be atomic. > > Oh, really? Ehm, no. Got confused a bit :-). Reread the thread, and think your latest implementation as posted here is ok. Micha ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Semaphore problems
On Tuesday 25 July 2006 06:40, Micha Nelissen wrote: > Vinzent Höfler wrote: > > because we assume it's non-recursive, that was the whole point. So > > we should *first* check the count and then may lock/unlock the > > mutex accordingly. > > Note that these two actions must be atomic. Oh, really? > This is what the TryLock is for. No, that's what the "Owner_Check_Lock" in my posted code would be for in the first place. But you're right, TryLock makes it possibly easier to detect/handle failures. So the code from > // Now try locking the real mutex. should actually be more like: |// First encounter? So lock it actually. |if self.Count = 0 then |begin | // This should *always* succeed, because we're the owning | // thread (we've just checked it, right?) and we didn't lock it | // yet according to "Count". | // Thinkable ways how this can fail is if somebody has direct | // access to the actual pthread mutex inside here or we | // fuc^Wmessed up the counter somehow ... | if pthread_mutex_trylock (self...) <> 0 then | // Our real mutex couldn't be locked!? This *is* strange. | exit (FAILURE); |end {if}; | |// Alright, we got it. Mutex is locked (or at least, it *should* be |// already), so count up. |self.Count := self.Count + 1; |self.Owner_Check.Unlock; |exit (SUCCESS); A pthread_mutex_trylock alone wouldn't actually help on a non-recursive "real" mutex. Because: if it's already locked I still don't know if it belongs to the current thread, but precisely that knowledge is needed to implement the recursive one on top of a non-recursive. Vinzent. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal