Board index » kylix » Re: Kylix now officially alive?

Re: Kylix now officially alive?


2005-01-03 11:43:38 PM
kylix1
Michael Schnell wrote:
Quote
To protect the pointers, the signal would need to be blocked for some
instructions when the top queue entry is taken from the FiFo queue.
A FiFo is not the best solution. My first implementation used a pipe but
that caused lot's of problems with multiple threads. My second (and final)
solution is a double linked list (if I remember correctly) which is
protected by a critical section (because it is limited to a single
process).
Quote
I also don't know how a signal can be used to wake up a sleeping thread,
but I suppose this is possible.
The pthread_kill() function does not return if you send a signal to a
sleeping thread.
--
Regards,
Andreas Hausladen
 
 

Re:Re: Kylix now officially alive?

"Michael Schnell" < XXXX@XXXXX.COM >wrote in message
Quote
>Is the OP wanting all the signalling to happen within a single process?
I
>thought s/he was looking for IPC.
>

The VCL is to be blamed here.
So we have different incompatible sets of inter thread communication
means:
But the question is about Inter-Process Communication, or so I thought. I
don't see how the VCL is a limiting factor in the least. The question is
about IPC, I thought that was from one process to another. All the
discussion seems to be centred around inter-thread communication within a
single process.
For IPC there are other mechanisms that are not reliant on Windows messaging
mechanism; such as pipes (named or otherwise), sockets and shared memory to
name a few.
Rob
 

Re:Re: Kylix now officially alive?

And further to some of the other discussion, my suggestion of using sockets
seems to get better looking all the time...:)
"Robby Tanner" < XXXX@XXXXX.COM >wrote in
message news:41d9ae32$ XXXX@XXXXX.COM ...
Quote

"Michael Schnell" < XXXX@XXXXX.COM >wrote in message
news:41d3096a$ XXXX@XXXXX.COM ...
>>Is the OP wanting all the signalling to happen within a single
process?
I
>>thought s/he was looking for IPC.
>>
>
>The VCL is to be blamed here.
>So we have different incompatible sets of inter thread communication
means:

But the question is about Inter-Process Communication, or so I thought. I
don't see how the VCL is a limiting factor in the least. The question is
about IPC, I thought that was from one process to another. All the
discussion seems to be centred around inter-thread communication within a
single process.

For IPC there are other mechanisms that are not reliant on Windows
messaging
mechanism; such as pipes (named or otherwise), sockets and shared memory
to
name a few.

Rob


 

{smallsort}

Re:Re: Kylix now officially alive?

Quote
And further to some of the other discussion, my suggestion of using sockets
seems to get better looking all the time...:)

AFAIK, Socket are a good IPC tool in Linux, while in Windows Sockets are
quite slow and using messages that carry pointers to shared memory
regions are faster,
-Michael
 

Re:Re: Kylix now officially alive?

"Michael Schnell" < XXXX@XXXXX.COM >wrote in message
Quote
>And further to some of the other discussion, my suggestion of using
sockets
>seems to get better looking all the time...:)
>

AFAIK, Socket are a good IPC tool in Linux, while in Windows Sockets are
quite slow
I didn't know that bit, thanks. Are there some metrics or other discussions
I should review on that.
Quote
and using messages that carry pointers to shared memory
regions are faster,
-Michael
 

Re:Re: Kylix now officially alive?

Quote
>AFAIK, Socket are a good IPC tool in Linux, while in Windows Sockets are
>quite slow
>and using messages that carry pointers to shared memory
>regions are faster,
I didn't know that bit, thanks. Are there some metrics or other discussions
I should review on that.

I only got that from grapevine. I'd be happy to see some metrics, too.
-Michael
 

Re:Re: Kylix now officially alive?

Quote
A FiFo is not the best solution. My first implementation used a pipe but
that caused lot's of problems with multiple threads. My second (and final)
solution is a double linked list (if I remember correctly) which is
protected by a critical section (because it is limited to a single
process).
Hmm. The advantage of a linked list vs a FIF0 (done as cyclicly used
array) is that it can be done in a way that it can grow "infinitely".
But how to do the linked list to make it fast ? Of course you need to
protect the pointer handling. But if you use standard memory allocation
and freeing mechanisms each time to allocate and free the elements, this
will result in another locking by a critical section in the RTL and
cause a lot of memory hole handling activities in the RTL.
Perhaps the FP TList code shows some nice ideas....
- Michael
 

Re:Re: Kylix now officially alive?

On 2005-01-01, Michael Schnell < XXXX@XXXXX.COM >wrote:
Quote
>
>Server has no GUI, client no multiple connections.

Either of GUI or a multiple connection situation could stall the work on
a request or thread when the parts are not decently decoupled.
A threaded solution could reach deadlock. There are no guarantees in programming.
Quote
>That's a problem in theory. However the chance on such a big one is already
>very low, let alone multiple combined, since the largest queries require
>global access, so they can be done only by an administrator anyway.
>(customers only have permission on their little part of the object model)

