Install capr.pl

Parallel caget
This commit is contained in:
Ronaldo Mercado
2010-05-25 21:44:38 +01:00
parent 797d263f04
commit 408721daec
2 changed files with 79 additions and 18 deletions

View File

@@ -29,6 +29,7 @@ ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),)
PERL_SCRIPTS += cainfo.pl
PERL_SCRIPTS += caput.pl
PERL_SCRIPTS += caget.pl
PERL_SCRIPTS += capr.pl
PERL_SCRIPTS += camonitor.pl
PERL_MODULES += CA.pm

View File

@@ -31,7 +31,7 @@ if ( defined $ENV{"EPICS_HOST_ARCH"} ) {
our( $opt_d, $opt_f, $opt_r);
my $usage = "Usage:\n $0 [-d dbd_file] ( [-f record_type] | [-r] | [record_name] ) [interest]\n";
my %record = (); # Empty hash to put dbd data in
my $iIdx = 0; # Array indexes for interest, data type and base
my $iIdx = 0; # Array indexes for interest, data type and base
my $tIdx = 1;
my $bIdx = 2;
my %device = (); # Empty hash to record which rec types have device support
@@ -58,6 +58,13 @@ my %fieldType = (
DBF_NOACCESS => "ezcaNoAccess"
);
# globals for parallel_caget
my %callback_data;
my $callback_incomplete;
# globals for caget
my $caget_data;
my $caget_incomplete;
my $cadebug = 0;
######### Main program ############
@@ -286,6 +293,49 @@ sub printField {
return($col);
}
# grab a list of pvs simultaneously
# The results are filled in the the %callback_data global hash
# and the result of the operation is the number of read pvs
# Usage: $read_pvs = parallel_caget( @pvlist )
sub parallel_caget {
my @chans = map { CA->new($_); } @_;
my $wait = 1;
eval { CA->pend_io($wait); };
if ($@) {
if ($@ =~ m/^ECA_TIMEOUT/) {
my $err = (@chans > 1) ? 'some PV(s)' : "'" . $chans[0]->name . "'";
print "Channel connect timed out: $err not found.\n";
foreach my $chan (@chans) {
$callback_data{$chan->name} = "<timeout>"
unless $chan->is_connected;
}
@chans = grep { $_->is_connected } @chans;
} else {
die $@;
}
}
map {
my $type;
$type = $_->field_type;
#$callback_data{$_->name} = undef;
$_->get_callback(\&caget_callback, $type);
} @chans;
my $read_pvs = @chans;
$callback_incomplete = @chans;
CA->pend_event(0.1) while $callback_incomplete;
return $read_pvs;
}
sub caget_callback {
my ($chan, $status, $data) = @_;
die $status if $status;
$callback_data{$chan->name} = $data;
$callback_incomplete--;
}
# Given record name and interest level prints data from record fields
# that are at or below the interest level specified.
# Useage: printRecord( $recordName, $interestLevel)
@@ -295,12 +345,16 @@ sub printRecord {
my ($error, $recType, $field, $fType, $fInterest, $data);
my ($fToGet, $col, $base);
#print("checking record $name, interest $interest\n");
$col = 0;
$recType = getRecType($name);
print("$name is record type $recType\n");
exists($record{$recType}) || die "Record type $recType not found in dbd file --";
#capture list of fields to obtain
my @list = (); #fiels to read
my @fields_pr = (); #fields for print-out
my @ftypes = (); #types, from parser
my @bases = (); #bases, from parser
foreach $field (sort keys %{$record{$recType}}) {
# Skip DTYP field if this rec type doesn't have device support defined
if($field eq "DTYP" && !(exists($device{$recType}))) { next; }
@@ -309,15 +363,25 @@ sub printRecord {
unless( $fType eq "ezcaNoAccess" ) {
if( $interest >= $fInterest ) {
$fToGet = $name . "." . $field;
$data = caget($fToGet);
chomp $data;
#$data =~ s/\s+//;
#if( $data[0] ) { die "ca get error on field $field --" };
$col = printField($field, $data, $fType, $base, $col);
#print ("fType = $fType $data[1]\n");
push @fields_pr, $field;
push @list, $fToGet;
push @ftypes, $fType;
push @bases, $base;
}
}
}
my $read_pvs;
$read_pvs = parallel_caget( @list );
$col = 0;
for (my $i=0; $i < scalar @list; $i++) {
$field = $fields_pr[$i];
$fToGet = $list[$i];
$data = $callback_data{$fToGet};
$fType = $ftypes[$i];
chomp $data;
$col = printField($field, $data, $fType, $base, $col);
}
print("\n"); # Final line feed
}
@@ -361,10 +425,6 @@ sub printRecordList {
}
}
# variable to communicate callback handler result
my $callback_data;
my $incomplete;
my $cadebug = 0;
# returns a terse result of a caget operation
# using perlCA
@@ -385,9 +445,9 @@ sub caget {
my $type = $channel->field_type;
my $count = $channel->element_count;
$channel->get_callback(\&callback_handler, $type);
$incomplete = 1;
CA->pend_event(0.1) while ($incomplete);
return $callback_data;
$caget_incomplete = 1;
CA->pend_event(0.1) while ($caget_incomplete);
return $caget_data;
}
sub callback_handler
@@ -395,8 +455,8 @@ sub callback_handler
my ($chan, $status, $data) = @_;
die $status if $status;
#display($chan, $type, $data);
$callback_data = $data;
$incomplete=0;
$caget_data = $data;
$caget_incomplete=0;
}
sub show_call_stack {