Re: [fpc-pascal] Compiling the compiler

2006-07-25 Thread Andreas Berger

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

2006-07-25 Thread Andreas Berger
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?

2006-07-25 Thread Peter Vreman

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

2006-07-25 Thread Lee, John
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

2006-07-25 Thread Vinzent Hoefler
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

2006-07-25 Thread Micha Nelissen
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

2006-07-25 Thread Michael Van Canneyt



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

2006-07-25 Thread Vinzent Hoefler
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

2006-07-25 Thread Andreas Berger
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

2006-07-25 Thread Michael Van Canneyt



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

2006-07-25 Thread Andreas Berger
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

2006-07-25 Thread Vincent Snijders

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

2006-07-25 Thread Andreas Berger

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

2006-07-25 Thread Burkhard Carstens
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

2006-07-25 Thread Vinzent Hoefler
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

2006-07-25 Thread 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.


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

2006-07-25 Thread Graeme Geldenhuys

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

2006-07-25 Thread Micha Nelissen
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

2006-07-25 Thread Graeme Geldenhuys

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

2006-07-25 Thread Burkhard Carstens
[...]
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

2006-07-25 Thread Micha Nelissen
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

2006-07-25 Thread Burkhard Carstens
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

2006-07-25 Thread Burkhard Carstens
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

2006-07-25 Thread 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 ? :-)

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


Re: [fpc-pascal] Semaphore problems

2006-07-25 Thread Vinzent Hoefler
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

2006-07-25 Thread Micha Nelissen
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

2006-07-25 Thread Vinzent Hoefler
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