Here I disagree. I.e. an Indy workalike needs to be able to create a
decent HTTP server. This would handle thousands of concurrent requests.
As long as they don't access a common backend. Then that would be the
bottleneck. If they don't access common backend that are a bottleneck,
forking and doing a small (maximal) amount of connections using select() per
fork is better. The requests are finite in size. Throughput would be higher.
HTTP was originally written for such scheme.
Quote
And a request could result in a database lookup or whatever time
consuming activity. Here timesharing and multiprocessing between the
threads is really essential to keep other connections running.
If the db is a connection is a socket, it would just be one extra socket to wait
on.
Quote
Since some days I am thinking about a related chapter in a book that I
just started to write an am considering to try to publish later this
year. The book is supposed to be on "embedded communication" and the
chapter is on "Multitasking vs. 'run to completion objects' ".
Please add stuff like the remark above. With some tricks and select you can
avoid waiting for databases without blocking the thread _exclusively_ on the
database connection.
Quote
In Delphi language we have both concepts: Multitasking via TThreads and
"run to completion objects" via events. So we are very free here.
If you go for the thread/connection approach, which is the typical (but still
not unique) windows way.
On Unix there is also fork/select, kqueue (FreeBSD, kernel event system),
and epoll on linux. Basically also an event system, however less on IPC
messages but more on activity on file/socket descriptors. I haven't
researched these yet, but they are mainly needed for massive amounts of open
filedescriptors, less interesting for embedded use.
The biggest advantage is that a thread can do multiple connections this way, decreasing
the number of threads by one (and most important) magnitude
Tasks are divided into small stuff that run to completion, and then block
till the next activity on the file/socketdescriptors occur (either client or
backend selectors)
Quote
But when designing an embedded device from scratch, you need to decide if
you want to implement a multitasking OS of some kind. Of course
multitasking needs much more resources (e.g. memory for the stacks) and
it's not easy to do the inter process communication and the necessary
locking decently.
I'm more worried about performance with high connection counts.
Quote
But OTOH if no MT is used, it's not easy to keep the run to completion
code short short enough, you don't have priories.
Moreover with MT you
can write code more "straight forward", as you are allowed to wait for
(e.g. hardware) result in midst your actions.
You have to keep stuff MT and MP safe. Recent troubles with ICS and HT
safety stress that this shouldn't be taken lightly. (only ICS9 after april
is somewhat stable on HT systems. Talking about the webserver)
Quote
BTW.: I understand that you read German well enough. Would you be
inclined to do some proof-reading of the stuff _if_ the book projects
really gets up to speed ?
1. I never proofread books before
2. I'm only starting to tread on this new ground myself.
3. I understand German fairly well, but am not native.
If you consider 3, and don't get your hopes up, I'm of course willing to
look at it.
Quote
Re.: TThread implementation and extensions in FP / Lazarus, please let
me know it I can be of any help.
First we need testing, port example programs etc. We don't exactly know what
is missing yet.
Porting some kylix socket suite would make a nice test.
Quote
P.S.: Perhaps we should move the discussion to some more appropriate
newsgroup.
Most of the stuff we discussed can be applied to Delphi/Kylix too, e.g.
implementing in a descendant of tthread, maybe requiring a small rts patch.
(but Andreas c.s. already maintain patches for that, given significant use
of it, they might include it). The fork/select stuff more even so, since it
is Linux (or Unix) in general. I would be surprised if nobody did epoll stuff
with kylix yet.
P.s. FPC 1.9.6 was released on newyear.
 

Re:Re: Kylix now officially alive?

Quote
tthread.synchronize implementation has been picked up again by Micha. He already
had a proposal patch, but we are now adapting it for inclusion.

I just took a short look at the (not latest) FP code.
Here I saw that TThreadlist.LockList is not yet done correctly.
If Threads are to be usable in the next version, this, too, needs to be
done. This is very easy with TCriticalSection, which _is_ done in
fcl/linux/syncobjs.pp (using pthread_mutex_lock). I have no idea if (in
the version I have) this is not used in TThreadlist.LockList. Perhaps
you can take a look and have the appropriate maintainer know if there is
a problem.
BTW. I feel, the critical section code speed can be improved using a
simple memory variable for locking (using a locked inc instruction) and
calling the OS Mutex only when the section is busy:
function LockedDec(var Target: integer) : Integer; assembler;
asm
mov ecx, Target
mov eax, -1
lock xadd [ecx], eax
dec eax
end;
function LockedInc(var Target: integer) : Integer; assembler;
asm
mov ecx, Target
mov eax, 1
lock xadd [ecx], eax
dec eax
end;
(FActivity is a member variable of TCriticalSection)
procedure TCriticalSection.Acquire;
begin
Result := 0;
while LockedDec(FActivity) < 0 do begin
LockedInc(FActivity);
EnterCriticalSection(CriticalSection);
end;
end;
TCriticalSection.Release;
begin
LockedInc(FActivity);
LeaveCriticalSection(CriticalSection);
end;
(Maybe a Release without an Acquire should be handled somehow but this
is erroneous anyway.)
What do you think ?
-Michael
 

