Re: load_files freezes in a multi threading application using JPL (Java calling Prolog)

Jan Wielemaker <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 03/17/2014 12:02 PM, Sergio Castro wrote:
> Hi Jan,
>
> I did some more experiments that may shed some light on the problem. I'm
> using two files with the same content:
>
> ---- hello.pl
> :- thread_local(hello/1).
> hello(X) :- write('Hello '), write(X), flush_output.
> ----
>
> ---- hello2.pl
> :- thread_local(hello/1).
> hello(X) :- write('Hello '), write(X), flush_output.
> ----
>
> Loading these two files results in no deadlock and the following output:
>
> %
> /Users/sergioc/.jpc/file_Users_sergioc_Documents_workspaces_heal_jpc_target_classes/org/jpc/pl/jpc.pl
> compiled 0.00 sec, 1 clauses
> before load_files
> % /Users/sergioc/.jpc/hello.pl compiled 0.00 sec, 2 clauses
> after load_files
> before load_files
> Warning: /Users/sergioc/.jpc/hello2.pl:5:
> Redefined static procedure hello/1
> Foreign predicate system:$record_clause/3 did not clear exception:
> error(permission_error(modify,thread_local_procedure,hello/1),context(system:
> $record_clause/3,_G1162))
> % /Users/sergioc/.jpc/hello2.pl compiled 0.00 sec, 2 clauses
> after load_files
> OK
>
> If I comment out the thread_local/1 directives (that are being used just
> to trigger an exception) I get a deadlock:
>
> %
> /Users/sergioc/.jpc/file_Users_sergioc_Documents_workspaces_heal_jpc_target_classes/org/jpc/pl/jpc.pl
> compiled 0.00 sec, 1 clauses
> before load_files
> % /Users/sergioc/.jpc/hello.pl compiled 0.00 sec, 2 clauses
> after load_files
> before load_files
> Warning: /Users/sergioc/.jpc/hello2.pl:5:
> Redefined static procedure hello/1
> Previously defined at /Users/sergioc/.jpc/hello.pl:5
>
> It seems that the handling of the exception in the first case might be
> doing some cleanup that overcomes the deadlock. Does this provides you
> any hint to the cause of the deadlock?

Not really.  I tried with this code:

test :-
         load_files(hello, []),
         thread_create(load_files(hello2, []), Id, []),
         thread_join(Id, Status),
         writeln(Status).

That loads both scenarios just fine (with errors of course).  Does
code without errors work?  Does it work if you suppress output using
load_files(hello, [silent(true)]) (and no errors in the code)?  Anyway,
probably attaching a debugging to the deadlocked process and getting
the stacks of all threads is the most promising route to get a clue.

	Cheers --- Jan

>
> Sergio
>
>
>
> Le Dimanche 16 mars 2014 15h52, Jan Wielemaker <[email protected]> a
> �crit :
>
>     On 03/14/2014 05:27 PM, Sergio Castro wrote:
>      > Hello,
>      >
>      > My scenario is the following: I implemented a simple mechanism to
>      > overcome certain JPL limitations regarding multithreading
>      > applications (e.g., afaik a JPL query always has to be opened, its
>      > results traversed, and closed in the same thread). So the main idea
>      > is that I keep a dedicated thread in a query wrapper, and all query
>      > operations are executed in the context of that thread. Then the
>      > calling thread waits until the query thread completes, since the
>      > objective of the query thread is just to circumvent the JPL
>      > multithreading limitations regarding the need of being manipulated in
>      > the same Java thread.
>      >
>      > If possible, I would like feedback regarding the correctness of this
>      > design. I am aware that this is of course less efficient than
>      > directly using a JPL query (since with my query wrapper there is a
>      > separate Java thread for each active query), but I find it useful for
>      > scenarios where I do not want to be constrained to traverse a JPL
>      > query in the same thread. I am happy to share the code if someone is
>      > interested btw.
>
>     I don't know. Technically, I guess this should be possible, but I wonder
>     what requirement justifies this complication. Can you give a scenario
>     where yiou would like to do this?
>
>      > However, I found a problem that appears in this setting. If I execute
>      > the query below twice (using JPL), it freezes at the second call to
>      > load_files/2 (this is a simplification of my problem to keep the
>      > description simple, in my application I am in fact loading files
>      > using Logtalk, and the calls do not happen exactly one after
>      > another):
>      >
>      > "writeln('before load_files'), flush_output,
>      > load_files('<filepath>/hello.pl', []), writeln('after load_files'),
>      > flush_output"
>      >
>      > So the output I see is:
>      >
>      > before load_files % <filepath>/hello.pl compiled 0.00 sec, 2 clauses
>      > after load_files before load_files <FROZEN HERE>
>      >
>      > Note that the calls to load_files do not happen concurrently (afaik
>      > files should not be loaded concurrently). However, they do happen in
>      > different threads (synchronised between them). I also verified that
>      > if I execute everything in the same thread, then load_files does not
>      > freeze.
>
>     load_files/2 can be called concurrently.  Additional threads trying to
>     load a file while this is in progress will wait for the initiating
>     thread.  The above works find in pure Prolog, so I assume the culprit
>     is JPL or your wrapper.
>
>      > Any idea what may be the problem ?
>
>     Typically, attach e.g., gdb and see which threads are blocking where.
>     That might give a clue.
>
>          Cheers --- Jan
>
>
>
>
>      >
>      > Thanks,
>      >
>      > Sergio -------------- next part -------------- HTML attachment
>      > scrubbed and removed _______________________________________________
>      > SWI-Prolog mailing list [email protected]
>     <mailto:[email protected]>
>      > https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
>      >
>
>

_______________________________________________
SWI-Prolog mailing list
[email protected]
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.