ithreads at runtime?

  • Thread starter Walter Roberson
  • Start date
W

Walter Roberson

I wonder if someone could give me some hints how to enable
ithread support conditionally at run-time ?


I have written a multi-threaded firewall log analysis program that
calls upon a series of utility modules that I've written. Shared
variables are involved (and Queues, but the Queues don't seem to be a
problem at the moment.) I described some of the effort and lessons in a
previous topic in this newsgroup.

As the program is slower than I'd prefer, I attempted to profile with
-d:DProf . That failed miserably on any module for which I had
use threads::shared complaining that,

panic: Devel::DProf inconsistent subroutine return at /usr/freeware/lib/perl5/5.8.2/irix-n32-thread-multi/threads/shared.pm line 17.

According to the Devel::DProf documentation, this is a known failure
mode for certain kinds of returns from routines (involving labels.)

I rejigged my modules to do require's instead of use's, and built in
the appropriate run-time logic to know whether to bother to place
lock() and share() calls. In my main code, I placed the appropriate
logic to know to proceed linearily instead of multi-threaded depending
on a run-time option. With appropriate placement of () to delimit
function calls [instead relying on prototypes being available],
and a few other misc. tweaks, I was able to make Devel::DProf happy.
(Looks like massive numbers of split() are my slow point still.)
And in the process I improved the utility modules so they should now
work even without threads configured. A nuisance, but not a wasted effort.

And everything seemed fine until I went to switch back to threaded mode.
When I stopped giving my new run-time option, one of the modules
started complaining that I need to use threads before I
use threads::shared . Some experimentation showed I had to change my
require threads; in my main routine to use threads; instead,
to stop the message... or at least that was the easiest way I could find.
[NB: threads::shared does some magic to force you to include them
in the right order.] But with the 'use' instead of 'require',
Devel::DProf breaks again...


So, at the moment I seem to be stuck. If I use a 'require' then
threads::shared knows that threads weren't invoked at compile time and
shared threads don't work. But if I use a 'use' then Devel::DProf can't
monitor the program.

It's all down to a single statement, but a statement that seemingly
has to go in at compile time rather than at run-time.

Is it fair game to examine @ARGV in a BEGIN block?
Or am I going to have to use some hack such as requiring the
program be invoked via perl -Mthreads to supply the compile-time
context for threads when I want threads used?

Uggh, just realized I could pull a trick such as exec()ing
itself as perl -Mthreads Blech!
 
B

Ben Morrow

I wonder if someone could give me some hints how to enable
ithread support conditionally at run-time ?
As the program is slower than I'd prefer, I attempted to profile with
-d:DProf . That failed miserably on any module for which I had
use threads::shared complaining that,

panic: Devel::DProf inconsistent subroutine return at
/usr/freeware/lib/perl5/5.8.2/irix-n32-thread-multi/threads/shared.pm line 17.

According to the Devel::DProf documentation, this is a known failure
mode for certain kinds of returns from routines (involving labels.)

I rejigged my modules to do require's instead of use's, and built in
the appropriate run-time logic to know whether to bother to place
lock() and share() calls.

There's no need to do that. If you 'use threads::shared' without
having a previous 'use threads' those lock and share calls will become
noops.
And everything seemed fine until I went to switch back to threaded mode.
When I stopped giving my new run-time option, one of the modules
started complaining that I need to use threads before I
use threads::shared . Some experimentation showed I had to change my
require threads; in my main routine to use threads; instead,
to stop the message... or at least that was the easiest way I could find.
[NB: threads::shared does some magic to force you to include them
in the right order.]

It's not threads::shared magic, it's threads magic. If threads finds
threads::shared has been loaded before it, it complains.
Is it fair game to examine @ARGV in a BEGIN block?

Err... yes.

BEGIN {
unless (grep $_ eq '-nothreads', @ARGV) {
require threads;
import threads;
}
}

use threads::shared;

or, if you'd rather:

use if not grep($_ eq '-nothreads', @ARGV), 'threads';
use threads::shared;

Get if.pm from CPAN.

Ben
 
W

Walter Roberson

:> I wonder if someone could give me some hints how to enable
:> ithread support conditionally at run-time ?

:> I rejigged my modules to do require's instead of use's, and built in
:> the appropriate run-time logic to know whether to bother to place
:> lock() and share() calls.

:There's no need to do that. If you 'use threads::shared' without
:having a previous 'use threads' those lock and share calls will become
:noops.

Thanks, I had forgotten that. I've re-rejigged and that part seems to
working fine.

:> Is it fair game to examine @ARGV in a BEGIN block?

:Err... yes.

Okay, I'll work towards that. I'll have to do a little code restructuring
to make it work right in my situation, but it shouldn't be too bad.
 
W

Walter Roberson

:[email protected] (Walter Roberson) wrote:
:> I wonder if someone could give me some hints how to enable
:> ithread support conditionally at run-time ?

:eek:r, if you'd rather:

:use if not grep($_ eq '-nothreads', @ARGV), 'threads';

Thanks, I ended up using something akin to that, and now have
a single program that enables or disables thread support at runtime.

It ended up being a lot cleaner than I expected -- when I was written
the program first several weeks ago, the code for supporting or
not supporting threads at need looked like it was going to be excessively
messy.

The bit you reminded me of, of share() and lock() being no-ops
unless use threads is in effect, helps a fair bit.


Another part that helped a fair bit was using share() as a call
instead of using the my $var : shared syntax that doesn't work at all
when threading is not enabled. Using share() as a call also allowed
me to get around some issues that 'my' variables are local to the
block, so you can't define them conditionally -- e.g., you can't have

if ( $Config{useithreads} ) {
my $sharedvar : shared;
} else {
my $sharedvar;
}

because the variable would go out of scope after the 'if'. But this works:

my $sharedvar;
share $sharedvar if $Config{useithreads};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top