Re:Re: Kylix now officially alive?

Thanks for all your remarks.
Of course you are right to note that the Linux way (and the way the HTTP
concept is initially done) is using a process per connection, not
threads. Maybe this is why Linux makes a better HTTP server than
Windows. I also do know that in Linux it's very easy to define a port in
a configuration file and then the system will automatically spawn a
process with the port connected to your program as a pipe, so your
program does not even need to know that this is a TCP/IP port. This will
happen concurrently for all connection established to that port from
remote. Great old stuff indeed !
But Unfortunately this is not really easily usable with Kylix or FP,
especially if you want to create a multi-Platform project. Moreover in
embedded projects you at the same time have activities that result form
TCP/IP port input and those that result from timing, hardware or
whatever. Here a multithreadded way can be appropriate, and nonetheless
multiple TCP/IP socket streams should be handled with appropriate
performance and security.
-Michael
 

Re:Re: Kylix now officially alive?

On 2005-01-04, Michael Schnell < XXXX@XXXXX.COM >wrote:
Quote
>tthread.synchronize implementation has been picked up again by Micha. He already
>had a proposal patch, but we are now adapting it for inclusion.
the version I have) this is not used in TThreadlist.LockList. Perhaps
you can take a look and have the appropriate maintainer know if there is
a problem.


BTW. I feel, the critical section code speed can be improved using a
simple memory variable for locking (using a locked inc instruction) and
calling the OS Mutex only when the section is busy:
Are you sure this is MP safe?
IIRC the Indy problems of last spring were due to such constructs which turned
out to be not MP (and thus HT) safe.
 

Re:Re: Kylix now officially alive?

Quote
Are you sure this is MP safe?
As _only_ bus locking instruction are used for the critical variable, it
is multi processor save _if_ it's thread save. I can't guarantee same,
but I did not find a reason why it would not be. It's running in an
embedded (single processor) project since years without any problem, but
of course this is no proof.
Perhaps you might want to go through the quite limited number of
different possible cases with three concurrent threads. (I'm very sure
that adding more threads will not add any potential problems.) For a
critical section it's granted that the thread that acquires the
semaphore will be the one that releases it: releasing is always done
after acquiring, so there are only a few possible sequence variations.
IMHO it's worth investigating, as in 99,9 % of the cases this would
avoid calling the library. OTOH, maybe in Linux, the PThread library
does something similar and so it's not necessary to do it in user code.
But nonetheless,
while LockedDec(FActivity) < 0 do begin
LockedInc(FActivity);
EnterCriticalSection(CriticalSection);
end;
could be done independently of the OS and the processor (of course
LockedInc() needs to be done for any processor type, but independently
of the OS.)
Quote

IIRC the Indy problems of last spring were due to such constructs which turned
out to be not MP (and thus HT) safe.
Supposedly they did not use the appropriate bus locking instructions
(which need to be done using ASM).
-Michael
 

Re:Re: Kylix now officially alive?

Quote
Are you sure this is MP safe?

BTW. 1: I remember that the Delphi 4? string handling was not multi
processor save.
BTW. 2: I remember that last time I worked with FP some years ago the
memory management was not even thread save.
Is the FP memory management and string handling (and other basic stuff)
thread and multi processing save now ?
-Michael
 

Re:Re: Kylix now officially alive?

Quote
procedure TCriticalSection.Acquire;
begin
Result := 0;
while LockedDec(FActivity) < 0 do begin
LockedInc(FActivity);
EnterCriticalSection(CriticalSection);
end;
end;

OOPS that is not going to work, as the EnterCriticalSection() procedure
does not block in any case, but only for the second call before
LeaveCriticalSection() is called. Here we would simply need do do use a
semaphore that blocks in any case and releases (all or, better, one) of
the waiting threads in the TCriticalSection.Release procedure.
-Michael
 

Re:Re: Kylix now officially alive?

BTW.:
The _idea_ of a better implementation of pascal object events is taken
care of by chrome:
www.chromesville.com/page.asp
They add the "event" and the "delegate" keyword to implement events that
1) can be fired only from within an object and 2) allow for multiple
subscribers to hook to the same object (which would need a quite complex
set of read and write procedures for the event property in Delphi).
They say nothing about the use of threads with events, but it seems like
the chrome event definition could be a nice basis for same (using
events as a means for inter thread communication).
Maybe the "event" and the "delegate" keywords could be a nice addition
to FP, too.
-Michael