817 lines
13 KiB
Groff
817 lines
13 KiB
Groff
.\" $NetBSD: pmc.3,v 1.5 2003/04/16 13:35:13 wiz Exp $
|
|
.\"
|
|
.\" Copyright (c) 2002 Wasabi Systems, Inc.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" Written by Jason R. Thorpe for Wasabi Systems, Inc.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\" 3. All advertising materials mentioning features or use of this software
|
|
.\" must display the following acknowledgement:
|
|
.\" This product includes software developed for the NetBSD Project by
|
|
.\" Wasabi Systems, Inc.
|
|
.\" 4. The name of Wasabi Systems, Inc. may not be used to endorse
|
|
.\" or promote products derived from this software without specific prior
|
|
.\" written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
|
|
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.Dd August 8, 2002
|
|
.Dt PMC 3
|
|
.Os
|
|
.Sh NAME
|
|
.Nm pmc_configure_counter ,
|
|
.Nm pmc_start_counter ,
|
|
.Nm pmc_stop_counter ,
|
|
.Nm pmc_get_num_counters ,
|
|
.Nm pmc_get_counter_class ,
|
|
.Nm pmc_get_counter_type ,
|
|
.Nm pmc_get_counter_value ,
|
|
.Nm pmc_get_accumulated_counter_value ,
|
|
.Nm pmc_get_counter_class_name ,
|
|
.Nm pmc_get_counter_type_name ,
|
|
.Nm pmc_get_counter_event_name ,
|
|
.Nm pmc_get_counter_event_list
|
|
.Nd performance counter interface library
|
|
.Sh LIBRARY
|
|
.Lb libpmc
|
|
.Sh SYNOPSIS
|
|
.In pmc.h
|
|
.Ft int
|
|
.Fn pmc_configure_counter "int ctr" "const char *evname" \
|
|
"pmc_ctr_t reset_val" "uint32_t flags"
|
|
.Ft int
|
|
.Fn pmc_start_counter "int ctr"
|
|
.Ft int
|
|
.Fn pmc_stop_counter "int ctr"
|
|
.Ft int
|
|
.Fn pmc_get_num_counters "void"
|
|
.Ft int
|
|
.Fn pmc_get_counter_class "void"
|
|
.Ft int
|
|
.Fn pmc_get_counter_type "int ctr" "int *typep"
|
|
.Ft int
|
|
.Fn pmc_get_counter_value "int ctr" "uint64_t *valp"
|
|
.Ft int
|
|
.Fn pmc_get_accumulated_counter_value "int ctr" "uint64_t *valp"
|
|
.Ft const char *
|
|
.Fn pmc_get_counter_class_name "int class"
|
|
.Ft const char *
|
|
.Fn pmc_get_counter_type_name "int type"
|
|
.Ft const char *
|
|
.Fn pmc_get_counter_event_name "pmc_evid_t event"
|
|
.Ft const struct pmc_event *
|
|
.Fn pmc_get_counter_event_list "void"
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm pmc
|
|
library is an interface to performance monitoring counters available
|
|
on some CPUs.
|
|
.Pp
|
|
The
|
|
.Nm pmc
|
|
library can count events on the following CPU families.
|
|
Each second-level entry describes a performance counter class.
|
|
A given class may apply to multiple individual CPU models.
|
|
Each class has one or more counter types.
|
|
A CPU may have more than one counter of a given type.
|
|
Refer to the corresponding processor programmer's manual for
|
|
more information about individual events.
|
|
.Bl -bullet
|
|
.It
|
|
ARM
|
|
.Bl -bullet
|
|
.It
|
|
Intel i80200
|
|
.Pq PMC_CLASS_I80200
|
|
.Pp
|
|
There are two types of counters available in this class:
|
|
.Bl -tag -width PMC_TYPE_I80200_CCNTxx
|
|
.It PMC_TYPE_I80200_CCNT
|
|
cycle counter
|
|
.It PMC_TYPE_I80200_PMCx
|
|
performance counter
|
|
.El
|
|
.Pp
|
|
The following events may be counted by a counter of type
|
|
PMC_TYPE_I80200_CCNT:
|
|
.Pp
|
|
.Bl -item -offset indent -compact
|
|
.It
|
|
clock
|
|
.It
|
|
clock-div-64
|
|
.El
|
|
.Pp
|
|
The following events may be counted by a counter of type
|
|
PMC_TYPE_I80200_PMCx:
|
|
.Pp
|
|
.Bl -item -offset indent -compact
|
|
.It
|
|
insfetch-miss
|
|
.It
|
|
insfetch-stall
|
|
.It
|
|
datadep-stall
|
|
.It
|
|
itlb-miss
|
|
.It
|
|
dtlb-miss
|
|
.It
|
|
branch-taken
|
|
.It
|
|
branch-mispredicted
|
|
.It
|
|
instruction-executed
|
|
.It
|
|
dcachebufffull-stall-time
|
|
.It
|
|
dcachebufffull-stall-count
|
|
.It
|
|
dcache-access
|
|
.It
|
|
dcache-miss
|
|
.It
|
|
dcache-writeback
|
|
.It
|
|
swchange-pc
|
|
.It
|
|
bcu-mem-request
|
|
.It
|
|
bcu-queue-full
|
|
.It
|
|
bcu-queue-drain
|
|
.It
|
|
bcu-ecc-no-elog
|
|
.It
|
|
bcu-1bit-error
|
|
.It
|
|
narrow-ecc-caused-rmw
|
|
.El
|
|
.El
|
|
.It
|
|
i386
|
|
.Bl -bullet
|
|
.It
|
|
Intel i586
|
|
.Pq PMC_CLASS_I586
|
|
.Pp
|
|
There are two types of counters available in this class:
|
|
.Bl -tag -width PMC_TYPE_I586_PMCxxx
|
|
.It PMC_TYPE_I586_TSC
|
|
cycle counter
|
|
.It PMC_TYPE_I586_PMCx
|
|
performance counter
|
|
.El
|
|
.Pp
|
|
The following events may be counted by a counter of type
|
|
PMC_TYPE_I586_PMCx:
|
|
.Pp
|
|
.Bl -item -offset indent -compact
|
|
.It
|
|
tlb-data-miss
|
|
.It
|
|
tlb-ins-miss
|
|
.It
|
|
l1cache-ins-miss
|
|
.It
|
|
l1cache-data-miss
|
|
.It
|
|
l1cache-data-miss-read
|
|
.It
|
|
l1cache-data-miss-write
|
|
.It
|
|
l1cache-writeback
|
|
.It
|
|
l1cache-writeback-hit
|
|
.It
|
|
l2cache-data-snoop
|
|
.It
|
|
l2cache-data-snoop-hit
|
|
.It
|
|
mem-read
|
|
.It
|
|
mem-write
|
|
.It
|
|
mem-access
|
|
.It
|
|
mem-access-both-pipes
|
|
.It
|
|
mem-bank-conflicts
|
|
.It
|
|
mem-misalign-ref
|
|
.It
|
|
mem-uncached-read
|
|
.It
|
|
seg-load-any
|
|
.It
|
|
branch
|
|
.It
|
|
branch-btb-hit
|
|
.It
|
|
branch-taken
|
|
.It
|
|
ins-read
|
|
.It
|
|
ins-pipeline-flush
|
|
.It
|
|
ins-executed
|
|
.It
|
|
ins-executed-vpipe
|
|
.It
|
|
ins-stall-agi
|
|
.It
|
|
ins-stall-write
|
|
.It
|
|
ins-stall-data
|
|
.It
|
|
ins-stall-writeline
|
|
.It
|
|
bus-utilization
|
|
.It
|
|
bus-locked
|
|
.It
|
|
bus-io-cycle
|
|
.It
|
|
fpu-flops
|
|
.It
|
|
int-hw
|
|
.It
|
|
break-match0
|
|
.It
|
|
break-match1
|
|
.It
|
|
break-match2
|
|
.It
|
|
break-match3
|
|
.El
|
|
.It
|
|
Intel i686
|
|
.Pq PMC_CLASS_I686
|
|
.Pp
|
|
There are two types of counters available in this class:
|
|
.Bl -tag -width PMC_TYPE_I686_PMCxxx
|
|
.It PMC_TYPE_I686_TSC
|
|
cycle counter
|
|
.It PMC_TYPE_I686_PMCx
|
|
performance counter
|
|
.El
|
|
.Pp
|
|
The following events may be counted by a counter of type
|
|
PMC_TYPE_I686_PMCx:
|
|
.Pp
|
|
.Bl -item -offset indent -compact
|
|
.It
|
|
mem-refs
|
|
.It
|
|
l1cache-lines
|
|
.It
|
|
l1cache-mlines
|
|
.It
|
|
l1cache-mlines-evict
|
|
.It
|
|
l1cache-miss-wait
|
|
.It
|
|
ins-fetch
|
|
.It
|
|
ins-fetch-misses
|
|
.It
|
|
itlb-misses
|
|
.It
|
|
insfetch-mem-stall
|
|
.It
|
|
insfetch-decode-stall
|
|
.It
|
|
l2cache-insfetch
|
|
.It
|
|
l2cache-data-loads
|
|
.It
|
|
l2cache-data-stores
|
|
.It
|
|
l2cache-lines
|
|
.It
|
|
l2cache-lines-evict
|
|
.It
|
|
l2cache-mlines
|
|
.It
|
|
l2cache-mlines-evict
|
|
.It
|
|
l2cache-reqs
|
|
.It
|
|
l2cache-addr-strobes
|
|
.It
|
|
l2cache-data-busy
|
|
.It
|
|
l2cache-data-busy-read
|
|
.It
|
|
bus-drdy-clocks-self
|
|
.It
|
|
bus-drdy-clocks-any
|
|
.It
|
|
bus-lock-clocks-self
|
|
.It
|
|
bus-lock-clocks-any
|
|
.It
|
|
bus-req-outstanding-self
|
|
.It
|
|
bus-req-outstanding-any
|
|
.It
|
|
bus-burst-reads-self
|
|
.It
|
|
bus-burst-reads-any
|
|
.It
|
|
bus-read-for-ownership-self
|
|
.It
|
|
bus-read-for-ownership-any
|
|
.It
|
|
bus-write-back-self
|
|
.It
|
|
bus-write-back-any
|
|
.It
|
|
bus-ins-fetches-self
|
|
.It
|
|
bus-ins-fetches-any
|
|
.It
|
|
bus-invalidates-self
|
|
.It
|
|
bus-invalidates-any
|
|
.It
|
|
bus-partial-writes-self
|
|
.It
|
|
bus-partial-writes-any
|
|
.It
|
|
bus-partial-trans-self
|
|
.It
|
|
bus-partial-trans-any
|
|
.It
|
|
bus-io-trans-self
|
|
.It
|
|
bus-io-trans-any
|
|
.It
|
|
bus-deferred-trans-self
|
|
.It
|
|
bus-deferred-trans-any
|
|
.It
|
|
bus-burst-trans-self
|
|
.It
|
|
bus-burst-trans-any
|
|
.It
|
|
bus-total-trans-self
|
|
.It
|
|
bus-total-trans-any
|
|
.It
|
|
bus-mem-trans-self
|
|
.It
|
|
bus-mem-trans-any
|
|
.It
|
|
bus-recv-cycles
|
|
.It
|
|
bus-bnr-cycles
|
|
.It
|
|
bus-hit-cycles
|
|
.It
|
|
bus-hitm-cycles
|
|
.It
|
|
bus-snoop-stall
|
|
.It
|
|
fpu-flops
|
|
.It
|
|
fpu-comp-ops
|
|
.It
|
|
fpu-except-assist
|
|
.It
|
|
fpu-mul
|
|
.It
|
|
fpu-div
|
|
.It
|
|
fpu-div-busy
|
|
.It
|
|
mem-sb-blocks
|
|
.It
|
|
mem-sb-drains
|
|
.It
|
|
mem-misalign-ref
|
|
.It
|
|
ins-pref-dispatch-nta
|
|
.It
|
|
ins-pref-dispatch-t1
|
|
.It
|
|
ins-pref-dispatch-t2
|
|
.It
|
|
ins-pref-dispatch-weak
|
|
.It
|
|
ins-pref-miss-nta
|
|
.It
|
|
ins-pref-miss-t1
|
|
.It
|
|
ins-pref-miss-t2
|
|
.It
|
|
ins-pref-miss-weak
|
|
.It
|
|
ins-retired
|
|
.It
|
|
uops-retired
|
|
.It
|
|
ins-decoded
|
|
.It
|
|
ins-stream-retired-packed-scalar
|
|
.It
|
|
ins-stream-retired-scalar
|
|
.It
|
|
ins-stream-comp-retired-packed-scalar
|
|
.It
|
|
ins-stream-comp-retired-scalar
|
|
.It
|
|
int-hw
|
|
.It
|
|
int-cycles-masked
|
|
.It
|
|
int-cycles-masked-pending
|
|
.It
|
|
branch-retired
|
|
.It
|
|
branch-miss-retired
|
|
.It
|
|
branch-taken-retired
|
|
.It
|
|
branch-taken-mispred-retired
|
|
.It
|
|
branch-decoded
|
|
.It
|
|
branch-btb-miss
|
|
.It
|
|
branch-bogus
|
|
.It
|
|
branch-baclear
|
|
.It
|
|
stall-resource
|
|
.It
|
|
stall-partial
|
|
.It
|
|
seg-loads
|
|
.It
|
|
unhalted-cycles
|
|
.It
|
|
mmx-exec
|
|
.It
|
|
mmx-sat-exec
|
|
.It
|
|
mmx-uops-exec
|
|
.It
|
|
mmx-exec-packed-mul
|
|
.It
|
|
mmx-exec-packed-shift
|
|
.It
|
|
mmx-exec-pack-ops
|
|
.It
|
|
mmx-exec-unpack-ops
|
|
.It
|
|
mmx-exec-packed-logical
|
|
.It
|
|
mmx-exec-packed-arith
|
|
.It
|
|
mmx-trans-mmx-float
|
|
.It
|
|
mmx-trans-float-mmx
|
|
.It
|
|
mmx-assist
|
|
.It
|
|
mmx-retire
|
|
.It
|
|
seg-rename-stalls-es
|
|
.It
|
|
seg-rename-stalls-ds
|
|
.It
|
|
seg-rename-stalls-fs
|
|
.It
|
|
seg-rename-stalls-gs
|
|
.It
|
|
seg-rename-stalls-all
|
|
.It
|
|
seg-rename-es
|
|
.It
|
|
seg-rename-ds
|
|
.It
|
|
seg-rename-fs
|
|
.It
|
|
seg-rename-gs
|
|
.It
|
|
seg-rename-all
|
|
.It
|
|
seg-rename-retire
|
|
.El
|
|
.It
|
|
AMD Athlon / K7
|
|
.Pq PMC_CLASS_K7
|
|
.Pp
|
|
There are two types of counters available in this class:
|
|
.Bl -tag -width PMC_TYPE_K7_PMCxxx
|
|
.It PMC_TYPE_K7_TSC
|
|
cycle counter
|
|
.It PMC_TYPE_K7_PMCx
|
|
performance counter
|
|
.El
|
|
.Pp
|
|
The following events may be counted by a counter of type
|
|
PMC_TYPE_K7_PMCx:
|
|
.Pp
|
|
.Bl -item -offset indent -compact
|
|
.It
|
|
seg-load-all
|
|
.It
|
|
seg-load-es
|
|
.It
|
|
seg-load-cs
|
|
.It
|
|
seg-load-ss
|
|
.It
|
|
seg-load-ds
|
|
.It
|
|
seg-load-fs
|
|
.It
|
|
seg-load-gs
|
|
.It
|
|
seg-load-hs
|
|
.It
|
|
seg-load-stall
|
|
.It
|
|
l1cache-access
|
|
.It
|
|
l1cache-miss
|
|
.It
|
|
l1cache-refill
|
|
.It
|
|
l1cache-refill-invalid
|
|
.It
|
|
l1cache-refill-shared
|
|
.It
|
|
l1cache-refill-exclusive
|
|
.It
|
|
l1cache-refill-owner
|
|
.It
|
|
l1cache-refill-modified
|
|
.It
|
|
l1cache-load
|
|
.It
|
|
l1cache-load-invalid
|
|
.It
|
|
l1cache-load-shared
|
|
.It
|
|
l1cache-load-exclusive
|
|
.It
|
|
l1cache-load-owner
|
|
.It
|
|
l1cache-load-modified
|
|
.It
|
|
l1cache-writeback
|
|
.It
|
|
l1cache-writeback-invalid
|
|
.It
|
|
l1cache-writeback-shared
|
|
.It
|
|
l1cache-writeback-exclusive
|
|
.It
|
|
l1cache-writeback-owner
|
|
.It
|
|
l1cache-writeback-modified
|
|
.It
|
|
l2cache-access
|
|
.It
|
|
l2cache-tag-read
|
|
.It
|
|
l2cache-tag-write
|
|
.It
|
|
l2cache-inst-read
|
|
.It
|
|
l2cache-inst-load
|
|
.It
|
|
l2cache-data-store
|
|
.It
|
|
l2cache-data-loadmem
|
|
.It
|
|
l2cache-data-write
|
|
.It
|
|
l2cache-data-move
|
|
.It
|
|
l2cache-access-busy
|
|
.It
|
|
l2cache-hit
|
|
.It
|
|
l2cache-miss
|
|
.It
|
|
mem-misalign-ref
|
|
.It
|
|
mem-access
|
|
.It
|
|
mem-access-uc
|
|
.It
|
|
mem-access-wc
|
|
.It
|
|
mem-access-wt
|
|
.It
|
|
mem-access-wp
|
|
.It
|
|
mem-access-wb
|
|
.It
|
|
ins-fetch
|
|
.It
|
|
ins-fetch-miss
|
|
.It
|
|
ins-refill-l2
|
|
.It
|
|
ins-refill-mem
|
|
.It
|
|
ins-fetch-stall
|
|
.It
|
|
ins-retired
|
|
.It
|
|
ins-empty
|
|
.It
|
|
itlb-miss-l1
|
|
.It
|
|
itlb-miss-l2
|
|
.It
|
|
ops-retired
|
|
.It
|
|
branch-retired
|
|
.It
|
|
branch-miss-retired
|
|
.It
|
|
branch-taken-retired
|
|
.It
|
|
branch-taken-miss-retired
|
|
.It
|
|
branch-far-retired
|
|
.It
|
|
branch-resync-retired
|
|
.It
|
|
branch-near-retired
|
|
.It
|
|
branch-near-miss-retired
|
|
.It
|
|
branch-indirect-miss-retired
|
|
.It
|
|
int-hw
|
|
.It
|
|
int-cycles-masked
|
|
.It
|
|
int-cycles-masked-pending
|
|
.It
|
|
break-match0
|
|
.It
|
|
break-match1
|
|
.It
|
|
break-match2
|
|
.It
|
|
break-match3
|
|
.El
|
|
.El
|
|
.El
|
|
.Pp
|
|
The
|
|
.Nm pmc
|
|
library maintains a mapping between event names and the event selector
|
|
used by the CPU's performance monitoring hardware.
|
|
The mapping is described by the following structure:
|
|
.Bd -literal -offset indent
|
|
struct pmc_event {
|
|
const char *name;
|
|
pmc_evid_t val;
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The
|
|
.Fn pmc_configure_counter
|
|
function configures the counter
|
|
.Fa ctr
|
|
to count the event
|
|
.Fa evname .
|
|
The initial value of the counter will be set to
|
|
.Fa reset_val ,
|
|
and this value will be loaded back into the counter each time it overflows.
|
|
There are currently no flags defined for the
|
|
.Fa flags
|
|
argument.
|
|
.Pp
|
|
The
|
|
.Fn pmc_start_counter
|
|
function enables counting on counter
|
|
.Fa ctr .
|
|
.Pp
|
|
The
|
|
.Fn pmc_stop_counter
|
|
function disables counting on counter
|
|
.Fa ctr .
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_num_counters
|
|
function returns the number of counters present in the CPU.
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_counter_class
|
|
function returns the counter class of the CPU.
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_counter_type
|
|
function places the counter type of counter
|
|
.Fa ctr
|
|
into
|
|
.Fa *typep .
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_counter_value
|
|
function places the total number of events counted by counter
|
|
.Fa ctr
|
|
into
|
|
.Fa *valp .
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_accumulated_counter_value
|
|
function places the total number of events counted for the current
|
|
process and all of its children by counter
|
|
.Fa ctr
|
|
into
|
|
.Fa *valp .
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_counter_class_name
|
|
function returns the name of the counter class
|
|
.Fa classval .
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_counter_type_name
|
|
function returns the name of the counter type
|
|
.Fa type .
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_counter_event_name
|
|
function returns the name of the event
|
|
.Fa event
|
|
for the current CPU's performance counter class.
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_counter_event_list
|
|
function returns an array of
|
|
.Em pmc_event
|
|
structures, listing the supported event types for the CPU.
|
|
The array is terminated by and entry who's
|
|
.Em name
|
|
member is NULL.
|
|
.Sh RETURN VALUES
|
|
The
|
|
.Fn pmc_configure_counter ,
|
|
.Fn pmc_start_counter ,
|
|
.Fn pmc_stop_counter ,
|
|
.Fn pmc_get_counter_type ,
|
|
.Fn pmc_get_counter_value ,
|
|
and
|
|
.Fn pmc_get_accumulated_counter_value
|
|
functions return 0 to indicate success and -1 to indicate failure,
|
|
in which case
|
|
.Xr errno 2
|
|
will be set to indicate the mode of failure.
|
|
.Pp
|
|
The
|
|
.Fn pmc_get_counter_class_name ,
|
|
.Fn pmc_get_counter_type_name ,
|
|
.Fn pmc_get_counter_event_name ,
|
|
and
|
|
.Fn pmc_get_counter_event_list
|
|
functions return NULL and set
|
|
.Xr errno 2
|
|
to indicate failure.
|
|
.Sh SEE ALSO
|
|
.Xr pmc 1 ,
|
|
.Xr pmc_control 2 ,
|
|
.Xr pmc_get_info 2 ,
|
|
.Xr pmc 9
|
|
.Sh HISTORY
|
|
The
|
|
.Nm pmc
|
|
library first appeared in
|
|
.Nx 2.0 .
|
|
.Sh AUTHORS
|
|
The
|
|
.Nm pmc
|
|
library was written by
|
|
.An Jason R. Thorpe
|
|
.Aq thorpej@wasabisystems.com
|
|
and contributed by Wasabi Systems, Inc.
|