From b69ec3f6d953e67422dd32b72688cba850fd1b2e Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Mon, 13 Jan 2014 15:56:57 -0800 Subject: Initial commit --- .dir-locals.el | 40 ++ .gitignore | 56 ++ COPYING | 674 +++++++++++++++++++++ Doxyfile | 40 ++ INSTALL | 332 ++++++++++ Makefile.am | 50 ++ Makefile_doxygen.am | 164 +++++ README | 24 + bindings/haskell/.gitignore | 7 + bindings/haskell/README | 8 + bindings/haskell/Setup.hs | 22 + bindings/haskell/examples/simple.hs | 46 ++ bindings/haskell/ppamltracer.cabal | 62 ++ bindings/haskell/src/PPAML/Tracer.hs | 268 ++++++++ bindings/haskell/src/PPAML/Tracer/Exception.hs | 78 +++ bindings/java/.gitignore | 7 + bindings/java/README | 12 + bindings/java/build.xml | 165 +++++ bindings/java/examples/build.xml | 41 ++ .../com/galois/ppaml/tracer/examples/Simple.java | 84 +++ bindings/java/src/c/Makefile.am | 39 ++ .../java/src/c/com_galois_ppaml_tracer_Phase.c | 97 +++ .../java/src/c/com_galois_ppaml_tracer_Tracer.c | 76 +++ bindings/java/src/c/configure.ac | 58 ++ bindings/java/src/c/pointer.h | 38 ++ .../src/java/com/galois/ppaml/tracer/CWrapper.java | 184 ++++++ .../ppaml/tracer/ClockAcquisitionException.java | 35 ++ .../ppaml/tracer/NativeOutOfMemoryError.java | 38 ++ .../java/com/galois/ppaml/tracer/OTFException.java | 34 ++ .../galois/ppaml/tracer/OTFManagerException.java | 34 ++ .../tracer/OTFManagerInitializationException.java | 34 ++ .../ppaml/tracer/OTFWriterCloseException.java | 34 ++ .../ppaml/tracer/OTFWriterEntryException.java | 34 ++ .../galois/ppaml/tracer/OTFWriterException.java | 34 ++ .../ppaml/tracer/OTFWriterExitException.java | 34 ++ .../tracer/OTFWriterInitializationException.java | 34 ++ .../tracer/OTFWriterPhaseDefinitionException.java | 34 ++ .../OTFWriterProcessDefinitionException.java | 34 ++ .../ppaml/tracer/OTFWriterResolutionException.java | 34 ++ .../src/java/com/galois/ppaml/tracer/Phase.java | 220 +++++++ .../com/galois/ppaml/tracer/TimingException.java | 34 ++ .../src/java/com/galois/ppaml/tracer/Tracer.java | 163 +++++ .../ppaml/tracer/UnexpectedReturnValueError.java | 37 ++ .../java/com/galois/ppaml/tracer/package-info.java | 80 +++ bindings/python/.gitignore | 8 + bindings/python/MANIFEST.in | 21 + bindings/python/README | 11 + bindings/python/examples/simple.py | 49 ++ bindings/python/ppamltracer.py | 365 +++++++++++ bindings/python/setup.py | 34 ++ bindings/racket/.gitignore | 16 + bindings/racket/README | 11 + bindings/racket/main.rkt | 396 ++++++++++++ bindings/racket/manual.scrbl | 181 ++++++ configure.ac | 64 ++ examples/simple.c | 92 +++ include/Makefile.am | 23 + include/ppaml/tracer.h | 166 +++++ include/ppaml/tracer/internal.h | 111 ++++ m4/ax_prog_doxygen.m4 | 532 ++++++++++++++++ m4/otf.m4 | 74 +++ ppamltracer.pc.in | 10 + src/Makefile.am | 35 ++ src/index.dox | 45 ++ src/require.h | 46 ++ src/timing.c | 86 +++ src/timing.h | 32 + src/tracer.c | 133 ++++ 68 files changed, 6194 insertions(+) create mode 100644 .dir-locals.el create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 Doxyfile create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile_doxygen.am create mode 100644 README create mode 100644 bindings/haskell/.gitignore create mode 100644 bindings/haskell/README create mode 100644 bindings/haskell/Setup.hs create mode 100644 bindings/haskell/examples/simple.hs create mode 100644 bindings/haskell/ppamltracer.cabal create mode 100644 bindings/haskell/src/PPAML/Tracer.hs create mode 100644 bindings/haskell/src/PPAML/Tracer/Exception.hs create mode 100644 bindings/java/.gitignore create mode 100644 bindings/java/README create mode 100644 bindings/java/build.xml create mode 100644 bindings/java/examples/build.xml create mode 100644 bindings/java/examples/src/com/galois/ppaml/tracer/examples/Simple.java create mode 100644 bindings/java/src/c/Makefile.am create mode 100644 bindings/java/src/c/com_galois_ppaml_tracer_Phase.c create mode 100644 bindings/java/src/c/com_galois_ppaml_tracer_Tracer.c create mode 100644 bindings/java/src/c/configure.ac create mode 100644 bindings/java/src/c/pointer.h create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/CWrapper.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/ClockAcquisitionException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/NativeOutOfMemoryError.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFManagerException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFManagerInitializationException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterCloseException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterEntryException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterExitException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterInitializationException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterPhaseDefinitionException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterProcessDefinitionException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterResolutionException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/Phase.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/TimingException.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/Tracer.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/UnexpectedReturnValueError.java create mode 100644 bindings/java/src/java/com/galois/ppaml/tracer/package-info.java create mode 100644 bindings/python/.gitignore create mode 100644 bindings/python/MANIFEST.in create mode 100644 bindings/python/README create mode 100755 bindings/python/examples/simple.py create mode 100644 bindings/python/ppamltracer.py create mode 100755 bindings/python/setup.py create mode 100644 bindings/racket/.gitignore create mode 100644 bindings/racket/README create mode 100644 bindings/racket/main.rkt create mode 100644 bindings/racket/manual.scrbl create mode 100644 configure.ac create mode 100644 examples/simple.c create mode 100644 include/Makefile.am create mode 100644 include/ppaml/tracer.h create mode 100644 include/ppaml/tracer/internal.h create mode 100644 m4/ax_prog_doxygen.m4 create mode 100644 m4/otf.m4 create mode 100644 ppamltracer.pc.in create mode 100644 src/Makefile.am create mode 100644 src/index.dox create mode 100644 src/require.h create mode 100644 src/timing.c create mode 100644 src/timing.h create mode 100644 src/tracer.c diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..ed52889 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,40 @@ +;; .dir-locals.el -- directory-local variables for ppamltracer +;; Copyright (C) 2013 Galois, Inc. +;; +;; This library is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by the Free +;; Software Foundation, either version 3 of the License, or (at your option) +;; any later version. +;; +;; This library is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +;; more details. +;; +;; You should have received a copy of the GNU General Public License along with +;; this library. If not, see . +;; +;; To contact Galois, complete the Web form at +;; or write to Galois, Inc., 421 Southwest +;; 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. + +((autoconf . ((fill-column . 80) + (indent-tabs-mode . nil))) + (c . ((c-file-style . "k&r") + (c-basic-offset . 8) + (fill-column . 80) + (tab-width . 8) + (indent-tabs-mode . t))) + (haskell-cabal-mode . ((fill-column . 80) + (indent-tabs-mode . nil))) + (haskell-mode . ((fill-column . 80) + (indent-tabs-mode . nil))) + (java-mode . ((fill-column . 80) + (indent-tabs-mode . nil))) + (python . (; as per PEP 8 + (python-indent . 4) + (indent-tabs-mode . nil) + (fill-column . 79))) + (scheme-mode . ((indent-tabs-mode . nil))) + (scribble . ((indent-tabs-mode . nil))) + (nxml-mode . ((indent-tabs-mode . nil)))) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4caf57 --- /dev/null +++ b/.gitignore @@ -0,0 +1,56 @@ +# .gitignore for ppamltracer -*- conf -*- + +# Editor backup files +*~ +\#* +.\#* + +# autoscan +autoscan.log +configure.scan + +# aclocal +aclocal.m4 +autom4te.cache/ +m4/libtool.m4 +m4/lt*.m4 + +# autoconf +configure + +# autoheader +config.h.in + +# libtoolize +ltmain.sh + +# automake +Makefile.in +ar-lib +config.guess +config.sub +depcomp +install-sh +missing + +# configure +.deps/ +Makefile +config.h +config.log +config.status +libtool +ppamltracer.pc +stamp-* + +# make +.libs/ +*.la +*.lo +*.o + +# Doxygen +doc/ + +# Examples +examples/simple diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..fa1fec8 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,40 @@ +# Doxyfile -- Doxygen description for ppamltracer -*- conf -*- +# Copyright (C) 2013 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +PROJECT_NAME = $(PROJECT) + +OUTPUT_DIRECTORY = $(DOCDIR) +OPTIMIZE_OUTPUT_FOR_C = YES +GENERATE_CHI = $(GENERATE_CHI) +GENERATE_HTML = $(GENERATE_HTML) +GENERATE_HTMLHELP = $(GENERATE_HTMLHELP) +GENERATE_LATEX = $(GENERATE_LATEX) +GENERATE_MAN = $(GENERATE_MAN) +GENERATE_RTF = $(GENERATE_RTF) +GENERATE_XML = $(GENERATE_XML) +GENERATE_TAGFILE = $(DOCDIR)/$(PROJECT).tag + +INPUT = $(SRCDIR)/src/index.dox $(SRCDIR)/include +RECURSIVE = YES +JAVADOC_AUTOBRIEF = YES +ALPHABETICAL_INDEX = NO +IGNORE_PREFIX = ppaml_ + +EXAMPLE_PATH = $(SRCDIR)/examples diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..cc29059 --- /dev/null +++ b/INSTALL @@ -0,0 +1,332 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation, Inc. +Copyright (C) 2013, 2014 Galois, Inc. + +Copying and distribution of this file, with or without modification, are +permitted in any medium without royalty provided the copyright notice and this +notice are preserved. This file is offered as-is, without warranty of any kind. + +Basic Installation +================== + +Briefly, the shell commands + + ./configure + make + make install + +should configure, build, and install this package. + + +The `configure' shell script attempts to guess correct values for various +system-dependent variables used during compilation. It uses those values to +create a `Makefile' in the top-level directory of the package, as well as the +`include' and `src' subdirectories. It also creates a `config.h' file +containing system-dependent definitions. Finally, it creates a shell script +`config.status' that you can run in the future to recreate the current +configuration, and a file `config.log' containing compiler output (useful mainly +for debugging `configure'). + +It can also use an optional file (typically called `config.cache' and enabled +with `--cache-file=config.cache' or simply `-C') that saves the results of its +tests to speed up reconfiguring. Caching is disabled by default to prevent +problems with accidental use of stale cache files. + +If you need to do unusual things to compile the package, please try to figure +out how `configure' could check whether to do them, and mail diffs or +instructions to the address given in the `README' so they can be considered for +the next release. If you are using the cache, and at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + +The file `configure.ac' is used to create `configure' by a program called +`autoconf'. You need `configure.ac' if you want to change it or regenerate +`configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. If you have not done so already, install the Open Trace Format development + libraries and the `otfconfig' program. Many GNU/Linux distributions + provide packages for libotf and otfconfig; if you need, however, you may + download the source from + . + + 2. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints some + messages telling which features it is checking for. + + 3. Type `make' to compile the package. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular user, + and only the `make install' phase executed with root privileges. + + 5. You can remove the program binaries and object files from the source code + directory by typing `make clean'. To also remove the files that + `configure' created (so you can compile the package for a different kind + of computer), type `make distclean'. There is also a `make + maintainer-clean' target, but that is intended mainly for the package's + developers. If you use it, you may have to get all sorts of other + programs in order to regenerate files that came with the distribution. + + 6. You can also type `make uninstall' to remove the installed files again. + + 7. This package provides `make distcheck', which can by used by developers to + test that all other targets like `make install' and `make uninstall' work + correctly. This target is generally not run by end users. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for details +on some of the pertinent environment variables. + +You can give `configure' initial values for configuration parameters by setting +variables in the command line or in the environment. Here is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the same +time, by placing the object files for each architecture in their own directory. +To do this, you can use GNU `make'. `cd' to the directory where you want the +object files and executables to go and run the `configure' script. `configure' +automatically checks for the source code in the directory that `configure' is +in and in `..'. This is known as a "VPATH" build. + +With a non-GNU `make', it is safer to compile the package for one architecture +at a time in the source code directory. After you have installed the package +for one architecture, use `make distclean' before reconfiguring for another +architecture. + +On MacOS X 10.5 and later systems, you can create libraries and executables +that work on multiple system types--known as "fat" or "universal" binaries--by +specifying multiple `-arch' options to the compiler but only a single `-arch' +option to the preprocessor. Like this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + +This is not guaranteed to produce working output in all cases, you may have to +build one architecture at a time and combine the results using the `lipo' tool +if you have problems. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You can +specify an installation prefix other than `/usr/local' by giving `configure' +the option `--prefix=PREFIX', where PREFIX must be an absolute file name. + +You can specify separate installation prefixes for architecture-specific files +and architecture-independent files. If you pass the option +`--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix +for installing programs and libraries. Documentation and other data files +still use the regular prefix. + +In addition, if you use an unusual directory layout you can give options like +`--bindir=DIR' to specify different values for particular kinds of files. Run +`configure --help' for a list of the directories you can set and what kinds of +files go in them. In general, the default for these options is expressed in +terms of `${prefix}', so that specifying just `--prefix' will affect all of the +other directory specifications that were not explicitly provided. + +The most portable way to affect installation locations is to pass the correct +locations to `configure'; however, many packages provide one or both of the +following shortcuts of passing variable assignments to the `make install' +command line to change installation locations without having to reconfigure or +recompile. + +The first method involves providing an override variable for each affected +directory. For example, `make install prefix=/alternate/directory' will choose +an alternate location for all directory configuration variables that were +expressed in terms of `${prefix}'. Any directories that were specified during +`configure', but not in terms of `${prefix}', must each be overridden at +install time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by the GNU +Coding Standards, and ideally causes no recompilation. However, some platforms +have known limitations with the semantics of shared libraries that end up +requiring recompilation when using this method, particularly noticeable in +packages that use GNU Libtool. + +The second method involves providing the `DESTDIR' variable. For example, +`make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' +before all installation names. The approach of `DESTDIR' overrides is not +required by the GNU Coding Standards, and does not work on platforms that have +drive letters. On the other hand, it does better at avoiding recompilation +issues, and works well even when some directory options were not specified in +terms of `${prefix}' at `configure' time. + +Optional Features +================= + +This package pays attention to `--enable-FEATURE' options to `configure', where +FEATURE indicates an optional part of the package. It also pays attention to +`--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for +the X Window System). The `README' should mention any `--enable-' and +`--with-' options that the package recognizes. + +This package offers the ability to configure how verbose the execution of +`make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure --disable-silent-rules' +sets the default to verbose, which can be overridden with `make V=0'. + +Particular systems +================== + +On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not +installed, it is recommended to use the following options in order to use an +ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + +HP-UX `make' updates targets which have the same time stamps as their +prerequisites, which makes it generally unusable when shipped generated files +such as `configure' are involved. Use GNU `make' instead. + +On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its +`' header file. The option `-nodtk' can be used as a workaround. If +GNU CC is not installed, it is therefore recommended to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + +On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains +several dysfunctional programs; working variants of these programs are +available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it +_after_ `/usr/bin'. + +On Haiku, software installed for all users goes in `/boot/common', not +`/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, but +needs to determine by the type of machine the package will run on. Usually, +assuming the package is built to be run on the _same_ architectures, +`configure' can figure that out, but if it prints a message saying it cannot +guess the machine type, give it the `--build=TYPE' option. TYPE can either be +a short name for the system type, such as `sun4', or a canonical name which has +the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + +See the file `config.sub' for the possible values of each field. + +If you are _building_ compiler tools for cross-compiling, you should use the +option `--target=TYPE' to select the type of system they will produce code for. + +If you want to _use_ a cross compiler, that generates code for a platform +different from the build platform, you should specify the "host" platform +(i.e., that on which the generated programs will eventually be run) with +`--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you can +create a site shell script called `config.site' that gives default values for +variables like `CC', `cache_file', and `prefix'. `configure' looks for +`PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it +exists. Or, you can set the `CONFIG_SITE' environment variable to the location +of the site script. A warning: not all `configure' scripts look for a site +script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the environment +passed to `configure'. However, some packages may run configure again during +the build, and the customized values of these variables may be lost. In order +to avoid this problem, you should set them in the `configure' command line, +using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..d46630e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,50 @@ +# Makefile.am -- automake script for ppamltracer +# Copyright (C) 2013 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = include src +EXTRA_DIST = Doxyfile bindings examples +dist-hook: + $(RM) `find $(distdir) -type f -name .gitignore` + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = ppamltracer.pc + +include $(srcdir)/Makefile_doxygen.am +if DX_COND_doc +MOSTLYCLEANFILES = $(DX_CLEANFILES) + +all-local: doc + +doc: doxygen-doc + +install-data-local: install-doxygen-doc +install-doxygen-doc: $(DX_DOCDIR)/$(DX_PROJECT).tag + $(INSTALL) -d $(docdir) + cp -a $(DX_DOCDIR)/* $(docdir) + +uninstall-local: uninstall-doxygen-doc +uninstall-doxygen-doc: + $(RM) -r $(docdir)/{html,latex,man,$(DX_PROJECT).{ps,pdf},rtf,xml} + $(RM) $(docdir)/$(DX_PROJECT).tag + +.PHONY: doc install-doxygen-doc uninstall-doxygen-doc +endif DX_COND_doc diff --git a/Makefile_doxygen.am b/Makefile_doxygen.am new file mode 100644 index 0000000..73b1bf0 --- /dev/null +++ b/Makefile_doxygen.am @@ -0,0 +1,164 @@ +# Makefile_doxygen.am -- Makefile.am fragment to go along with AX_PROG_DOXYGEN +# Copyright (C) 2009 Oren Ben-Kiki +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice and this +# notice are preserved. This file is offered as-is, without any warranty. + +## --------------------------------- ## +## Format-independent Doxygen rules. ## +## --------------------------------- ## + +if DX_COND_doc + +## ------------------------------- ## +## Rules specific for HTML output. ## +## ------------------------------- ## + +if DX_COND_html + +DX_CLEAN_HTML = @DX_DOCDIR@/html + +endif DX_COND_html + +## ------------------------------ ## +## Rules specific for CHM output. ## +## ------------------------------ ## + +if DX_COND_chm + +DX_CLEAN_CHM = @DX_DOCDIR@/chm + +if DX_COND_chi + +DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi + +endif DX_COND_chi + +endif DX_COND_chm + +## ------------------------------ ## +## Rules specific for MAN output. ## +## ------------------------------ ## + +if DX_COND_man + +DX_CLEAN_MAN = @DX_DOCDIR@/man + +endif DX_COND_man + +## ------------------------------ ## +## Rules specific for RTF output. ## +## ------------------------------ ## + +if DX_COND_rtf + +DX_CLEAN_RTF = @DX_DOCDIR@/rtf + +endif DX_COND_rtf + +## ------------------------------ ## +## Rules specific for XML output. ## +## ------------------------------ ## + +if DX_COND_xml + +DX_CLEAN_XML = @DX_DOCDIR@/xml + +endif DX_COND_xml + +## ----------------------------- ## +## Rules specific for PS output. ## +## ----------------------------- ## + +if DX_COND_ps + +DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps + +DX_PS_GOAL = doxygen-ps + +doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps + +@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag + cd @DX_DOCDIR@/latex; \ + rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ + $(DX_LATEX) refman.tex; \ + $(MAKEINDEX_PATH) refman.idx; \ + $(DX_LATEX) refman.tex; \ + countdown=5; \ + while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ + refman.log > /dev/null 2>&1 \ + && test $$countdown -gt 0; do \ + $(DX_LATEX) refman.tex; \ + countdown=`expr $$countdown - 1`; \ + done; \ + $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi + +endif DX_COND_ps + +## ------------------------------ ## +## Rules specific for PDF output. ## +## ------------------------------ ## + +if DX_COND_pdf + +DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf + +DX_PDF_GOAL = doxygen-pdf + +doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf + +@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag + cd @DX_DOCDIR@/latex; \ + rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ + $(DX_PDFLATEX) refman.tex; \ + $(DX_MAKEINDEX) refman.idx; \ + $(DX_PDFLATEX) refman.tex; \ + countdown=5; \ + while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ + refman.log > /dev/null 2>&1 \ + && test $$countdown -gt 0; do \ + $(DX_PDFLATEX) refman.tex; \ + countdown=`expr $$countdown - 1`; \ + done; \ + mv refman.pdf ../@PACKAGE@.pdf + +endif DX_COND_pdf + +## ------------------------------------------------- ## +## Rules specific for LaTeX (shared for PS and PDF). ## +## ------------------------------------------------- ## + +if DX_COND_latex + +DX_CLEAN_LATEX = @DX_DOCDIR@/latex + +endif DX_COND_latex + +.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) + +.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) + +doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag + +doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) + +@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS) + rm -rf @DX_DOCDIR@ + $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) + +DX_CLEANFILES = \ + @DX_DOCDIR@/@PACKAGE@.tag \ + -r \ + $(DX_CLEAN_HTML) \ + $(DX_CLEAN_CHM) \ + $(DX_CLEAN_CHI) \ + $(DX_CLEAN_MAN) \ + $(DX_CLEAN_RTF) \ + $(DX_CLEAN_XML) \ + $(DX_CLEAN_PS) \ + $(DX_CLEAN_PDF) \ + $(DX_CLEAN_LATEX) + +endif DX_COND_doc + diff --git a/README b/README new file mode 100644 index 0000000..9801594 --- /dev/null +++ b/README @@ -0,0 +1,24 @@ + ppamltracer, v0.1.0 + +ppamltracer is a lightweight tracing library designed for explicit instrmention +of generated code. If you're writing a compiler and need hard data on your +optimizer's efficacy, ppamltracer is the library for you. + +ppamltracer writes trace logs in the Open Trace Format [1], a free and open +standard developed by the Zentrum für Informationsdienste und +Hochleistungsrechnen (Center for Information Services and High-Performance +Computing) at the Technical University of Dresden. + +This package contains the C code required to build the libppamltracer shared +library, as well as bindings for Haskell, Racket, Python, and Java. While the +bindings present idiomatic interfaces of various degrees of safety, they all +rely on the shared library, so you'll need to install that first. For detailed +installation instructions, see the INSTALL file. + +For examples that use the C API, see the examples directory. For examples that +use the APIs presented by the various language bindings, see the READMEs +associated with those bindings. + + +[1] http://tu-dresden.de/die_tu_dresden/zentrale_einrichtungen/zih/forschung/projekte/otf +[2] http://darpa.mil/Our_Work/I2O/Programs/Probabilistic_Programming_for_Advanced_Machine_Learning_(PPAML%29.aspx) diff --git a/bindings/haskell/.gitignore b/bindings/haskell/.gitignore new file mode 100644 index 0000000..805d057 --- /dev/null +++ b/bindings/haskell/.gitignore @@ -0,0 +1,7 @@ +# .gitignore for ppamltracer-haskell -*- conf -*- + +*.hi +*.o +dist*/ + +examples/simple diff --git a/bindings/haskell/README b/bindings/haskell/README new file mode 100644 index 0000000..3d9cf39 --- /dev/null +++ b/bindings/haskell/README @@ -0,0 +1,8 @@ + ppamltracer-haskell, v0.1.0 + +This package contains Haskell bindings to ppamltracer. They require GHC 7.6 or +later. + +This package uses the Cabal build system; normal Cabal build procedure applies. + +For examples of use, see the examples directory. diff --git a/bindings/haskell/Setup.hs b/bindings/haskell/Setup.hs new file mode 100644 index 0000000..fa38bd0 --- /dev/null +++ b/bindings/haskell/Setup.hs @@ -0,0 +1,22 @@ +{- Setup -- Cabal setup file for ppamltracer +Copyright (C) 2014 Galois, Inc. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +To contact Galois, complete the Web form at or +write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, Oregon, +97204-1622. -} + +import Distribution.Simple + +main = defaultMain diff --git a/bindings/haskell/examples/simple.hs b/bindings/haskell/examples/simple.hs new file mode 100644 index 0000000..478f25b --- /dev/null +++ b/bindings/haskell/examples/simple.hs @@ -0,0 +1,46 @@ +{- simple.hs -- basic ppamltracer example +This file is in the public domain. + +Compile this with + ghc --make simple.hs +-} + +{-# LANGUAGE LambdaCase #-} +module Main where + +import Control.Applicative ((<$>), (<*>)) +import Control.Monad (liftM) + +import PPAML.Tracer + +main :: IO () +main = do + -- Start ppamltracer. + withTracer "/tmp/simple_report" $ \tracer -> do + -- Register the factorial phase. + withPhase tracer "fact" $ \phase -> do + -- Print factorials. + putStr "Factorials:" + mapM_ (putStr . (' ':) . show) =<< mapM (fact phase) [0 .. 40] + putStrLn "" + -- Register the Fibonacci phase. + withPhase tracer "fib" $ \phase -> do + -- Print Fibonacci numbers. + putStr "Fibonacci numbers:" + mapM_ (putStr . (' ':) . show) =<< mapM (fib phase) [0 .. 25] + putStrLn "" + +{- Records that we're running inside the provided phase and computes a +factorial. -} +fact :: PhaseHandle -> Integer -> IO Integer +fact phase = withPhaseRunning phase . \case + 0 -> return 1 + n -> liftM (n*) $ fact phase (n - 1) + +{- Records that we're running inside the provided phase and computes a Fibonacci +number. -} +fib :: PhaseHandle -> Integer -> IO Integer +fib phase = withPhaseRunning phase . \case + 0 -> return 0 + 1 -> return 1 + n -> (+) <$> fib phase (n - 1) <*> fib phase (n - 2) diff --git a/bindings/haskell/ppamltracer.cabal b/bindings/haskell/ppamltracer.cabal new file mode 100644 index 0000000..5b6918e --- /dev/null +++ b/bindings/haskell/ppamltracer.cabal @@ -0,0 +1,62 @@ +-- ppamltracer.cabal -- Cabal build file for ppamltracer +-- Copyright (C) 2014 Galois, Inc. +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU General Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your option) any later +-- version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +-- details. +-- +-- You should have received a copy of the GNU General Public License along with +-- this program. If not, see . +-- +-- To contact Galois, complete the Web form at +-- or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +-- Oregon, 97204-1622. + +cabal-version: >=1.10 +name: ppamltracer +version: 0.1.0 +synopsis: A lightweight tracing library +description: ppamltracer is a lightweight tracing library designed for explicit + instrumention of generated code. If you’re writing a compiler and need hard + data on your optimizer’s efficacy, ppamltracer is the library for you. This + package uses Haskell’s foreign function interface to wrap the C libppamltracer + API. + . + ppamltracer writes trace logs in the + , a free and open standard + developed by the Zentrum für Informationsdienste und Hochleistungsrechnen + (Center for Information Services and High-Performance Computing) at the + Technical University of Dresden. + . + We developed ppamltracer as part of DARPA’s + + (PPAML) project. +copyright: © 2014 Galois, Inc. +license: GPL-3 +author: Benjamin Barenblat +maintainer: bbarenblat@galois.com +category: Language +build-type: Simple +extra-source-files: examples/simple.hs +tested-with: GHC==7.6.3 + +library + hs-source-dirs: src + default-language: Haskell2010 + other-extensions: DeriveDataTypeable + , EmptyDataDecls + , ExistentialQuantification + , TemplateHaskell + build-depends: base + , deepseq >=1.2.0.0 && <2 + , hierarchical-exceptions <2 + extra-libraries: ppamltracer + exposed-modules: PPAML.Tracer + other-modules: PPAML.Tracer.Exception + ghc-options: -Wall -O2 diff --git a/bindings/haskell/src/PPAML/Tracer.hs b/bindings/haskell/src/PPAML/Tracer.hs new file mode 100644 index 0000000..ddff15c --- /dev/null +++ b/bindings/haskell/src/PPAML/Tracer.hs @@ -0,0 +1,268 @@ +{- PPAML.Tracer -- PPAML timing instrumentation system (Haskell bindings) +Copyright (C) 2014 Galois, Inc. + +This library is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this library. If not, see . + +To contact Galois, complete the Web form at or +write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, Oregon, +97204-1622. -} + +{-| Getting started with ppamltracer is easy. Because of Haskell’s intrinsic +laziness, though, getting meaningful results out of ppamltracer is slightly more +difficult. For instance, consider the following (correctly written) example: + +> import PPAML.Tracer +> +> main = +> withTracer "/tmp/my_report" $ \tracer -> +> withPhase tracer "phase 1" $ \phase -> +> withPhaseRunning phase doStuff +> withPhase tracer "phase 2" $ \phase -> do +> withPhaseRunning phase doOtherStuff +> withPhaseRunning phase doYetMoreStuff + +This creates a report which appears to record the total runtime of 'doStuff' +recorded as \"phase 1\" and the total runtime of 'doOtherStuff' and +'doYetMoreStuff' combined as \"phase 2\". In actuality, however, the report +does not record the total runtime – instead, + +> withPhaseRunning phase f + +records the time required to evaluate 'f'’s result to normal form. Thus, 'f' +can leverage infinite data as intermediate values; only 'f'’s final result need +be finite. -} + +{-# LANGUAGE EmptyDataDecls #-} +{-# LANGUAGE LambdaCase #-} +module PPAML.Tracer + ( -- * Tracers + Tracer, TracerHandle + , withTracer + -- * Phases + , Phase, PhaseHandle + , withPhase + -- * Timing + , withPhaseRunning, withPhaseRunning_ + -- * Exceptions + {-| ppamltracer defines a fairly detailed exception hierarchy; however, + all exceptions are truly exceptional cases, and they likely will not + occur in normal use. For reference, the hierarchy looks like this: + + @ +'Control.Exception.SomeException' +└─ 'TracerException' + ├─ 'OTFException' + │ ├─ 'OTFManagerException' + │ │ └─ 'OTFManagerInitializationFailure' + │ └─ 'OTFWriterException' + │ ├─ 'OTFWriterInitializationFailure' + │ ├─ 'OTFPhaseDefinitionFailure' + │ ├─ 'OTFPhaseEntryFailure' + │ ├─ 'OTFPhaseExitFailure' + │ ├─ 'OTFWriterCloseFailure' + │ ├─ 'OTFTraceResolutionFailure' + │ └─ 'OTFProcessDefinitionFailure' + └─ 'TimingException' + └─ 'ClockAcquisitionFailure' + @ -} + , TracerException + -- ** Open Trace Format exceptions + , OTFException + , OTFManagerException, OTFManagerInitializationFailure + , OTFWriterException, OTFWriterInitializationFailure, + OTFPhaseDefinitionFailure, OTFPhaseEntryFailure, OTFPhaseExitFailure, + OTFWriterCloseFailure, OTFTraceResolutionFailure, + OTFProcessDefinitionFailure + -- ** Timing exceptions + , TimingException, ClockAcquisitionFailure + ) where + +import Control.DeepSeq (NFData, ($!!)) +import Control.Exception (bracket_, throw) +import Foreign (Storable, Ptr, allocaBytes, peek) +import Foreign.C (CInt(CInt), CSize(CSize), CString, withCString) +import System.IO.Unsafe (unsafeDupablePerformIO) + +import PPAML.Tracer.Exception + + +-------------------------------- High-level API -------------------------------- + +{-| Constructs a 'Tracer' and executes the specified computation. The trace +report will be stored in Open Trace Format; all trace file paths will begin with +the specified path. + +Throws: + + * 'OTFManagerInitializationFailure' if the Open Trace Format manager could not + be initialized. + + * 'OTFWriterInitializationFailure' if the Open Trace Format writer could not + be initialized. + + * 'OTFTraceResolutionFailure' if setting the trace resolution failed. + + * 'OTFProcessDefinitionFailure' if defining the main OTF process failed. + + * 'OTFWriterCloseFailure' if the Open Trace Format writer could not be closed + after the computation ran. -} + +withTracer :: FilePath -> (TracerHandle -> IO a) -> IO a +withTracer reportBaseName f = + allocaBytes tracerSize $ \tracerHandle -> + bracket_ (tracerInit tracerHandle reportBaseName) + (tracerDone tracerHandle) + (f tracerHandle) + +{-| Constructs a 'Phase' and executes the specified computation. + +Throws 'OTFPhaseDefinitionFailure' if the phase could not be defined. -} +withPhase :: TracerHandle -- ^ the associated 'Tracer' + -> String -- ^ the name of the 'Phase' + -> (PhaseHandle -> IO a) + -> IO a +withPhase tracer name f = + allocaBytes phaseSize $ \phaseHandle -> + bracket_ (phaseInit tracer phaseHandle name) + (phaseDone phaseHandle) + (f phaseHandle) + +{-| Executes an IO action and evaluates its result to normal form, recording the +time required to do so in the provided 'Phase'. -} +withPhaseRunning :: NFData a => PhaseHandle -> IO a -> IO a +withPhaseRunning phase f = withPhaseRunning_ phase ((return $!!) =<< f) + +{-| Executes an IO action, recording the time required to do so in the provided +'Phase'. Unlinke 'withPhaseRunning', this function does /not/ evaluate the +action’s result. Use this function when you need finer-grained control over the +precise degree of evaluation than 'withPhaseRunning' offers. +-} +withPhaseRunning_ :: PhaseHandle -> IO a -> IO a +withPhaseRunning_ phase = bracket_ (phaseStart phase) (phaseStop phase) + + +----------------------------------- Tracers ------------------------------------ + +----- Data type ----- + +{-| Tracer state bundle. ppamltracer is fundamentally a set of stateful +operations; this data type dsecribes the state ppamltracer needs to operate +properly. A one-to-one mapping exists between 'Tracer's and trace reports, so +you will likely only need one 'Tracer' per program. -} +data Tracer + +foreign import ccall unsafe "ppaml/tracer/internal.h & ppaml_tracer_t_size" + ppaml_tracer_t_size :: Ptr CSize + +tracerSize :: Int +tracerSize = fromIntegral $ unsafeReadLibraryConstant ppaml_tracer_t_size + + +----- Initialization and finalization ----- + +type TracerHandle = Ptr Tracer + +foreign import ccall unsafe "ppaml/tracer.h ppaml_tracer_init" + ppaml_tracer_init :: TracerHandle -> CString -> IO CInt + +tracerInit :: TracerHandle -> FilePath -> IO () +tracerInit tracer reportNameBase = + withCString reportNameBase $ \cReportNameBase -> + ppaml_tracer_init tracer cReportNameBase >>= \case + 0 -> return () + 1 -> throw OTFManagerInitializationFailure + 2 -> throw OTFWriterInitializationFailure + 3 -> throw OTFTraceResolutionFailure + 4 -> throw OTFProcessDefinitionFailure + r -> unexpectedReturnCode r + +foreign import ccall unsafe "ppaml/tracer.h ppaml_tracer_done" + ppaml_tracer_done :: TracerHandle -> IO CInt + +tracerDone :: TracerHandle -> IO () +tracerDone tracer = + ppaml_tracer_done tracer >>= \case 0 -> return () + 1 -> throw OTFWriterCloseFailure + r -> unexpectedReturnCode r + + +------------------------------------ Phases ------------------------------------ + +----- Data type ----- + +-- | A phase of execution to trace and to gather timing statistics about. +data Phase + +foreign import ccall unsafe "ppaml/tracer/internal.h & ppaml_phase_t_size" + ppaml_phase_t_size :: Ptr CSize + +phaseSize :: Int +phaseSize = fromIntegral $ unsafeReadLibraryConstant ppaml_phase_t_size + + +----- Initialization and finalization ----- + +type PhaseHandle = Ptr Phase + +foreign import ccall unsafe "ppaml/tracer.h ppaml_phase_init" + ppaml_phase_init :: TracerHandle -> PhaseHandle -> CString -> IO CInt + +phaseInit :: TracerHandle -> PhaseHandle -> String -> IO () +phaseInit tracer phase name = + withCString name $ \cName -> + ppaml_phase_init tracer phase cName >>= \case + 0 -> return () + 1 -> throw OTFPhaseDefinitionFailure + r -> unexpectedReturnCode r + +foreign import ccall unsafe "ppaml/tracer.h ppaml_phase_done" + ppaml_phase_done :: PhaseHandle -> IO CInt + +phaseDone :: PhaseHandle -> IO () +phaseDone phase = + ppaml_phase_done phase >>= \case 0 -> return () + r -> unexpectedReturnCode r + + +----- Timing ----- + +foreign import ccall unsafe "ppaml/tracer.h ppaml_phase_start" + ppaml_phase_start :: PhaseHandle -> IO CInt + +phaseStart :: PhaseHandle -> IO () +phaseStart phase = + ppaml_phase_start phase >>= \case 0 -> return () + 1 -> throw ClockAcquisitionFailure + 2 -> throw OTFPhaseEntryFailure + r -> unexpectedReturnCode r + +foreign import ccall unsafe "ppaml/tracer.h ppaml_phase_stop" + ppaml_phase_stop :: PhaseHandle -> IO CInt + +phaseStop :: PhaseHandle -> IO () +phaseStop phase = + ppaml_phase_stop phase >>= \case 0 -> return () + 1 -> throw ClockAcquisitionFailure + 2 -> throw OTFPhaseExitFailure + r -> unexpectedReturnCode r + + +----------------------------------- Utility ------------------------------------ + +unsafeReadLibraryConstant :: Storable a => Ptr a -> a +unsafeReadLibraryConstant = unsafeDupablePerformIO . peek + +unexpectedReturnCode :: CInt -> a +unexpectedReturnCode code = + error $ "unexpected return code " ++ show code ++ "\n\ + \This is a bug in ppamltracer! Report it to the maintainers." diff --git a/bindings/haskell/src/PPAML/Tracer/Exception.hs b/bindings/haskell/src/PPAML/Tracer/Exception.hs new file mode 100644 index 0000000..ba77c84 --- /dev/null +++ b/bindings/haskell/src/PPAML/Tracer/Exception.hs @@ -0,0 +1,78 @@ +{- PPAML.Tracer.Exception -- exceptions used by ppamltracer +Copyright (C) 2014 Galois, Inc. + +This library is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this library. If not, see . + +To contact Galois, complete the Web form at or +write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, Oregon, +97204-1622. -} + +{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE TemplateHaskell #-} +module PPAML.Tracer.Exception where + +import Control.Exception (SomeException(SomeException)) +import Control.Exception.Hierarchical (mkAbstractException, mkException) + +-- | A generic ppamltracer error. Extends 'SomeException'. +mkAbstractException 'SomeException "TracerException" + + +-------------------------------- OTF exceptions -------------------------------- + +{-| An error related to Open Trace Format input and output. Extends +'TracerException'. -} +mkAbstractException 'TracerException "OTFException" + +-- | An error caused by the Open Trace Fromat manager. Extends 'OTFException'. +mkAbstractException 'OTFException "OTFManagerException" + +{-| Failure to initialize the Open Trace Format manager. Extends +'OTFManagerException'. -} +mkException 'OTFManagerException "OTFManagerInitializationFailure" + +-- | An error caused by the Open Trace Format writer. Extends 'OTFException'. +mkAbstractException 'OTFException "OTFWriterException" + +{-| Failure to initialize the Open Trace Format writer. Extends +'OTFWriterException'. -} +mkException 'OTFWriterException "OTFWriterInitializationFailure" + +-- | Failure to define a phase. Extends 'OTFWriterException'. +mkException 'OTFWriterException "OTFPhaseDefinitionFailure" + +-- | Failure to record entry into a phase. Extends 'OTFWriterException'. +mkException 'OTFWriterException "OTFPhaseEntryFailure" + +-- | Failure to record exit from a phase. Extends 'OTFWriterException'. +mkException 'OTFWriterException "OTFPhaseExitFailure" + +{-| Failure to close the Open Trace Format writer. Extends +'OTFWriterException'. -} +mkException 'OTFWriterException "OTFWriterCloseFailure" + +-- | Failure to set the tracer resolution. Extends 'OTFWriterException'. +mkException 'OTFWriterException "OTFTraceResolutionFailure" + +-- | Failure to define a process (i.e., a thread). Extends 'OTFWriterException'. +mkException 'OTFWriterException "OTFProcessDefinitionFailure" + + +------------------------------ Timing exceptions ------------------------------- + +-- | An error related to system timers. Extends 'TracerException'. +mkAbstractException 'TracerException "TimingException" + +-- | A failure to get the current clock time. Extends 'TimingException'. +mkException 'TimingException "ClockAcquisitionFailure" diff --git a/bindings/java/.gitignore b/bindings/java/.gitignore new file mode 100644 index 0000000..32690c1 --- /dev/null +++ b/bindings/java/.gitignore @@ -0,0 +1,7 @@ +# .gitignore for ppamltracer-java -*- conf -*- + +build/ +dist/ + +# Examples +examples/dist diff --git a/bindings/java/README b/bindings/java/README new file mode 100644 index 0000000..b5d4bfb --- /dev/null +++ b/bindings/java/README @@ -0,0 +1,12 @@ + ppamltracer-java, v0.1.0 + +This package contains Java bindings to ppamltracer. They require Java SE 5 or +later. + +This package uses the Java Native Interface. Therefore, building it produces +two artifacts: a jar, which you should install in your CLASSPATH, and a shared +library, which you should install in your LD_LIBRARY_PATH. If you have both +Ant and autotools installed, simply typing `ant' will build both artifacts and +install them in the `dist' directory. + +For examples of use, see the examples directory. diff --git a/bindings/java/build.xml b/bindings/java/build.xml new file mode 100644 index 0000000..d4e57f6 --- /dev/null +++ b/bindings/java/build.xml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bindings/java/examples/build.xml b/bindings/java/examples/build.xml new file mode 100644 index 0000000..e7f6f4d --- /dev/null +++ b/bindings/java/examples/build.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/bindings/java/examples/src/com/galois/ppaml/tracer/examples/Simple.java b/bindings/java/examples/src/com/galois/ppaml/tracer/examples/Simple.java new file mode 100644 index 0000000..a698573 --- /dev/null +++ b/bindings/java/examples/src/com/galois/ppaml/tracer/examples/Simple.java @@ -0,0 +1,84 @@ +/* Simple -- basic ppamltracer example + * This file is in the public domain. */ + +package com.galois.ppaml.tracer.examples; + +import com.galois.ppaml.tracer.Phase; +import com.galois.ppaml.tracer.Tracer; + +public class Simple { + + protected Phase factPhase; + + protected Phase fibPhase; + + protected void go(Tracer tracer) { + // Register the phases. + factPhase = tracer.createPhase("fact"); + fibPhase = tracer.createPhase("fib"); + + // Print factorials. + System.out.print("Factorials:"); + for (int i = 0; i < 21; i++) { + System.out.print(" " + fact(i)); + } + System.out.println(); + + // Print Fibonacci numbers. + System.out.print("Fibonacci numbers:"); + for (int i = 0; i < 30; i++) { + System.out.print(" " + fib(i)); + } + System.out.println(); + + // Finalize phases and exit. + factPhase.close(); + fibPhase.close(); + } + + protected long fact(int n) { + // Record that we're running inside the factorial phase. + factPhase.start(); + // Compute the factorial. + long result; + if (n == 0) { + result = 1; + } else { + result = n * fact(n - 1); + } + // Return the result. + factPhase.stop(); + return result; + } + + protected int fib(int n) { + // Record that we're running inside the Fibonacci phase. + fibPhase.start(); + // Compute the nth Fibonacci number. + int result; + switch (n) { + case 0: + case 1: + result = n; + break; + default: + result = fib(n - 1) + fib(n - 2); + break; + } + // Return the result. + fibPhase.stop(); + return result; + } + + public static void main(String[] args) { + // Start ppamltracer. + Tracer tracer = new Tracer("/tmp/simple_report"); + + // Run the app. + (new Simple()).go(tracer); + + // Finalize ppamltracer and exit. + tracer.close(); + } + +} diff --git a/bindings/java/src/c/Makefile.am b/bindings/java/src/c/Makefile.am new file mode 100644 index 0000000..c30a4cf --- /dev/null +++ b/bindings/java/src/c/Makefile.am @@ -0,0 +1,39 @@ +# Makefile.am -- automake script for ppamltracer-java (JNI wrapper) +# Copyright (C) 2013, 2014 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +ACLOCAL_AMFLAGS = -I m4 + +lib_LTLIBRARIES = libppamltracer_java.la +libppamltracer_java_la_SOURCES = \ + $(srcdir)/com_galois_ppaml_tracer_Phase.c \ + $(srcdir)/com_galois_ppaml_tracer_Phase.h \ + $(srcdir)/com_galois_ppaml_tracer_Tracer.c \ + $(srcdir)/com_galois_ppaml_tracer_Tracer.h \ + $(srcdir)/pointer.h +libppamltracer_java_la_CFLAGS = \ + -std=c99 \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -pedantic \ + -I@JAVA_HOME@/include +libppamltracer_java_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -export-symbols-regex '^Java_' diff --git a/bindings/java/src/c/com_galois_ppaml_tracer_Phase.c b/bindings/java/src/c/com_galois_ppaml_tracer_Phase.c new file mode 100644 index 0000000..76f346b --- /dev/null +++ b/bindings/java/src/c/com_galois_ppaml_tracer_Phase.c @@ -0,0 +1,97 @@ +/* com_galois_ppaml_tracer_Phase.c -- JNI wrapper for com.galois.ppaml.tracer.Phase + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +#include + +#include + +#include +#include + +#include "pointer.h" + +JNIEXPORT +jlong JNICALL Java_com_galois_ppaml_tracer_Phase_mallocPhase( + JNIEnv *const env, + jclass Phase) +{ + return jlong_of_pointer(malloc(sizeof(ppaml_phase_t))); +} + +JNIEXPORT +jint JNICALL Java_com_galois_ppaml_tracer_Phase_ppaml_1phase_1init( + JNIEnv *const env, + jclass Phase, + jlong tracer, + jlong phase, + jstring name) +{ + jint r; + // Allocate memory. + const char *const cName = (*env)->GetStringUTFChars(env, name, NULL); + if (cName == NULL) { + r = -1; + goto done; + } + // Perform the operation. + r = ppaml_phase_init( + pointer_of_jlong(tracer), + pointer_of_jlong(phase), + cName); + // Clean up. +done: (*env)->ReleaseStringUTFChars(env, name, cName); + return r; +} + +JNIEXPORT +jint JNICALL Java_com_galois_ppaml_tracer_Phase_ppaml_1phase_1done( + JNIEnv *const env, + jclass Phase, + jlong phase) +{ + return ppaml_phase_done(pointer_of_jlong(phase)); +} + +JNIEXPORT +void JNICALL Java_com_galois_ppaml_tracer_Phase_freePhase( + JNIEnv *const env, + jclass Phase, + jlong phase) +{ + free(pointer_of_jlong(phase)); +} + +JNIEXPORT +jint JNICALL Java_com_galois_ppaml_tracer_Phase_ppaml_1phase_1start( + JNIEnv *const env, + jclass Phase, + jlong phase) +{ + return ppaml_phase_start(pointer_of_jlong(phase)); +} + +JNIEXPORT +jint JNICALL Java_com_galois_ppaml_tracer_Phase_ppaml_1phase_1stop( + JNIEnv *const env, + jclass Phase, + jlong phase) +{ + return ppaml_phase_stop(pointer_of_jlong(phase)); +} diff --git a/bindings/java/src/c/com_galois_ppaml_tracer_Tracer.c b/bindings/java/src/c/com_galois_ppaml_tracer_Tracer.c new file mode 100644 index 0000000..2c23966 --- /dev/null +++ b/bindings/java/src/c/com_galois_ppaml_tracer_Tracer.c @@ -0,0 +1,76 @@ +/* com_galois_ppaml_tracer_Tracer.c -- JNI wrapper for com.galois.ppaml.tracer.Tracer + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +#include + +#include + +#include +#include + +#include "pointer.h" + +JNIEXPORT +jlong JNICALL Java_com_galois_ppaml_tracer_Tracer_mallocTracer( + JNIEnv *const env, + jclass Tracer) +{ + return jlong_of_pointer(malloc(sizeof(ppaml_tracer_t))); +} + +JNIEXPORT +jint JNICALL Java_com_galois_ppaml_tracer_Tracer_ppaml_1tracer_1init( + JNIEnv *const env, + jclass Tracer, + jlong tracer, + jstring reportNameBase) +{ + jint r; + // Allocate memory. + const char *const cReportNameBase = + (*env)->GetStringUTFChars(env, reportNameBase, NULL); + if (cReportNameBase == NULL) { + r = -1; + goto done; + } + // Perform the operation. + r = ppaml_tracer_init(pointer_of_jlong(tracer), cReportNameBase); + // Clean up. +done: (*env)->ReleaseStringUTFChars(env, reportNameBase, cReportNameBase); + return r; +} + +JNIEXPORT +jint JNICALL Java_com_galois_ppaml_tracer_Tracer_ppaml_1tracer_1done( + JNIEnv *const env, + jclass Tracer, + jlong tracer) +{ + return ppaml_tracer_done(pointer_of_jlong(tracer)); +} + +JNIEXPORT +void JNICALL Java_com_galois_ppaml_tracer_Tracer_freeTracer( + JNIEnv *const env, + jclass Tracer, + jlong tracer) +{ + free(pointer_of_jlong(tracer)); +} diff --git a/bindings/java/src/c/configure.ac b/bindings/java/src/c/configure.ac new file mode 100644 index 0000000..0d1556b --- /dev/null +++ b/bindings/java/src/c/configure.ac @@ -0,0 +1,58 @@ +# configure.ac -- autoconf script for ppamltracer-java (JNI wrapper) +# Copyright (C) 2013, 2014 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +# Fire up Autoconf. +AC_PREREQ([2.69]) +AC_INIT([ppamltracer-java], [0.1.0], [bbarenblat@galois.com]) + +# Fire up Automake. +AM_INIT_AUTOMAKE([-Wall -Wno-gnu -Werror foreign no-dist-gzip dist-bzip2]) +AC_CONFIG_MACRO_DIR([m4]) + +# Build quietly. +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +# Build a C library. +AC_PROG_CC +AC_PROG_CC_C99 +# Automake 1.12 seems to require this, but automake 1.11 doesn't recognize it. +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +LT_INIT + +# JNI +AC_ARG_VAR([JAVA_HOME], [path to JDK installation]) +if test -z "$JAVA_HOME"; then + AC_MSG_ERROR([empty JAVA_HOME environment variable; please set it to the path to your JDK installation]) +fi +AC_SUBST([JAVA_HOME]) + +# ppamltracer +AC_CHECK_HEADER([ppaml/tracer.h], + [], + [AC_MSG_ERROR([ppamltracer development headers are required (are they in C_INCLUDE_PATH?)])]) +AC_CHECK_LIB([ppamltracer], [ppaml_tracer_init], + [], + [AC_MSG_ERROR([libppamltracer is required (is it in LIBRARY_PATH?)])]) + +# Generate Makefile. +AC_CONFIG_FILES([Makefile]) + +# All done. +AC_OUTPUT diff --git a/bindings/java/src/c/pointer.h b/bindings/java/src/c/pointer.h new file mode 100644 index 0000000..123025d --- /dev/null +++ b/bindings/java/src/c/pointer.h @@ -0,0 +1,38 @@ +/* pointer.h -- pointer <-> jlong casts + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +#ifndef PPAML_TRACER_JAVA_POINTER_H +#define PPAML_TRACER_JAVA_POINTER_H + +#include + +#include + +inline void *pointer_of_jlong(const jlong value) +{ + return (void *)(intptr_t)value; +} + +inline jlong jlong_of_pointer(void *const pointer) +{ + return (jlong)(intptr_t)pointer; +} + +#endif diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/CWrapper.java b/bindings/java/src/java/com/galois/ppaml/tracer/CWrapper.java new file mode 100644 index 0000000..5a7887a --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/CWrapper.java @@ -0,0 +1,184 @@ +/* CWrapper -- wrapping C structures + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * A class which wraps a C structure and associated functions. + * + *

This class is intended to work hand-in-hand with Java Native Interface + * code that follows a four-stage lifecycle: + * + *

+ *
Allocation
The system reserves memory and resources needed by + * the structure.
+ *
Initialization
The system installs data into the structure to + * make it ready for use.
+ *
Finalization
The system cleans up the data structure under the + * assumption that it will not be used anymore.
+ *
Freeing
The system releases memory and resources needed by the + * structure.
+ *
+ * + * This class defines abstract methods associated with each of these phases; by + * defining contracts on them, it can then consolidate the phases into two + * concretely-implemented operations: + * + *
+ *
Open
The system allocates and initializes the underlying + * structure.
+ *
Close
The system finalizes and frees the underlying + * structure.
+ *
+ * + *

This class is not intended to be instantiated directly. Only + * instantiate its concrete subclasses. + */ +abstract class CWrapper { + + /** + * C pointer to the underlying data structure. + */ + protected long cPointer; + + + /////////////////////////// Low-level life cycle /////////////////////////// + + /** + * Reserves memory and resources needed by the structure. + * + *

Precondition: cPointer is 0. + * + *

Postcondition: If allocation was successful, + * cPointer is not 0. + */ + abstract protected void allocateCPointer(); + + /** + * Installs data into the structure to make it ready for use. + * + *

Precondition: Allocation succeeded. + */ + abstract protected void initializeCPointer(); + + /** + * Cleans up the structure under the assumption that it will not be used + * anymore. + * + *

Precondition: Initialization succeeded. + */ + abstract protected void finalizeCPointer(); + + /** + * Releases memory and resources needed by the structure. + * + *

Precondition: cPointer is not 0.
+ * Precondition: Finalization succeeded. + * + *

Postcondition: cPointer is 0. + */ + abstract protected void freeCPointer(); + + + ////////////////////////// High-level life cycle ////////////////////////// + + /** + * Allocates and initializes the underlying structure. + * + * @throws OpenedException the underlying structure has already been opened. + * + * @throws NativeOutOfMemoryError allocation failed. + */ + protected synchronized void open() { + if (cPointer != 0) { + throw new OpenedException(); + } + allocateCPointer(); + if (cPointer == 0) { + throw new NativeOutOfMemoryError(); + } + initializeCPointer(); + } + + /** + * Finalizes and frees the underlying structure. + * + * @throws ClosedException the underlying structure has already been closed. + */ + public synchronized void close() { + if (cPointer == 0) { + throw new ClosedException(); + } + finalizeCPointer(); + freeCPointer(); + cPointer = 0; + } + + + ////////////////////////// Associated exceptions ////////////////////////// + + /** + * Signals that the underlying structure is already open. + */ + public class OpenedException extends java.lang.IllegalStateException { + + static final long serialVersionUID = -7226578680647930527L; + + /** + * Constructs a CWrapper.OpenedException with no detail + * message. + */ + protected OpenedException() { + super(); + } + + } + + /** + * Signals that the underlying structure is already closed. + */ + public class ClosedException extends java.lang.IllegalStateException { + + static final long serialVersionUID = -2471059099211958977L; + + /** + * Constructs a CWrapper.ClosedException with no detail + * message. + */ + protected ClosedException() { + super(); + } + + } + + + ////////////////////////////// Miscellaneous ////////////////////////////// + + @Override + protected void finalize() { + close(); + } + + @Override + protected Object clone() throws java.lang.CloneNotSupportedException { + throw new java.lang.CloneNotSupportedException(); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/ClockAcquisitionException.java b/bindings/java/src/java/com/galois/ppaml/tracer/ClockAcquisitionException.java new file mode 100644 index 0000000..68b212d --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/ClockAcquisitionException.java @@ -0,0 +1,35 @@ +/* ClockAcquisitionException -- failure to get the time + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to get the current time. This could be due to any number + * of operating-system dependent factors. + */ +public class ClockAcquisitionException extends TimingException { + + static final long serialVersionUID = -5730008048750495655L; + + protected ClockAcquisitionException() { + super("could not get current time"); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/NativeOutOfMemoryError.java b/bindings/java/src/java/com/galois/ppaml/tracer/NativeOutOfMemoryError.java new file mode 100644 index 0000000..7c5ca3e --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/NativeOutOfMemoryError.java @@ -0,0 +1,38 @@ +/* NativeOutOfMemoryError -- failure to allocate with malloc + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to allocate on the native heap. + */ +public class NativeOutOfMemoryError extends java.lang.Error { + + static final long serialVersionUID = 1826582972785125106L; + + protected NativeOutOfMemoryError() { + super(); + } + + protected NativeOutOfMemoryError(String s) { + super(s); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFException.java new file mode 100644 index 0000000..a639c69 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFException.java @@ -0,0 +1,34 @@ +/* OTFException -- signals an OTF-related failure + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure related to the Open Trace Format API. + */ +public class OTFException extends java.lang.RuntimeException { + + static final long serialVersionUID = 29573934735841980L; + + protected OTFException(String s) { + super(s); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFManagerException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFManagerException.java new file mode 100644 index 0000000..b41d528 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFManagerException.java @@ -0,0 +1,34 @@ +/* OTFManagerException -- signals a failure related to the OTF manager + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure related to the Open Trace Format file manager. + */ +public class OTFManagerException extends OTFException { + + static final long serialVersionUID = 9158227932426782179L; + + protected OTFManagerException(String s) { + super(s); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFManagerInitializationException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFManagerInitializationException.java new file mode 100644 index 0000000..e4f61a0 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFManagerInitializationException.java @@ -0,0 +1,34 @@ +/* OTFManagerInitializationException -- failure to start the OTF manager + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to initialize the Open Trace Format file manager. + */ +public class OTFManagerInitializationException extends OTFManagerException { + + static final long serialVersionUID = 8357422459731580151L; + + protected OTFManagerInitializationException() { + super("could not initialize Open Trace Format file manager"); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterCloseException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterCloseException.java new file mode 100644 index 0000000..6b08d7d --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterCloseException.java @@ -0,0 +1,34 @@ +/* OTFWriterCloseException -- failure to close the OTF writer + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to close the Open Trace Format writer. + */ +public class OTFWriterCloseException extends OTFWriterException { + + static final long serialVersionUID = -3744439236064694516L; + + protected OTFWriterCloseException() { + super("could not close Open Trace Format writer"); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterEntryException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterEntryException.java new file mode 100644 index 0000000..e330941 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterEntryException.java @@ -0,0 +1,34 @@ +/* OTFWriterEntryException -- failure to record phase entry + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to record {@link Phase} entry. + */ +public class OTFWriterEntryException extends OTFWriterException { + + static final long serialVersionUID = -3863070199086068755L; + + protected OTFWriterEntryException() { + super("could not record phase start"); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterException.java new file mode 100644 index 0000000..f1d0e3c --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterException.java @@ -0,0 +1,34 @@ +/* OTFWriterException -- failure related to the OTF writer + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure related to the Open Trace Format writer. + */ +public class OTFWriterException extends OTFException { + + static final long serialVersionUID = -8501407892120456005L; + + protected OTFWriterException(String s) { + super(s); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterExitException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterExitException.java new file mode 100644 index 0000000..502e4bf --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterExitException.java @@ -0,0 +1,34 @@ +/* OTFWriterExitException -- failure to record phase exit + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to record {@link Phase} entry. + */ +public class OTFWriterExitException extends OTFWriterException { + + static final long serialVersionUID = 2672929667606300155L; + + protected OTFWriterExitException() { + super("could not record phase end"); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterInitializationException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterInitializationException.java new file mode 100644 index 0000000..315ceb2 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterInitializationException.java @@ -0,0 +1,34 @@ +/* OTFWriterInitializationException -- failure to start the OTF writer + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to initialize the Open Trace Format writer. + */ +public class OTFWriterInitializationException extends OTFWriterException { + + static final long serialVersionUID = -160590670499907090L; + + protected OTFWriterInitializationException() { + super("could not open Open Trace Format writer"); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterPhaseDefinitionException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterPhaseDefinitionException.java new file mode 100644 index 0000000..225b32b --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterPhaseDefinitionException.java @@ -0,0 +1,34 @@ +/* OTFWriterPhaseDefinitionException -- failure to define an OTF phase + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to define a {@link Phase}. + */ +public class OTFWriterPhaseDefinitionException extends OTFWriterException { + + static final long serialVersionUID = -5221693771344940262L; + + protected OTFWriterPhaseDefinitionException() { + super("could not define phase"); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterProcessDefinitionException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterProcessDefinitionException.java new file mode 100644 index 0000000..dc95859 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterProcessDefinitionException.java @@ -0,0 +1,34 @@ +/* OTFWriterProcessDefinitionException -- failure to define an OTF process + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to define an Open Trace Format process (thread). + */ +public class OTFWriterProcessDefinitionException extends OTFWriterException { + + static final long serialVersionUID = -2403392867513685061L; + + protected OTFWriterProcessDefinitionException(String processName) { + super("could not define Open Trace Format Process " + processName); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterResolutionException.java b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterResolutionException.java new file mode 100644 index 0000000..bccacc1 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/OTFWriterResolutionException.java @@ -0,0 +1,34 @@ +/* OTFWriterResolutionException -- failure to set the trace resolution + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure to set the time resolution of a {@link Tracer}. + */ +public class OTFWriterResolutionException extends OTFWriterException { + + static final long serialVersionUID = 7655059683403795873L; + + protected OTFWriterResolutionException() { + super("could not set trace resolution"); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/Phase.java b/bindings/java/src/java/com/galois/ppaml/tracer/Phase.java new file mode 100644 index 0000000..23ed2f4 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/Phase.java @@ -0,0 +1,220 @@ +/* Phase -- wrapped ppaml_phase_t + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * A phase of execution to trace. This class exports no public constructors; + * to instantiate it, use Tracer.createPhase. + */ +public final class Phase extends CWrapper { + + /** + * The Tracer this phase is associated with. + */ + private final Tracer tracer; + + /** + * The name of the phase. + */ + private final String name; + + /** + * Creates and initializes a Phase. You should not call this; + * call {@link Tracer.createPhase} instead. + * + * @param tracer the {@link Tracer} to associate the Phase + * with. + * + * @param name the name of the phase. + */ + protected Phase(Tracer tracer, final String name) { + this.tracer = tracer; + this.name = name; + super.open(); + } + + + ////////////////////////// Low-level life cycle ////////////////////////// + + ///// JNI shared library ///// + + static { + System.loadLibrary("ppamltracer_java"); + } + + /** + * Wraps malloc to allocate a ppaml_phase_t. + * + * @return Same as malloc. + */ + private static native long mallocPhase(); + + /** + * Wraps ppaml_phase_init. + * + * @return -1 if converting name from a String to + * a char * failed; all other return codes are the same as + * ppaml_phase_init. + */ + private static native int ppaml_phase_init( + long tracer, + long phase, + final String reportNameBase); + + /** + * Wraps ppaml_phase_done. + * + * @return Same as ppaml_phase_done. + */ + private static native int ppaml_phase_done(long phase); + + /** + * Wraps free. + */ + private static native void freePhase(long phase); + + + ///// JNI adapter code ///// + + @Override + protected void allocateCPointer() { + this.cPointer = mallocPhase(); + } + + /** + * Installs data into the structure to make it ready for use. + * + *

Precondition: Initialization succeeded. + * + * @throws OutOfMemoryError converting name from a + * String to a char * failed. + * + * @throws OTFWriterPhaseDefinitionException defining the OTF phase failed. + */ + @Override + protected void initializeCPointer() { + assert this.cPointer != 0; + assert tracer != null; + assert name != null; + final int r = ppaml_phase_init(tracer.cPointer, this.cPointer, name); + switch (r) { + case 0: + break; + case -1: + throw new java.lang.OutOfMemoryError( + "failed to convert Java string to C string"); + case 1: + throw new OTFWriterPhaseDefinitionException(); + default: + throw new UnexpectedReturnValueError(r); + } + } + + @Override + protected void finalizeCPointer() { + assert this.cPointer != 0; + final int r = ppaml_phase_done(this.cPointer); + if (r != 0) { + throw new UnexpectedReturnValueError(r); + } + } + + @Override + protected void freeCPointer() { + assert this.cPointer != 0; + freePhase(this.cPointer); + } + + + ////////////////////////// Starting and stopping ////////////////////////// + + ///// JNI shared library ///// + + /** + * Wraps ppaml_phase_start. + * + * @return Same as ppaml_phase_start. + */ + private static native int ppaml_phase_start(long phase); + + /** + * Wraps ppaml_phase_stop. + * + * @return Same as ppaml_phase_stop. + */ + private static native int ppaml_phase_stop(long phase); + + + ///// JNI adapter code ///// + + /** + * Records the start of a Phase. + * + * @throws ClosedException the Phase has been closed. + * + * @throws ClockAcquisitionException getting the time failed. + * + * @throws OTFWriterEntryException recording the phase start failed. + */ + public void start() { + if (this.cPointer == 0) { + throw new ClosedException(); + } + final int r = ppaml_phase_start(this.cPointer); + switch (r) { + case 0: + break; + case 1: + throw new ClockAcquisitionException(); + case 2: + throw new OTFWriterEntryException(); + default: + throw new UnexpectedReturnValueError(r); + } + } + + /** + * Records the end of a Phase. + * + * @throws ClosedException the Phase has been closed. + * + * @throws ClockAcquisitionException getting the time failed. + * + * @throws OTFWriterExitException recording the phase stop failed. + */ + public void stop() { + if (this.cPointer == 0) { + throw new ClosedException(); + } + final int r = ppaml_phase_stop(this.cPointer); + switch (r) { + case 0: + break; + case 1: + throw new ClockAcquisitionException(); + case 2: + throw new OTFWriterExitException(); + default: + throw new UnexpectedReturnValueError(r); + } + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/TimingException.java b/bindings/java/src/java/com/galois/ppaml/tracer/TimingException.java new file mode 100644 index 0000000..da1afad --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/TimingException.java @@ -0,0 +1,34 @@ +/* TimingException -- signals a timing failure + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals a failure related to timing. + */ +public class TimingException extends java.lang.RuntimeException { + + static final long serialVersionUID = -1441057354704045107L; + + protected TimingException(String s) { + super(s); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/Tracer.java b/bindings/java/src/java/com/galois/ppaml/tracer/Tracer.java new file mode 100644 index 0000000..fe0a180 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/Tracer.java @@ -0,0 +1,163 @@ +/* Tracer -- wrapped ppaml_tracer_t + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * State class for ppamltracer. + * + *

ppamltracer is fundamentally a set of stateful operations; a + * Tracer object holds the state ppamltracer needs to operate + * properly. + */ +public final class Tracer extends CWrapper { + + /** + * Base file path for trace report output. + */ + private final String reportNameBase; + + /** + * Creates and initializes a Tracer. The trace report will be + * stored in Open Trace Format. + * + * @param reportNameBase all trace file paths will begin with this path. + */ + public Tracer(final String reportNameBase) { + this.reportNameBase = reportNameBase; + super.open(); + } + + /** + * Creates and initializes a {@link Phase} associated with this + * Tracer. + * + * @param name the name of the phase. + */ + public Phase createPhase(final String name) { + return new Phase(this, name); + } + + + ////////////////////////// Low-level life cycle ////////////////////////// + + ///// JNI shared library ///// + + static { + System.loadLibrary("ppamltracer_java"); + } + + /** + * Wraps malloc to allocate a ppaml_tracer_t. + * + * @return Same as malloc. + */ + private static native long mallocTracer(); + + /** + * Wraps ppaml_tracer_init. + * + * @return -1 if converting reportNameBase from a + * String to a char * failed; all other return + * codes are the same as ppaml_tracer_init. + */ + private static native int ppaml_tracer_init( + long tracer, + final String reportNameBase); + + /** + * Wraps ppaml_tracer_done. + * + * @return Same as ppaml_tracer_done. + */ + private static native int ppaml_tracer_done(long tracer); + + /** + * Wraps free. + */ + private static native void freeTracer(long tracer); + + + ///// JNI adapter code ///// + + @Override + protected void allocateCPointer() { + this.cPointer = mallocTracer(); + } + + /** + * Installs data into the structure to make it ready for use. + * + *

Precondition: Initialization succeeded. + * + * @throws OutOfMemoryError converting reportNameBase from a + * String to a char * failed. + * + * @throws OTFManagerInitializationException the Open Trace Format file + * manager could not be initialized. + * + * @throws OTFWriterInitializationException the Open Trace Format writer + * could not be initialized. + * + * @throws OTFWriterResolutionException setting the trace resolution failed. + * + * @throws OTFWriterProcessDefinitionException defining the main OTF process + * failed. + */ + @Override + protected void initializeCPointer() { + assert this.cPointer != 0; + assert reportNameBase != null; + final int r = ppaml_tracer_init(this.cPointer, reportNameBase); + switch (r) { + case 0: + break; + case -1: + throw new java.lang.OutOfMemoryError( + "failed to convert Java string to C string"); + case 1: + throw new OTFManagerInitializationException(); + case 2: + throw new OTFWriterInitializationException(); + case 3: + throw new OTFWriterResolutionException(); + case 4: + throw new OTFWriterProcessDefinitionException("main"); + default: + throw new UnexpectedReturnValueError(r); + } + } + + @Override + protected void finalizeCPointer() { + assert this.cPointer != 0; + final int r = ppaml_tracer_done(this.cPointer); + if (r != 0) { + throw new UnexpectedReturnValueError(r); + } + } + + @Override + protected void freeCPointer() { + assert this.cPointer != 0; + freeTracer(this.cPointer); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/UnexpectedReturnValueError.java b/bindings/java/src/java/com/galois/ppaml/tracer/UnexpectedReturnValueError.java new file mode 100644 index 0000000..e536073 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/UnexpectedReturnValueError.java @@ -0,0 +1,37 @@ +/* UnexpectedReturnValueError -- unexpected return value from C API + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +package com.galois.ppaml.tracer; + +/** + * Signals an unexpected return value from libppamltracer. If this error is + * thrown, it indicates a bug in ppamltracer, and you should report it to the + * developers. + */ +public class UnexpectedReturnValueError extends java.lang.Error { + + static final long serialVersionUID = -2476858873119724922L; + + protected UnexpectedReturnValueError(int r) { + super("unexpected return value " + r + "\n" + + "This is a bug in ppamltracer! Report it to the maintainers."); + } + +} diff --git a/bindings/java/src/java/com/galois/ppaml/tracer/package-info.java b/bindings/java/src/java/com/galois/ppaml/tracer/package-info.java new file mode 100644 index 0000000..f922274 --- /dev/null +++ b/bindings/java/src/java/com/galois/ppaml/tracer/package-info.java @@ -0,0 +1,80 @@ +/* package-info.java -- package information + * Copyright (C) 2014 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +/** + * A lightweight, portable tracing library for instrumenting generated code. + * + *

ppamltracer is a lightweight, portable tracing library designed for + * explicit instrumention of generated code. If you're writing a compiler and + * need hard data on your optimizer's efficacy, ppamltracer is the library for + * you. This Java package provides bindings to the libppamltracer C API. + * + *

This package's usage can be summed up in a few lines: + * + *

+ *   // Create report.
+ *   Tracer tracer = new Tracer("/tmp/my_report");
+ *
+ *   // Register phase 1 and do stuff.
+ *   Phase phase = tracer.createPhase("phase 1");
+ *   phase.start();
+ *   doStuff();
+ *   phase.stop();
+ *   phase.close();
+ *
+ *   // Register phase 2 and do different stuff.
+ *   phase = tracer.createPhase("phase 2");
+ *   // Other stuff
+ *   phase.start();
+ *   doOtherStuff();
+ *   phase.stop();
+ *   // Yet more stuff
+ *   phase.start();
+ *   doYetMoreStuff();
+ *   phase.stop();
+ *
+ *   // Clean up.
+ *   phase.close();
+ *   tracer.close();
+ * 
+ * + *

This creates a report with the total runtime of doStuff + * recorded as "phase 1" and the total runtime of doOtherStuff and + * doYetMoreStuff combined as "phase 2". + * + *

com.galois.ppaml.tracer.examples.Simple, included in the + * distribution, contains a more lengthy example. + * + *

ppamltracer writes trace logs in the + * Open Trace Format, a free and + * open standard developed by the Zentrum für Informationsdienste und + * Hochleistungsrechnen (Center for Information Services and High-Performance + * Computing) at the Technical University of Dresden. + * + *

We developed ppamltracer as part of DARPA's + * Probabilistic + * Programming for Advancing Machine Learning (PPAML) project. + * + * @author Galois, Inc. + * + * @version 0.1.0 + */ + +package com.galois.ppaml.tracer; diff --git a/bindings/python/.gitignore b/bindings/python/.gitignore new file mode 100644 index 0000000..4ac65cb --- /dev/null +++ b/bindings/python/.gitignore @@ -0,0 +1,8 @@ +# .gitignore for ppamltracer-python -*- conf -*- + +# Python +*.pyc + +# distutils +MANIFEST +dist/ diff --git a/bindings/python/MANIFEST.in b/bindings/python/MANIFEST.in new file mode 100644 index 0000000..6ec6c9b --- /dev/null +++ b/bindings/python/MANIFEST.in @@ -0,0 +1,21 @@ +# MANIFEST.in -- manifest template for source distributions +# Copyright (C) 2013 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +recursive-include examples *.py diff --git a/bindings/python/README b/bindings/python/README new file mode 100644 index 0000000..35a6bbd --- /dev/null +++ b/bindings/python/README @@ -0,0 +1,11 @@ + ppamltracer-python, v0.1.0 + +This package provides Python bindings to ppamltracer. They require Python 2.7. + +This package uses distutils for installation; you can run + + python setup.py install + +to install the package. + +For examples of use, see the examples directory. diff --git a/bindings/python/examples/simple.py b/bindings/python/examples/simple.py new file mode 100755 index 0000000..350c85a --- /dev/null +++ b/bindings/python/examples/simple.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# simple.py -- basic ppamltracer-python example +# This file is in the public domain. + +import os +import sys + +from ppamltracer import Tracer + +def main(): + # Disable buffering on stdout so we can see the numbers as they are printed. + sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) + # Start ppamltracer. + with Tracer("/tmp/simple_report") as tracer: + # Register the factorial phase. + with tracer.create_phase("fact") as phase: + # Print factorials. + print "Factorials:", + for i in range(21): + print fact(phase, i), + print + # Register the Fibonacci phase. + with tracer.create_phase("fib") as phase: + # Print Fibonacci numbers. + print "Fibonacci numbers: ", + for i in range(24): + print fib(phase, i), + print + +def fact(phase, n): + # Record that we're running inside the factorial phase. + with phase.running(): + # Compute the factorial. + if n == 0: + return 1 + else: + return n * fact(phase, n - 1) + +def fib(phase, n): + # Record that we're running inside the Fibonacci phase. + with phase.running(): + # Compute the nth Fibonacci number. + if n == 0 or n == 1: + return n + else: + return fib(phase, n - 1) + fib(phase, n - 2) + +if __name__ == '__main__': + main() diff --git a/bindings/python/ppamltracer.py b/bindings/python/ppamltracer.py new file mode 100644 index 0000000..dde85a3 --- /dev/null +++ b/bindings/python/ppamltracer.py @@ -0,0 +1,365 @@ +# ppamltracer -- Python bindings to ppamltracer +# Copyright (C) 2013 Galois, Inc. +# +# This library is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this library. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +"""A tracing library for explicit instrumentation of generated code. + +ppamltracer is a lightweight, portable tracing library designed for +explicit instrumention of generated code. If you're writing a compiler +and need hard data on your optimizer's efficacy, ppamltracer is the +library for you. ppamltracer-python provides a high-level Python API on +top of the libppamltracer C API. + +ppamltracer-python's usage can be summed up in a couple lines: + + from ppamltracer import Tracer + with Tracer("/tmp/my_report") as tracer: + with tracer.create_phase("phase 1") as phase: + with phase.running(): + do_stuff() + with tracer.create_phase("phase 2") as phase: + with phase.running(): + do_other_stuff() + with phase.running(): + do_yet_more_stuff() + +This creates a report with the total runtime of do_stuff recorded as +"phase 1", and the total runtime of do_other_stuff and do_yet_more_stuff +combined as "phase 2". + +The ppamltracer-python distribution also contains a more lengthy example +in the "examples" directory. + +ppamltracer writes trace logs in the Open Trace Format [1], a free and +open standard developed by the Zentrum fuer Informationsdienste und +Hochleistungsrechnen (Center for Information Services and +High-Performance Computing) at the Technical University of Dresden. + +We developed ppamltracer and ppamltracer-python as part of DARPA's +Probabilistic Programming for Advancing Machine Learning (PPAML) +project [2]. + +References: + [1] http://tu-dresden.de/zih/otf/ + [2] http://darpa.mil/Our_Work/I2O/Programs/Probabilistic_Programming_for_Advanced_Machine_Learning_(PPAML).aspx +""" +# TODO: Replace "ue" in "fuer" with Unicode u-with-diaresis (blocking on +# deployment of fix to Python #1065986, "Fix pydoc crashing on unicode +# strings"). + +import ctypes +import ctypes.util +import warnings + + +################################ Low-level API ################################ + +_lib = ctypes.cdll.LoadLibrary(ctypes.util.find_library("ppamltracer")) +"""ctypes binding to the ppamltracer C library.""" + +# The code in this section binds the C API using ctypes, translating +# return codes into the exception hierarchy defined below. Since these +# functions are not intended to be used externally, they're not +# documented using pydoc; see the ppamltracer C API documentation for +# information on their behavior. + +_sizeof_ppaml_tracer_t = \ + ctypes.c_size_t.in_dll(_lib, "ppaml_tracer_t_size").value + +_sizeof_ppaml_phase_t = ctypes.c_size_t.in_dll(_lib, "ppaml_phase_t_size").value + +def _ppaml_tracer_init(tracer, report_name_base): + result = _lib.ppaml_tracer_init(tracer, report_name_base) + if result == 0: + return None + elif result == 1: + raise OTFManagerInitializationError() + elif result == 2: + raise OTFWriterInitializationError() + elif result == 3: + raise OTFWriterResolutionError() + elif result == 4: + raise OTFWriterProcessDefinitionError("main") + else: + _warn_unexpected_return_code() + raise TracerError() + +def _ppaml_tracer_done(tracer): + result = _lib.ppaml_tracer_done(tracer) + if result == 0: + return None + elif result == 1: + raise OTFWriterCloseError() + else: + _warn_unexpected_return_code() + raise TracerError() + +def _ppaml_phase_init(tracer, phase, name): + result = _lib.ppaml_phase_init(tracer, phase, name) + if result == 0: + return None + elif result == 1: + raise OTFWriterPhaseDefinitionError() + else: + _warn_unexpected_return_code() + raise TracerError() + +def _ppaml_phase_start(phase): + result = _lib.ppaml_phase_start(phase) + if result == 0: + return None + elif result == 1: + raise ClockAcquisitionError() + elif result == 2: + raise OTFWriterEntryError() + else: + _warn_unexpected_return_code() + raise TracerError() + +def _ppaml_phase_stop(phase): + result = _lib.ppaml_phase_stop(phase) + if result == 0: + return None + elif result == 1: + raise ClockAcquisitionError() + elif result == 2: + raise OTFWriterExitError() + else: + _warn_unexpected_return_code() + raise TracerError() + +def _ppaml_phase_done(phase): + result = _lib.ppaml_phase_done(phase) + if result == 0: + return None + else: + _warn_unexpected_return_code() + raise TracerError() + + +############################# Resource-based API ############################## + +class Tracer(object): + """A tracer for programs, which records execution timing information. + + This class is designed to be used with Python's "with" statement-- e.g., + + with Tracer("/tmp/my_report") as tracer: + main(tracer) + + """ + + def __init__(self, report_name_base): + """Create a new tracer. + + The tracer will create an Open Trace Format report during program + execution. The multiple files of the report will all start with the + specified base name. + + """ + self._report_name_base = report_name_base + self._underlying = None + + def __enter__(self): + if self._underlying is None: + self._underlying = \ + ctypes.create_string_buffer(_sizeof_ppaml_tracer_t) + _ppaml_tracer_init(self._underlying, self._report_name_base) + return self + + def __exit__(self, *exception_info): + if self._underlying is not None: + _ppaml_tracer_done(self._underlying) + self._underlying = None + + def create_phase(self, name): + """Construct a Phase associated with this Tracer. + + This function is merely a convenience function; internally, it shells + out to the Phase constructor. + + """ + return Phase(self, name) + + +class Phase(object): + """A phase of computation traced by ppamltracer. + + This class is designed to be used with Python's "with" statement-- e.g., + + with Phase(tracer, "my phase") as phase: + with phase.running(): + do_stuff() + with phase.running(): + do_stuff_again() + + Note the double use of "with". The outer "with" manages the lifetime of + a Phase; the inner "with" actually starts and stops the phase timer. + + """ + + def __init__(self, tracer, name): + """Define a new phase tracked by a given tracer.""" + self._tracer = tracer + self._name = name + self._underlying = None + + def __enter__(self): + if self._underlying is None: + self._underlying = \ + ctypes.create_string_buffer(_sizeof_ppaml_phase_t) + _ppaml_phase_init( + self._tracer._underlying, + self._underlying, + self._name) + return self + + def __exit__(self, *exception_info): + if self._underlying is not None: + _ppaml_phase_done(self._underlying) + self._underlying = None + + def _start(self): + _ppaml_phase_start(self._underlying) + + def _stop(self): + _ppaml_phase_stop(self._underlying) + + def running(self): + """ Create a resource manager for the phase timer. + + This manager handles starting and stopping the phase, allowing you to + time operations by saying, e.g., + + with phase.running(): + do_stuff() + + """ + return _PhaseTimerManager(self) + + +class _PhaseTimerManager(object): + """Manage entry and exit from a Phase using the "with" statement.""" + + def __init__(self, phase): + self._phase = phase + + def __enter__(self): + self._phase._start() + + def __exit__(self, *exception_info): + self._phase._stop() + + +############################# Exception hierarchy ############################# + +class TracerError(Exception): + """A generic ppamltracer error.""" + pass + +class OTFError(TracerError): + """An error related to Open Trace Format input and output.""" + pass + +class OTFManagerError(OTFError): + """An error caused by the Open Trace Format manager.""" + pass + +class OTFManagerInitializationError(OTFManagerError): + """Failure to initialize the Open Trace Format manager.""" + + def __init__(self): + super.__init__( + self, + "could not initialize Open Trace Format file manager") + +class OTFWriterError(OTFError): + """An error caused by the Open Trace Format writer.""" + pass + +class OTFWriterInitializationError(OTFWriterError): + """Failure to initialize the Open Trace Format writer.""" + + def __init__(self): + super.__init__(self, "could not open Open Trace Format writer") + +class OTFWriterPhaseDefinitionError(OTFWriterError): + """Failure to define a phase. """ + + def __init__(self): + super.__init__(self, "could not define phase") + +class OTFWriterEntryError(OTFWriterError): + """Failure to record entry into a phase.""" + + def __init__(self): + super.__init__(self, "could not record phase start") + +class OTFWriterExitError(OTFWriterError): + """Failure to record exit from a phase.""" + + def __init__(self): + super.__init__(self, "could not record phase end") + +class OTFWriterCloseError(OTFWriterError): + """Failure to close the Open Trace Format writer.""" + + def __init__(self): + super.__init__(self, "could not close Open Trace Format writer") + +class OTFWriterResolutionError(OTFWriterError): + """Failure to set the tracer resolution.""" + + def __init__(self): + super.__init__(self, "could not set trace resolution") + +class OTFWriterProcessDefinitionError(OTFWriterError): + """Failure to define an Open Trace Format process.""" + + def __init__(self, process_name=None): + if process_name is None: + super.__init__(self, "could not define Open Trace Format process") + else: + super.__init__(self, + ("could not define Open Trace Format process \"" + + process_name + + "\"")) + +class TimingError(TracerError): + """An error related to system timers.""" + pass + +class ClockAcquisitionError(TimingError): + """A failure to get the current clock time.""" + + def __init__(self): + super.__init__(self, "could not get current time") + + +############################### Warnings ############################### + +class UnwrappedCErrorWarning(Warning): + """A warning indicating a failure to correctly wrap a C API.""" + pass + +def _warn_unexpected_return_code(): + warnings.warn(("Unexpected C return code\n" + + "*** This is a bug in ppamltracer-python! Report it to the maintainers."), + UnwrappedCErrorWarning, + 2) diff --git a/bindings/python/setup.py b/bindings/python/setup.py new file mode 100755 index 0000000..d8e9ec2 --- /dev/null +++ b/bindings/python/setup.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# setup.py -- distutils setup script for ppamltracer-python +# Copyright (C) 2013 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +from distutils.core import setup + +setup(name="ppamltracer-python", + version="0.1.0", + description="ppamltracer Python bindings", + author="Benjamin Barenblat", + author_email="bbarenblat@galois.com", + classifiers=["Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Topic :: Software Development :: Compilers"], + license="GPL", + py_modules=['ppamltracer']) diff --git a/bindings/racket/.gitignore b/bindings/racket/.gitignore new file mode 100644 index 0000000..9f3ac02 --- /dev/null +++ b/bindings/racket/.gitignore @@ -0,0 +1,16 @@ +# .gitignore for ppamltracer-racket -*- conf -*- + +# Bytecode +compiled/ +*.dep +*.zo + +# Scribble +manual/ +*.html +*.tex +*.pdf +racket.css +scribble.css +scribble-style.css +scribble-common.js diff --git a/bindings/racket/README b/bindings/racket/README new file mode 100644 index 0000000..b6c9d06 --- /dev/null +++ b/bindings/racket/README @@ -0,0 +1,11 @@ + ppamltracer-racket, v0.1.0 + +This package contains Racket bindings to ppamltracer. It requires Racket v5.2 +or later. + +Currently, this package is designed to be used as a collection; to install it, +you should type `raco link --name ppamltracer .'. (You may uninstall it with +`raco link --remove ppamltracer'.) + +To build the documentation, which contains a detailed example of use, you +should run `scribble ++xref-in setup/xref load-collections-xref manual.scrbl'. diff --git a/bindings/racket/main.rkt b/bindings/racket/main.rkt new file mode 100644 index 0000000..e4db143 --- /dev/null +++ b/bindings/racket/main.rkt @@ -0,0 +1,396 @@ +#lang racket/base +#| ppamltracer -- Racket bindings to ppamltracer +Copyright (C) 2013, 2014 Galois, Inc. + +This library is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this library. If not, see . + +To contact Galois, complete the Web form at +or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +Oregon, 97204-1622. |# + +(require (for-syntax racket/base + racket/syntax + (only-in racket/list drop-right) + (only-in racket/string string-join) + (only-in srfi/13 string-tokenize) + (only-in srfi/14 char-set char-set-complement) + srfi/26; hole notation + )) + +(require (rename-in ffi/unsafe [-> ~>]) + ffi/unsafe/define) +(require racket/contract) + +#| A shorthand for 'let-syntax-rule' with only one macro. For example, + + (let-syntax-rule (take-fst x y) x + (take-fst 'foo 'bar)) + +expands to + + 'foo +|# +(define-syntax-rule (let-syntax-rule (name . args) template body) + (let-syntax ([name (syntax-rules () [(_ . args) template])]) + body)) + +;; Convenience macro to instantiate an exception at the current location. +(define-syntax-rule (fail exception args ...) + (apply exception (list args ... (current-continuation-marks)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Low-level interface ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Load the library. +(define-ffi-definer define-ppamltracer (ffi-lib "libppamltracer")) + +#| We're going to model ppaml_tracer_t and ppaml_phase_t as abstract types by +having Racket treat them as buffers. These two symbols define how long those +buffers need to be. Ideally, they should be of type 'size_t', but Racket +doesn't have a size_t builtin, so we just use the largest C unsigned integer +type. |# +(define-ppamltracer ppaml_tracer_t_size _uint64) +(define-ppamltracer ppaml_phase_t_size _uint64) + +#| Define the struct types we're working with as buffer types. Instead of +mucking around with initializers and finalizers, which we can't seem to get +working correctly, we simply export an API which enforces proper resource +cleanup. |# +(define (make-buffer size) (make-ctype (_bytes o size) #f #f)) +(define _ppaml_tracer_t (make-buffer ppaml_tracer_t_size)) +(define _ppaml_phase_t (make-buffer ppaml_phase_t_size)) + +#| To help avoid passing structs of the wrong type in API internals, we'll +manipulate the structs as tagged pointers. |# +(define _tracer (_cpointer 'ppaml_tracer_t)) +(define _phase (_cpointer 'ppaml_phase_t)) + +;; Allocation functions for _tracer and _phase. +(define (malloc-tagged-pointer size-or-type tag) + (let ([result (malloc size-or-type 'atomic)]) + (cpointer-push-tag! result tag) + result)) +(define (malloc-_tracer) + (malloc-tagged-pointer _ppaml_tracer_t 'ppaml_tracer_t)) +(define (malloc-_phase) + (malloc-tagged-pointer _ppaml_phase_t 'ppaml_phase_t)) + +;; Import library functions. +(define-ppamltracer ppaml_tracer_init (_fun _tracer _path ~> _int)) +(define-ppamltracer ppaml_tracer_done (_fun _tracer ~> _int)) +(define-ppamltracer ppaml_phase_init (_fun _tracer _phase _string ~> _int)) +(define-ppamltracer ppaml_phase_done (_fun _phase ~> _int)) +(define-ppamltracer ppaml_phase_start (_fun _phase ~> _int)) +(define-ppamltracer ppaml_phase_stop (_fun _phase ~> _int)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Error handling ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +#| Convenience macro to create an exception. For example, + + (define-exception exn:fail:whatever) + +expands to + + (struct exn:fail:whatever exn:fail () + #:extra-constructor-name make-exn:fail:whatever + #:transparent) + +You can also call 'define-exception' with a message. Then, instead of creating +an extra binary make-prefixed constructor, 'define-exception' will create an +extra /unary/ make-prefixed constructor. All instances of the exception will +then have the same message. For example, + + (define-exception exn:fail:whatever "whatever happened!") + +expands to + + (struct exn:fail:whatever exn:fail () + #:transparent) + (define (make-exn:fail:whatever continuation-mark-set) + (exn:fail:whatever "whatever happened!" continuation-mark-set)) +|# +(define-syntax (define-exception stx) + (let ([#| Lifts a function which operates on data to operate on syntax + instead. |# + map-as-datum + (lambda (f stx) (datum->syntax stx (f (syntax->datum stx))))] + [#| Given an exception name (as a symbol), produces the conventional + super-exception. For instance, + + (take-base-exn 'exn:fail:whatever) + + expands to + + 'exn:fail + |# + take-base-exn + (compose1 string->symbol + (cut string-join <> ":") + (cut drop-right <> 1) + (cut string-tokenize <> (char-set-complement + (char-set #\:))) + symbol->string)]) + (syntax-case stx () + [(_ name) + (with-syntax ([base-name (map-as-datum take-base-exn #'name)] + [make-name (format-id stx "make-~a" #'name + #:source #'name)]) + #'(struct name base-name () + #:extra-constructor-name make-name + #:transparent))] + [(_ name message) + (with-syntax ([base-name (map-as-datum take-base-exn #'name)] + [make-name (format-id stx "make-~a" #'name + #:source #'name)]) + #'(begin + (struct name base-name () #:transparent) + (define (make-name continuation-mark-set) + (name message continuation-mark-set))))]))) + +#| Like define-exception, but does not create an extra make-prefixed +constructor at all. |# +(define-syntax (define-exception* stx) + (let ([map-as-datum + (lambda (f stx) (datum->syntax stx (f (syntax->datum stx))))] + [take-base-exn + (compose1 string->symbol + (cut string-join <> ":") + (cut drop-right <> 1) + (cut string-tokenize <> (char-set-complement + (char-set #\:))) + symbol->string)]) + (syntax-case stx () + [(_ name) + (with-syntax ([base-name (map-as-datum take-base-exn #'name)]) + #'(struct name base-name () #:transparent))]))) + +;;;;; Exception hierarchy ;;;;; + +(define-exception exn:fail:ppamltracer) + +(define-exception exn:fail:ppamltracer:otf) + +(define-exception exn:fail:ppamltracer:otf:manager) + +(define-exception exn:fail:ppamltracer:otf:manager:initialization + "could not initialize Open Trace Format file manager") + +(define-exception exn:fail:ppamltracer:otf:writer) + +(define-exception exn:fail:ppamltracer:otf:writer:initialization + "could not open Open Trace Format writer") + +(define-exception exn:fail:ppamltracer:otf:writer:phase-definition + "could not define phase") + +(define-exception exn:fail:ppamltracer:otf:writer:entry + "could not record phase start") + +(define-exception exn:fail:ppamltracer:otf:writer:exit + "could not record phase end") + +(define-exception exn:fail:ppamltracer:otf:writer:close + "could not close Open Trace Format writer") + +(define-exception exn:fail:ppamltracer:otf:writer:resolution + "could not set trace resolution") + +(define-exception* exn:fail:ppamltracer:otf:writer:process-definition) +(define (make-exn:fail:ppamltracer:otf:writer:process-definition + process-name + continuation-mark-set) + (exn:fail:ppamltracer:otf:writer:process-definition + (format "could not define Open Trace Format process ~v" process-name) + continuation-mark-set)) + +(define-exception exn:fail:ppamltracer:timing) + +(define-exception exn:fail:ppamltracer:timing:clock-acquisition + "could not get current time") + + +;;;;; Error-checked versions of library functions ;;;;; + +#| This macro makes checking C return codes trivial. Invocation is analogous +to that for the 'cond' form: + + (define some-function + (checked some-c-function + [0 'ok] + [1 (exn make-exn:fail:ppamltracer "bad data format")] + [-1 'ok])) + +This defines 'some-function' as a function taking an arbitrary number of +arguments. 'some-function', when invoked, will pass all its arguments to +'some-c-function'. If 'some-c-function' returns 0 or -1, then some-function +will evaluate successfully to whatever 'some-c-function' returned; if +'some-c-function' returns 1, though, 'some-function' will raise an +'exn:fail:ppamltracer' exception with the specified error message. + +If 'some-c-function' returns an unexpected value, 'some-function' will raise an +'exn:fail' noting the actual return value and declaring it a bug. |# +(define-syntax-rule (checked proc [expected consequence] ...) + (let-syntax-rule (cond-rhs result consequence-or-exception) + (if (eq? consequence-or-exception 'ok) + result + (raise consequence-or-exception)) + (lambda args + (let ([result (apply proc args)]) + (case result + [(expected) (cond-rhs result consequence)] + ... + [else (error (quote proc) + "unexpected return value ~v\n\ +This is a bug in ppamltracer! Report it to the maintainers." + result)]))))) + +(define ((as-void proc) . args) + (void (apply proc args))) + +(define ppaml-tracer-init + (as-void + (checked ppaml_tracer_init + [0 'ok] + [1 (fail make-exn:fail:ppamltracer:otf:manager:initialization)] + [2 (fail make-exn:fail:ppamltracer:otf:writer:initialization)] + [3 (fail make-exn:fail:ppamltracer:otf:writer:resolution)] + [4 (fail make-exn:fail:ppamltracer:otf:writer:process-definition + "main")]))) + +(define ppaml-tracer-done + (as-void + (checked ppaml_tracer_done + [0 'ok] + [1 (fail make-exn:fail:ppamltracer:otf:writer:close)]))) + +(define ppaml-phase-init + + (as-void + (checked ppaml_phase_init + [0 'ok] + [1 (fail make-exn:fail:ppamltracer:otf:writer:phase-definition)]))) + +(define ppaml-phase-start + (as-void + (checked ppaml_phase_start + [0 'ok] + [1 (fail make-exn:fail:ppamltracer:timing:clock-acquisition)] + [2 (fail make-exn:fail:ppamltracer:otf:writer:entry)]))) + +(define ppaml-phase-stop + (as-void + (checked ppaml_phase_stop + [0 'ok] + [1 (fail make-exn:fail:ppamltracer:timing:clock-acquisition)] + [2 (fail make-exn:fail:ppamltracer:otf:writer:exit)]))) + +(define ppaml-phase-done + (as-void + (checked ppaml_phase_done + [0 'ok]))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; High-level API ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +#| The functions in this section comprise a relatively safe API for this +library--i.e., using them will help avoid resource leaks. Of course, Racket +gives you plenty of rope to hang yourself--you could, for instance, call/cc +your way back into the middle of some traced function. |# + +;; Predicates on '_tracer' and '_phase', to emulate declaration as structs. +(define (cpointer-with-tag? obj tag) + (and (cpointer? obj) + (cpointer-has-tag? obj tag))) +(define (tracer? obj) (cpointer-with-tag? obj 'ppaml_tracer_t)) +(define (phase? obj) (cpointer-with-tag? obj 'ppaml_phase_t)) + +#| Execute a procedure in an exception-safe environment such that its resources +are properly released upon exit. With the exception handling stripped away, + + (managed-execution resource initialize initialize-args proc finalize) + +evaluates to + + (begin (apply initialize (cons resource initialize-args)) + (proc resource) + (finalize resource)) +|# +(define (managed-execution resource initialize initialize-args proc finalize) + (apply initialize (cons resource initialize-args)) + (let ([result + (with-handlers + ([exn? (lambda (exn) + #| An exception occurred during the execution of 'proc'. + Clean up and re-throw. |# + (with-handlers + ([exn? (lambda (exn) + #| An exception occurred during cleanup! + We're already responding to an existing + exception, though, so just ignore it. |# + (void))]) + (finalize resource)) + (raise exn))]) + (proc resource))]) + (finalize resource) + result)) + +(define (call-with-tracer report-name-base proc) + (managed-execution (malloc-_tracer) + ppaml-tracer-init + (list report-name-base) + proc + ppaml-tracer-done)) + +(define (call-with-phase tracer phase-name proc) + (managed-execution (malloc-_phase) + (lambda (phase tracer name) + ;; Reorder arguments to fit C API. + (ppaml-phase-init tracer phase name)) + (list tracer phase-name) + proc + ppaml-phase-done)) + +(define (call-with-phase-running phase proc) + (managed-execution phase + ppaml-phase-start + '() + (lambda (ignored) (proc)) + ppaml-phase-stop)) + + +;;;;; Macro versions ;;;;; + +(define-syntax-rule (let/tracer [tracer report-name-base] body ...) + (call-with-tracer report-name-base (lambda (tracer) body ...))) + +(define-syntax-rule (let/phase tracer [phase phase-name] body ...) + (call-with-phase tracer phase-name (lambda (phase) body ...))) + +(define-syntax-rule (with-phase-running phase body ...) + (call-with-phase-running phase (lambda () body ...))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Module interface ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide + (contract-out [tracer? (-> any/c boolean?)] + [phase? (-> any/c boolean?)] + [call-with-tracer (parametric->/c [A] + (-> path-string? (-> tracer? A) A))] + [call-with-phase (parametric->/c [A] + (-> tracer? string? (-> phase? A) A))] + [call-with-phase-running (parametric->/c [A] + (-> phase? (-> A) A))]) + let/tracer + let/phase + with-phase-running) diff --git a/bindings/racket/manual.scrbl b/bindings/racket/manual.scrbl new file mode 100644 index 0000000..f27731b --- /dev/null +++ b/bindings/racket/manual.scrbl @@ -0,0 +1,181 @@ +#lang scribble/manual +@;{ manual.scrbl -- Scribble documentation for ppamltracer-racket +Copyright (C) 2013, 2014 Galois, Inc. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +To contact Galois, complete the Web form at +or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +Oregon, 97204-1622. } + +@(require (for-label racket/base + racket/sequence)) +@(require (for-label ppamltracer)) + +@title{ppamltracer} + +ppamltracer is a lightweight, portable tracing library designed for explicit instrumention of generated code. +If you're writing a compiler and need hard data on your optimizer's efficacy, ppamltracer is the library for you. +This Racket library provides a high-level API on top of the libppamltracer C API. + +ppamltracer's usage can be summed up in a couple lines: + +@racketblock[ +(require ppamltracer) +(let/tracer [tracer "/tmp/my_report"] + (let/phase tracer [phase "phase 1"] + (with-phase-running phase + (do-stuff))) + (let/phase tracer [phase "phase 2"] + (with-phase-running phase + (do-other-stuff)) + (with-phase-running phase + (do-yet-more-stuff)))) +] + +This creates a report with the total runtime of @racket[do-stuff] recorded as "phase 1" and the total runtime of @racket[do-other-stuff] and @racket[do-yet-more-stuff] combined as "phase 2". + +@secref{getting-started} contains a more lengthy example. + +ppamltracer writes trace logs in the @hyperlink["http://tu-dresden.de/zih/otf/"]{Open Trace Format}, a free and open standard developed by the Zentrum für Informationsdienste und Hochleistungsrechnen (Center for Information Services and High-Performance Computing) at the Technical University of Dresden. + +We developed ppamltracer as part of DARPA's @hyperlink["http://darpa.mil/Our_Work/I2O/Programs/Probabilistic_Programming_for_Advanced_Machine_Learning_(PPAML).aspx"]{Probabilistic Programming for Advancing Machine Learning} (PPAML) project. + + +@section[#:tag "getting-started"]{Getting Started} + +This basic example demonstrates using ppamltracer to trace two functions -- a factorial function and a Fibonacci number generator. + +@#reader scribble/comment-reader (racketblock +;; simple.rkt -- basic ppamltracer example +;; This file is in the public domain. + +(require racket/sequence) +(require ppamltracer) + +(define (fact phase n) + ;; Record that we're running inside the factorial phase. + (with-phase-running phase + ;; Compute the factorial. + (if (= n 0) + 1 + (* n (fact phase (- n 1)))))) + +(define (fib phase n) + ;; Record that we're running inside the Fibonacci phase. + (with-phase-running phase + ;; Compute the nth Fibonacci number. + (case n + [(0 1) n] + [else (+ (fib phase (- n 1)) (fib phase (- n 2)))]))) + +;; Start ppamltracer. +(let/tracer [tracer "/tmp/simple_report"] + ;; Register the factorial phase. + (let/phase tracer [phase "fact"] + ;; Print factorials. + (printf "Factorials: ") + (sequence-for-each (lambda (n) (printf "~a " (fact phase n))) + (in-range 40)) + (printf "\n")) + ;; Register the Fibonacci phase. + (let/phase tracer [phase "fib"] + ;; Print Fibonacci numbers. + (printf "Fibonacci numbers: ") + (sequence-for-each (lambda (n) (printf "~a " (fib phase n))) + (in-range 16)) + (printf "\n"))) +) + +@section{API in Depth} + +@defmodule[ppamltracer] + +@subsection{Tracers} + +ppamltracer is fundamentally a set of stateful operations; the @racket[tracer] data type holds the state ppamltracer needs to operate properly. + +@defproc[(tracer? [obj any/c]) + boolean?]{ + Evaluates to @racket[#t] if and only if @racket[obj] is a @racket[tracer]. +} + +@defproc[(call-with-tracer [report-name-base path-string?] + [proc (-> tracer? A)]) + A]{ + Creates a new @racket[tracer]. + The @racket[tracer] will save trace reports in Open Trace Format; all trace file paths will begin with @racket[report-name-base]. +} + +@defform[#:id let/tracer + #:literals (tracer) + (let/tracer [tracer report-name-base] body ...) + #:contracts ([report-name-base path-string?])]{ + Macro version of @racket[call-with-tracer]. + Equivalent to + + @racketblock[ + (call-with-tracer report-name-base (lambda (tracer) body ...)) + ] +} + +@subsection{Phases} + +A @racket[phase] represents a phase of execution about which the user wishes to gather timing statistics. + +@defproc[(phase? [obj any/c]) + boolean?]{ + Evaluates to @racket[#t] if and only if @racket[obj] is a @racket[phase]. +} + +@defproc[(call-with-phase [tracer tracer?] + [phase-name string?] + [proc (-> phase? A)]) + A]{ + Creates a new @racket[phase] attached to @racket[tracer] and named @racket[phase-name]. +} + +@defform[#:id let/phase + #:literals (phase) + (let/phase tracer [phase name] body ...) + #:contracts ([tracer tracer?] + [name string?])]{ + Macro version of @racket[call-with-phase]. + Equivalent to + + @racketblock[ + (call-with-phase tracer name (lambda (phase) body ...)) + ] +} + +@subsection{Tracing} + +@defproc[(call-with-phase-running [phase phase?] + [proc (-> A)]) + A]{ + Runs @racket[proc], associating information about its timing and execution with @racket[phase] in the trace report. + Should @racket[proc] throw an exception, @racket[call-with-phase-running] will stop tracing before propagating the exception up the stack. +} + +@defform[#:id with-phase-running + #:literals (phase) + (with-phase-running phase body ...) + #:contracts ([phase phase?])]{ + Macro version of @racket[call-with-phase-running]. + Equivalent to + + @racketblock[ + (call-with-phase-running phase (lambda () body ...)) + ] +} + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..a5b80c6 --- /dev/null +++ b/configure.ac @@ -0,0 +1,64 @@ +# configure.ac -- autoconf script for ppamltracer +# Copyright (C) 2013 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +# Fire up Autoconf. +AC_PREREQ([2.69]) +AC_INIT([ppamltracer], [0.1.0], [bbarenblat@galois.com]) + +# Fire up Automake. Use ustar format because we actually have file names +# longer than 99 characters (hooray, Java). +AM_INIT_AUTOMAKE([-Wall -Wno-gnu -Werror foreign tar-ustar no-dist-gzip \ + dist-bzip2]) +AC_CONFIG_MACRO_DIR([m4]) + +# Build quietly. +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +# Build a C library. +AC_CONFIG_SRCDIR([config.h.in]) +AC_CONFIG_HEADERS([config.h]) +AC_PROG_CC +AC_PROG_CC_C99 +# Automake 1.12 seems to require this, but automake 1.11 doesn't recognize it. +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +LT_INIT + +# Dependencies +AC_CHECK_HEADERS([unistd.h]) +AC_CHECK_TYPE([clockid_t]) +GALOIS_PPAML_LIB_OPENTRACE( + [], + [AC_MSG_ERROR([both OTF development libraries and the 'otfconfig' program are required. You can install them from .])]) + +# Documentation +DX_HTML_FEATURE(ON) +DX_PDF_FEATURE(OFF) +DX_PS_FEATURE(OFF) +DX_INIT_DOXYGEN([ppamltracer], [Doxyfile], [doc]) + +# Generate Makefiles and pkg-config file. +AC_CONFIG_FILES([ + Makefile + src/Makefile + include/Makefile]) +AC_CONFIG_FILES([ppamltracer.pc]) + +# All done. +AC_OUTPUT diff --git a/examples/simple.c b/examples/simple.c new file mode 100644 index 0000000..614205d --- /dev/null +++ b/examples/simple.c @@ -0,0 +1,92 @@ +/* simple.c -- basic ppamltracer example + * This file is in the public domain. + * + * Compile this with + * cc -std=c99 -lppamltracer -o simple simple.c + */ + +#include +#include + +#include + +// ppamltracer state +ppaml_tracer_t tracer; +ppaml_phase_t phase_fact; +ppaml_phase_t phase_fib; + + +// Prototypes +unsigned long long fact(const unsigned short); +unsigned long fib(const unsigned short); + + +int main(int argc, char *argv[]) +{ + /* Disable buffering on stdout so we can see the numbers as they are + * printed. */ + setvbuf(stdout, NULL, _IONBF, 0); + + // Start ppamltracer. + ppaml_tracer_init(&tracer, "/tmp/simple_report"); + + // Register the phases. + ppaml_phase_init(&tracer, &phase_fact, "fact"); + ppaml_phase_init(&tracer, &phase_fib, "fib"); + + // Print factorials. + printf("Factorials: "); + for (unsigned short i = 0; i < 21; i++) { + printf("%lld ", fact(i)); + } + printf("\n"); + + // Print Fibonacci numbers. + printf("Fibonacci numbers: "); + for (unsigned short i = 0; i < 28; i++) { + printf("%ld ", fib(i)); + } + printf("\n"); + + // Finalize ppamltracer and exit. + ppaml_phase_done(&phase_fact); + ppaml_phase_done(&phase_fib); + ppaml_tracer_done(&tracer); + return 0; +} + +unsigned long long fact(const unsigned short n) +{ + // Record that we have entered the 'fact' phase. + ppaml_phase_start(&phase_fact); + + // Compute the factorial. + unsigned long long result; + if (n == 0) { + result = 1; + } else { + result = (unsigned long long)n * fact(n - 1); + } + + // Record that we're exiting the 'fact' phase. + ppaml_phase_stop(&phase_fact); + return result; +} + +unsigned long fib(const unsigned short n) +{ + // Record that we have entered the 'fib' phase. + ppaml_phase_start(&phase_fib); + + // Compute the nth Fibonancci number. + unsigned long result; + if (n == 0 || n == 1) { + result = 1; + } else { + result = fib(n - 1) + fib(n - 2); + } + + // Record that we're exiting the 'fact' phase. + ppaml_phase_stop(&phase_fib); + return result; +} diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..5ef2a54 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,23 @@ +# Makefile.am -- automake script for ppamltracer +# Copyright (C) 2013 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +nobase_include_HEADERS = \ + ppaml/tracer.h \ + ppaml/tracer/internal.h diff --git a/include/ppaml/tracer.h b/include/ppaml/tracer.h new file mode 100644 index 0000000..df9891a --- /dev/null +++ b/include/ppaml/tracer.h @@ -0,0 +1,166 @@ +/* ppaml/tracer.h -- PPAML timing instrumentation interface + * Copyright (C) 2013 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +/** + * @file tracer.h + * Library interface. + * + * This file defines the top-level interface for ppamltracer. + * + * Since all the functions in this file operate on @ref ppaml_tracer_t and @ref + * ppaml_phase_t structs, their documentation has been moved to the relevant + * data structure pages. + */ + +#ifndef PPAML_TRACER_H +#define PPAML_TRACER_H + +#include "tracer/internal.h" // for ppaml_tracer_t and ppaml_phase_t + +/** + * @name Resource management + * + * @{ + */ + +/** + * Initializes a ppaml_tracer_t. + * + * @relates ppaml_tracer_t + * + * The trace report will be stored in Open Trace Format; all trace file paths + * will begin with @p report_name_base. + * + * @param[out] tracer pointer to the tracer to be initialized + * @param[in] report_name_base base file name for the report files + * + * @pre @p tracer is nonnull. + * @pre @p *tracer is uninitialized. + * + * @return 0 upon success + * @return 1 if the Open Trace Format file manager could not be initialized + * @return 2 if the Open Trace Format writer could not be initialized + * @return 3 if setting the trace resolution failed + * @return 4 if defining the main OTF process failed + * + * @post If the function return successfully, @p *tracer is initialized. + */ +int ppaml_tracer_init(ppaml_tracer_t *tracer, const char report_name_base[]); + +/** + * Finalizes a ppaml_tracer_t. + * + * @relates ppaml_tracer_t + * + * @param[out] tracer pointer to the tracer to be finalized + * + * @pre @p tracer is nonnull. + * @pre @p *tracer is initialized. + * + * @return 0 upon success + * @return 1 if the Open Trace Format writer could not be closed + * + * @post If the function return successfully, @p *tracer is uninitialized. + */ +int ppaml_tracer_done(ppaml_tracer_t *tracer); + +/** + * Initializes a ppaml_phase_t. + * + * @relates ppaml_phase_t + * + * @param[in] tracer pointer to the tracer which records this phase + * @param[out] phase pointer to the phase to be initialized + * @param[in] name name of the phase + * + * @pre @p tracer is nonnull. + * @pre @p *tracer is initialized. + * @pre @p phase is nonnull. + * @pre @p *phase is uninitialized. + * + * @return 0 upon success + * @return 1 if defining the phase failed + * + * @post If the function return successfully, @p *phase is initialized. + */ +int ppaml_phase_init( + ppaml_tracer_t *tracer, + ppaml_phase_t *phase, + const char name[]); + +/** + * Finalizes a ppaml_phase_t. + * + * @relates ppaml_phase_t + * + * @param[out] phase pointer to the phase to be finalized + * + * @pre @p phase is nonnull. + * @pre @p *phase is initialized. + * + * @return 0 upon success; a nonzero return indicates failure. + * + * @post If the function return successfully, @p *phase is uninitialized. + */ +int ppaml_phase_done(ppaml_phase_t *phase); + +/// @} + +/** + * @name Timing + * + * @{ + */ + +/** + * Records the start of a phase. + * + * @relates ppaml_phase_t + * + * @param[in] phase pointer to the phase + * + * @pre @p phase is nonnull. + * @pre @p *phase is initialized. + * + * @return 0 upon success + * @return 1 if getting the time failed + * @return 2 if recording the phase start failed + */ +int ppaml_phase_start(ppaml_phase_t *phase); + +/** + * Records the end of a phase. + * + * @relates ppaml_phase_t + * + * @param[in] phase pointer to the phase + * + * @pre @p phase is nonnull. + * @pre @p *phase is initialized. + * + * @return 0 upon success + * @return 1 if getting the time failed + * @return 2 if recording the phase stop failed + */ +int ppaml_phase_stop(ppaml_phase_t *phase); + +/// @} + +#endif diff --git a/include/ppaml/tracer/internal.h b/include/ppaml/tracer/internal.h new file mode 100644 index 0000000..217d7ad --- /dev/null +++ b/include/ppaml/tracer/internal.h @@ -0,0 +1,111 @@ +/* ppaml/tracer/internal.h -- definitions of abstract types + * Copyright (C) 2013 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +/** + * @file internal.h + * Definitions of abstract types. + * + * @warning Do not include this file directly. Instead, include @ref + * ppaml/tracer.h. + * + * This file contains the implementations of abstract types which, for + * efficiency reasons, are exposed to the user. + */ + +/* THIS FILE SHOULD NOT BE #INCLUDED DIRECTLY. Instead, #include + * . */ + +#ifndef PPAML_TRACER_INTERNAL_H +#define PPAML_TRACER_INTERNAL_H + +#include +#include + +#include + +/** + * @struct ppaml_tracer_t ppaml/tracer/internal.h ppaml/tracer.h + * Tracer state bundle. + * + * ppamltracer is fundamentally a set of stateful operations; this struct holds + * the state ppamltracer needs to operate properly. + * + * To increase flexibility, ppamltracer users may allocate instances of this + * struct on the stack or heap. + * + * Newly-allocated instances of ppaml_tracer_t are invalid and must be + * initialized using @ref ppaml_tracer_init before they can be used. Once a + * ppaml_tracer_t is no longer required, it must be finalized using @ref + * ppaml_tracer_done. + */ +typedef struct { + /// @private The underlying Open Trace Format file manager. + OTF_FileManager *manager; + /// @private The underlying Open Trace Format output subsystem. + OTF_Writer *writer; +} ppaml_tracer_t; + +/** + * `sizeof(`@ref ppaml_tracer_t`)`. + * + * @warning This constant is intended for interfacing with other languages. It + * is not part of the stable ppamltracer C API. Use + * `sizeof(`@ref ppaml_tracer_t`)` instead. + */ +const size_t ppaml_tracer_t_size; + +/** + * @struct ppaml_phase_t ppaml/tracer/internal.h ppaml/tracer.h + * A phase of execution to trace. + * + * A ppaml_phase_t represents a phase of execution about which the user wishes + * to gather timing statistics. + * + * To increase flexibility, ppamltracer users may allocate instances of this + * struct on the stack or heap. + * + * Newly-allocated instances of ppaml_phase_t are invalid and must be + * initialized using @ref ppaml_phase_init before they can be used. Once a + * ppaml_phase_t is no longer required, it must be finalized using @ref + * ppaml_phase_done. + */ +typedef struct { + /// @private The associated ppaml_tracer_t. + ppaml_tracer_t *tracer; + /** + * @private + * The Open Trace Format identifier for this phase. + * + * Phases are isomorphic to functions as understood by the Open Trace + * Format libraries; thus, this is a "function identifier". + */ + uint32_t otf_function_id; +} ppaml_phase_t; + +/** + * `sizeof(`@ref ppaml_phase_t`)`. + * + * @warning This constant is intended for interfacing with other languages. It + * is not part of the stable ppamltracer C API. Use + * `sizeof(`@ref ppaml_phase_t`)` instead. + */ +const size_t ppaml_phase_t_size; + +#endif diff --git a/m4/ax_prog_doxygen.m4 b/m4/ax_prog_doxygen.m4 new file mode 100644 index 0000000..44b22b0 --- /dev/null +++ b/m4/ax_prog_doxygen.m4 @@ -0,0 +1,532 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html +# =========================================================================== +# +# SYNOPSIS +# +# DX_INIT_DOXYGEN(PROJECT-NAME, DOXYFILE-PATH, [OUTPUT-DIR]) +# DX_DOXYGEN_FEATURE(ON|OFF) +# DX_DOT_FEATURE(ON|OFF) +# DX_HTML_FEATURE(ON|OFF) +# DX_CHM_FEATURE(ON|OFF) +# DX_CHI_FEATURE(ON|OFF) +# DX_MAN_FEATURE(ON|OFF) +# DX_RTF_FEATURE(ON|OFF) +# DX_XML_FEATURE(ON|OFF) +# DX_PDF_FEATURE(ON|OFF) +# DX_PS_FEATURE(ON|OFF) +# +# DESCRIPTION +# +# The DX_*_FEATURE macros control the default setting for the given +# Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for +# generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML +# help (for MS users), 'CHI' for generating a seperate .chi file by the +# .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate +# output formats. The environment variable DOXYGEN_PAPER_SIZE may be +# specified to override the default 'a4wide' paper size. +# +# By default, HTML, PDF and PS documentation is generated as this seems to +# be the most popular and portable combination. MAN pages created by +# Doxygen are usually problematic, though by picking an appropriate subset +# and doing some massaging they might be better than nothing. CHM and RTF +# are specific for MS (note that you can't generate both HTML and CHM at +# the same time). The XML is rather useless unless you apply specialized +# post-processing to it. +# +# The macros mainly control the default state of the feature. The use can +# override the default by specifying --enable or --disable. The macros +# ensure that contradictory flags are not given (e.g., +# --enable-doxygen-html and --enable-doxygen-chm, +# --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each +# feature will be automatically disabled (with a warning) if the required +# programs are missing. +# +# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN +# with the following parameters: a one-word name for the project for use +# as a filename base etc., an optional configuration file name (the +# default is 'Doxyfile', the same as Doxygen's default), and an optional +# output directory name (the default is 'doxygen-doc'). +# +# Automake Support +# +# The following is a template aminclude.am file for use with Automake. +# Make targets and variables values are controlled by the various +# DX_COND_* conditionals set by autoconf. +# +# The provided targets are: +# +# doxygen-doc: Generate all doxygen documentation. +# +# doxygen-run: Run doxygen, which will generate some of the +# documentation (HTML, CHM, CHI, MAN, RTF, XML) +# but will not do the post processing required +# for the rest of it (PS, PDF, and some MAN). +# +# doxygen-man: Rename some doxygen generated man pages. +# +# doxygen-ps: Generate doxygen PostScript documentation. +# +# doxygen-pdf: Generate doxygen PDF documentation. +# +# Note that by default these are not integrated into the automake targets. +# If doxygen is used to generate man pages, you can achieve this +# integration by setting man3_MANS to the list of man pages generated and +# then adding the dependency: +# +# $(man3_MANS): doxygen-doc +# +# This will cause make to run doxygen and generate all the documentation. +# +# The following variable is intended for use in Makefile.am: +# +# DX_CLEANFILES = everything to clean. +# +# Then add this variable to MOSTLYCLEANFILES. +# +# ----- begin aminclude.am ------------------------------------- +# +# ## --------------------------------- ## +# ## Format-independent Doxygen rules. ## +# ## --------------------------------- ## +# +# if DX_COND_doc +# +# ## ------------------------------- ## +# ## Rules specific for HTML output. ## +# ## ------------------------------- ## +# +# if DX_COND_html +# +# DX_CLEAN_HTML = @DX_DOCDIR@/html +# +# endif DX_COND_html +# +# ## ------------------------------ ## +# ## Rules specific for CHM output. ## +# ## ------------------------------ ## +# +# if DX_COND_chm +# +# DX_CLEAN_CHM = @DX_DOCDIR@/chm +# +# if DX_COND_chi +# +# DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi +# +# endif DX_COND_chi +# +# endif DX_COND_chm +# +# ## ------------------------------ ## +# ## Rules specific for MAN output. ## +# ## ------------------------------ ## +# +# if DX_COND_man +# +# DX_CLEAN_MAN = @DX_DOCDIR@/man +# +# endif DX_COND_man +# +# ## ------------------------------ ## +# ## Rules specific for RTF output. ## +# ## ------------------------------ ## +# +# if DX_COND_rtf +# +# DX_CLEAN_RTF = @DX_DOCDIR@/rtf +# +# endif DX_COND_rtf +# +# ## ------------------------------ ## +# ## Rules specific for XML output. ## +# ## ------------------------------ ## +# +# if DX_COND_xml +# +# DX_CLEAN_XML = @DX_DOCDIR@/xml +# +# endif DX_COND_xml +# +# ## ----------------------------- ## +# ## Rules specific for PS output. ## +# ## ----------------------------- ## +# +# if DX_COND_ps +# +# DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps +# +# DX_PS_GOAL = doxygen-ps +# +# doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps +# +# @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag +# cd @DX_DOCDIR@/latex; \ +# rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ +# $(DX_LATEX) refman.tex; \ +# $(MAKEINDEX_PATH) refman.idx; \ +# $(DX_LATEX) refman.tex; \ +# countdown=5; \ +# while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ +# refman.log > /dev/null 2>&1 \ +# && test $$countdown -gt 0; do \ +# $(DX_LATEX) refman.tex; \ +# countdown=`expr $$countdown - 1`; \ +# done; \ +# $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi +# +# endif DX_COND_ps +# +# ## ------------------------------ ## +# ## Rules specific for PDF output. ## +# ## ------------------------------ ## +# +# if DX_COND_pdf +# +# DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf +# +# DX_PDF_GOAL = doxygen-pdf +# +# doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf +# +# @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag +# cd @DX_DOCDIR@/latex; \ +# rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ +# $(DX_PDFLATEX) refman.tex; \ +# $(DX_MAKEINDEX) refman.idx; \ +# $(DX_PDFLATEX) refman.tex; \ +# countdown=5; \ +# while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ +# refman.log > /dev/null 2>&1 \ +# && test $$countdown -gt 0; do \ +# $(DX_PDFLATEX) refman.tex; \ +# countdown=`expr $$countdown - 1`; \ +# done; \ +# mv refman.pdf ../@PACKAGE@.pdf +# +# endif DX_COND_pdf +# +# ## ------------------------------------------------- ## +# ## Rules specific for LaTeX (shared for PS and PDF). ## +# ## ------------------------------------------------- ## +# +# if DX_COND_latex +# +# DX_CLEAN_LATEX = @DX_DOCDIR@/latex +# +# endif DX_COND_latex +# +# .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) +# +# .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) +# +# doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag +# +# doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) +# +# @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS) +# rm -rf @DX_DOCDIR@ +# $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) +# +# DX_CLEANFILES = \ +# @DX_DOCDIR@/@PACKAGE@.tag \ +# -r \ +# $(DX_CLEAN_HTML) \ +# $(DX_CLEAN_CHM) \ +# $(DX_CLEAN_CHI) \ +# $(DX_CLEAN_MAN) \ +# $(DX_CLEAN_RTF) \ +# $(DX_CLEAN_XML) \ +# $(DX_CLEAN_PS) \ +# $(DX_CLEAN_PDF) \ +# $(DX_CLEAN_LATEX) +# +# endif DX_COND_doc +# +# ----- end aminclude.am --------------------------------------- +# +# LICENSE +# +# Copyright (c) 2009 Oren Ben-Kiki +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 12 + +## ----------## +## Defaults. ## +## ----------## + +DX_ENV="" +AC_DEFUN([DX_FEATURE_doc], ON) +AC_DEFUN([DX_FEATURE_dot], OFF) +AC_DEFUN([DX_FEATURE_man], OFF) +AC_DEFUN([DX_FEATURE_html], ON) +AC_DEFUN([DX_FEATURE_chm], OFF) +AC_DEFUN([DX_FEATURE_chi], OFF) +AC_DEFUN([DX_FEATURE_rtf], OFF) +AC_DEFUN([DX_FEATURE_xml], OFF) +AC_DEFUN([DX_FEATURE_pdf], ON) +AC_DEFUN([DX_FEATURE_ps], ON) + +## --------------- ## +## Private macros. ## +## --------------- ## + +# DX_ENV_APPEND(VARIABLE, VALUE) +# ------------------------------ +# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen. +AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])]) + +# DX_DIRNAME_EXPR +# --------------- +# Expand into a shell expression prints the directory part of a path. +AC_DEFUN([DX_DIRNAME_EXPR], + [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']]) + +# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF) +# ------------------------------------- +# Expands according to the M4 (static) status of the feature. +AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])]) + +# DX_REQUIRE_PROG(VARIABLE, PROGRAM) +# ---------------------------------- +# Require the specified program to be found for the DX_CURRENT_FEATURE to work. +AC_DEFUN([DX_REQUIRE_PROG], [ +AC_PATH_TOOL([$1], [$2]) +if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then + AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION]) + AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0) +fi +]) + +# DX_TEST_FEATURE(FEATURE) +# ------------------------ +# Expand to a shell expression testing whether the feature is active. +AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1]) + +# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE) +# ------------------------------------------------- +# Verify that a required features has the right state before trying to turn on +# the DX_CURRENT_FEATURE. +AC_DEFUN([DX_CHECK_DEPEND], [ +test "$DX_FLAG_$1" = "$2" \ +|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1, + requires, contradicts) doxygen-DX_CURRENT_FEATURE]) +]) + +# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE) +# ---------------------------------------------------------- +# Turn off the DX_CURRENT_FEATURE if the required feature is off. +AC_DEFUN([DX_CLEAR_DEPEND], [ +test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0) +]) + +# DX_FEATURE_ARG(FEATURE, DESCRIPTION, +# CHECK_DEPEND, CLEAR_DEPEND, +# REQUIRE, DO-IF-ON, DO-IF-OFF) +# -------------------------------------------- +# Parse the command-line option controlling a feature. CHECK_DEPEND is called +# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND), +# otherwise CLEAR_DEPEND is called to turn off the default state if a required +# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional +# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and +# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature. +AC_DEFUN([DX_ARG_ABLE], [ + AC_DEFUN([DX_CURRENT_FEATURE], [$1]) + AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2]) + AC_ARG_ENABLE(doxygen-$1, + [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1], + [--enable-doxygen-$1]), + DX_IF_FEATURE([$1], [don't $2], [$2]))], + [ +case "$enableval" in +#( +y|Y|yes|Yes|YES) + AC_SUBST([DX_FLAG_$1], 1) + $3 +;; #( +n|N|no|No|NO) + AC_SUBST([DX_FLAG_$1], 0) +;; #( +*) + AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1]) +;; +esac +], [ +AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)]) +$4 +]) +if DX_TEST_FEATURE([$1]); then + $5 + : +fi +AM_CONDITIONAL(DX_COND_$1, DX_TEST_FEATURE([$1])) +if DX_TEST_FEATURE([$1]); then + $6 + : +else + $7 + : +fi +]) + +## -------------- ## +## Public macros. ## +## -------------- ## + +# DX_XXX_FEATURE(DEFAULT_STATE) +# ----------------------------- +AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])]) +AC_DEFUN([DX_DOT_FEATURE], [AC_DEFUN([DX_FEATURE_dot], [$1])]) +AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])]) +AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])]) +AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])]) +AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])]) +AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])]) +AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) +AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) +AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])]) +AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])]) + +# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR]) +# --------------------------------------------------------- +# PROJECT also serves as the base name for the documentation files. +# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc". +AC_DEFUN([DX_INIT_DOXYGEN], [ + +# Files: +AC_SUBST([DX_PROJECT], [$1]) +AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])]) +AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])]) + +# Environment variables used inside doxygen.cfg: +DX_ENV_APPEND(SRCDIR, $srcdir) +DX_ENV_APPEND(PROJECT, $DX_PROJECT) +DX_ENV_APPEND(DOCDIR, $DX_DOCDIR) +DX_ENV_APPEND(VERSION, $PACKAGE_VERSION) + +# Doxygen itself: +DX_ARG_ABLE(doc, [generate any doxygen documentation], + [], + [], + [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen) + DX_REQUIRE_PROG([DX_PERL], perl)], + [DX_ENV_APPEND(PERL_PATH, $DX_PERL)]) + +# Dot for graphics: +DX_ARG_ABLE(dot, [generate graphics for doxygen documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_DOT], dot)], + [DX_ENV_APPEND(HAVE_DOT, YES) + DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])], + [DX_ENV_APPEND(HAVE_DOT, NO)]) + +# Man pages generation: +DX_ARG_ABLE(man, [generate doxygen manual pages], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_MAN, YES)], + [DX_ENV_APPEND(GENERATE_MAN, NO)]) + +# RTF file generation: +DX_ARG_ABLE(rtf, [generate doxygen RTF documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_RTF, YES)], + [DX_ENV_APPEND(GENERATE_RTF, NO)]) + +# XML file generation: +DX_ARG_ABLE(xml, [generate doxygen XML documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_XML, YES)], + [DX_ENV_APPEND(GENERATE_XML, NO)]) + +# (Compressed) HTML help generation: +DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_HHC], hhc)], + [DX_ENV_APPEND(HHC_PATH, $DX_HHC) + DX_ENV_APPEND(GENERATE_HTML, YES) + DX_ENV_APPEND(GENERATE_HTMLHELP, YES)], + [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)]) + +# Seperate CHI file generation. +DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file], + [DX_CHECK_DEPEND(chm, 1)], + [DX_CLEAR_DEPEND(chm, 1)], + [], + [DX_ENV_APPEND(GENERATE_CHI, YES)], + [DX_ENV_APPEND(GENERATE_CHI, NO)]) + +# Plain HTML pages generation: +DX_ARG_ABLE(html, [generate doxygen plain HTML documentation], + [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)], + [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)], + [], + [DX_ENV_APPEND(GENERATE_HTML, YES)], + [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)]) + +# PostScript file generation: +DX_ARG_ABLE(ps, [generate doxygen PostScript documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_LATEX], latex) + DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) + DX_REQUIRE_PROG([DX_DVIPS], dvips) + DX_REQUIRE_PROG([DX_EGREP], egrep)]) + +# PDF file generation: +DX_ARG_ABLE(pdf, [generate doxygen PDF documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex) + DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) + DX_REQUIRE_PROG([DX_EGREP], egrep)]) + +# LaTeX generation for PS and/or PDF: +AM_CONDITIONAL(DX_COND_latex, DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf)) +if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then + DX_ENV_APPEND(GENERATE_LATEX, YES) +else + DX_ENV_APPEND(GENERATE_LATEX, NO) +fi + +# Paper size for PS and/or PDF: +AC_ARG_VAR(DOXYGEN_PAPER_SIZE, + [a4wide (default), a4, letter, legal or executive]) +case "$DOXYGEN_PAPER_SIZE" in +#( +"") + AC_SUBST(DOXYGEN_PAPER_SIZE, "") +;; #( +a4wide|a4|letter|legal|executive) + DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE) +;; #( +*) + AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE']) +;; +esac + +#For debugging: +#echo DX_FLAG_doc=$DX_FLAG_doc +#echo DX_FLAG_dot=$DX_FLAG_dot +#echo DX_FLAG_man=$DX_FLAG_man +#echo DX_FLAG_html=$DX_FLAG_html +#echo DX_FLAG_chm=$DX_FLAG_chm +#echo DX_FLAG_chi=$DX_FLAG_chi +#echo DX_FLAG_rtf=$DX_FLAG_rtf +#echo DX_FLAG_xml=$DX_FLAG_xml +#echo DX_FLAG_pdf=$DX_FLAG_pdf +#echo DX_FLAG_ps=$DX_FLAG_ps +#echo DX_ENV=$DX_ENV +]) diff --git a/m4/otf.m4 b/m4/otf.m4 new file mode 100644 index 0000000..42b0224 --- /dev/null +++ b/m4/otf.m4 @@ -0,0 +1,74 @@ +# otf.m4 -- helper function to detect OTF libraries -*- Autoconf -*- +# Copyright (C) 2013 Galois, Inc. +# +# This library is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this library. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +# GALOIS_PPAML_LIB_OPENTRACE(ACTION-IF-FOUND, ACTION-IF-NOT-FOUND) +# This macro expands the OTF_CFLAGS and OTF_LIBS variables, but it does not add +# them to CFLAGS or LIBS. +AC_DEFUN([GALOIS_PPAML_LIB_OPENTRACE], [ + AC_REQUIRE([AC_PROG_SED]) + otf_ok=whoKnows + # Check for otfconfig. + AC_PATH_PROG([OTFCONFIG], [otfconfig]) + AC_ARG_VAR([OTFCONFIG], [path to otfconfig binary]) + if test -z "$OTFCONFIG"; then + otf_ok=no + else + OTF_CFLAGS="`"$OTFCONFIG" --includes`" + OTF_LIBS="`"$OTFCONFIG" --libs`" + # Save CFLAGS and LIBS, and reset CFLAGS and LIBS to the OTF + # requirements. + SAVECFLAGS="$CFLAGS" + SAVELIBS="$LIBS" + CFLAGS="$OTF_CFLAGS" + LIBS="$OTF_LIBS" + # Try to compile using the CFLAGS. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include "], + [int x = otf_errno;])], + [otf_compile_headers=yes], + [otf_compile_headers=no]) + # Try to compile using the libraries. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include "], + [int x = otf_errno;])], + [otf_link=yes], + [otf_link=no]) + # Did we pass? + if test \( "$otf_compile_headers" = "yes" \) -a \ + \( "$otf_link" = "yes" \); then + otf_ok=yes + else + otf_ok=no + fi + # Restore CFLAGS and LIBS. + CFLAGS="$SAVECFLAGS" + LIBS="$SAVELIBS" + fi + # Execute the users' blocks. + if test "$otf_ok" = "yes"; then + AC_SUBST([OTF_CFLAGS]) + AC_SUBST([OTF_LIBS]) + ifelse([$1], , :, [$1]) + else + ifelse([$2], , :, [$2]) + fi +]) diff --git a/ppamltracer.pc.in b/ppamltracer.pc.in new file mode 100644 index 0000000..a2a9a5f --- /dev/null +++ b/ppamltracer.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ppamltracer +Version: @PACKAGE_VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lppamltracer +Libs.private: @OTF_LIBS@ diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..d5f4ab2 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,35 @@ +# Makefile.am -- automake script for ppamltracer +# Copyright (C) 2013 Galois, Inc. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# To contact Galois, complete the Web form at +# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland, +# Oregon, 97204-1622. + +lib_LTLIBRARIES = libppamltracer.la +libppamltracer_la_SOURCES = \ + $(srcdir)/require.h \ + $(srcdir)/timing.c \ + $(srcdir)/timing.h \ + $(srcdir)/tracer.c +libppamltracer_la_CFLAGS = \ + -I$(top_srcdir)/include \ + -std=c99 \ + -Wall \ + -Wextra \ + -pedantic \ + @OTF_CFLAGS@ +libppamltracer_la_LIBADD = @OTF_LIBS@ +libppamltracer_la_LDFLAGS = -export-symbols-regex '^ppaml_' diff --git a/src/index.dox b/src/index.dox new file mode 100644 index 0000000..3dd4b77 --- /dev/null +++ b/src/index.dox @@ -0,0 +1,45 @@ +/* index.dox -- front-page documentation for ppamltracer -*- c -*- + * Copyright (C) 2013 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +/** + * @mainpage Overview + * + * ppamltracer is a lightweight, portable tracing library designed for explicit + * instrumention of generated code. If you're writing a compiler and need hard + * data on your optimizer's efficacy, ppamltracer is the library for you. + * + * @ref simple.c shows ppamltracer in action tracing two phases of computation + * (factorials and Fibonacci numbers), and honestly, it's probably all the API + * documentation you need. You can also have a look at @ref ppaml_tracer_t and + * @ref ppaml_phase_t, the data structures which ppamltracer manipulates. + * + * ppamltracer writes trace logs in the [Open Trace Format] + * (http://tu-dresden.de/zih/otf/), a free and open standard developed by the + * Zentrum für Informationsdienste und Hochleistungsrechnen (Center for + * Information Services and High-Performance Computing) at the Technical + * University of Dresden. + * + * We developed ppamltracer as part of DARPA's [Probabilistic Programming for + * Advancing Machine Learning] + * (http://darpa.mil/Our_Work/I2O/Programs/Probabilistic_Programming_for_Advanced_Machine_Learning_(PPAML%29.aspx) + * (PPAML) project. + * + * @example simple.c + */ diff --git a/src/require.h b/src/require.h new file mode 100644 index 0000000..f731c15 --- /dev/null +++ b/src/require.h @@ -0,0 +1,46 @@ +/* require.h -- useful error-handling macros + * Copyright (C) 2013 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +#ifndef REQUIRE_H +#define REQUIRE_H + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define require_not(var, val, ret_val) \ + do { \ + if ((var) != val) { \ + r = ret_val; \ + goto done; \ + } \ + } while (0) +#define require_zero(var, ret_val) require_not(var, 0, ret_val) +#define require_one(var, ret_val) require_not(var, 1, ret_val) + +#define require_nonnull(ptr, ret_val) \ + do { \ + if ((ptr) == NULL) { \ + r = ret_val; \ + goto done; \ + } \ + } while (0) + +#endif diff --git a/src/timing.c b/src/timing.c new file mode 100644 index 0000000..25cbba7 --- /dev/null +++ b/src/timing.c @@ -0,0 +1,86 @@ +/* timing.c -- cross-platform wall time + * Copyright (C) 2013 Galois, Inc. All rights reserved. */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#define _POSIX_C_SOURCE 199309L + +#include + +#include "timing.h" +#include "require.h" + +#define ignore(var) ((void)(var)) + +const uint64_t MICRO_PER_BASE = 1000000; +const uint64_t NANO_PER_MICRO = 1000; + +// Try to use the POSIX timers, if possible. +#if HAVE_UNISTD_H +# include +#endif +#if (HAVE_UNISTD_H && _POSIX_TIMERS > 0) + +# include + +# if __linux__ + /* Hopefully, you're running linux >=2.6.28, and + * CLOCK_MONOTONIC_RAW exists. */ + static const clockid_t CLOCK_ID = CLOCK_MONOTONIC_RAW; +# elif _POSIX_MONOTONIC_CLOCK + // You're not on Linux, but you've got a POSIX monotonic clock. + static const clockid_t CLOCK_ID = CLOCK_MONOTONIC; +# else + // Just use the POSIX wall clock. + static const clockid_t CLOCK_ID = CLOCK_REALTIME; +# endif + + int timing_get_wall(uint64_t *const result) + { + int r = 0; + struct timespec now; + require_zero(clock_gettime(CLOCK_ID, &now), 1); + *result = (uint64_t)now.tv_sec * MICRO_PER_BASE + + (uint64_t)now.tv_nsec / NANO_PER_MICRO; + done: return r; + } + +#elif (__APPLE__ && __MACH__) + + /* No POSIX timers, but we're on a Mac, so we can use + * 'mach_absolute_time'. */ +# include + + int timing_get_wall(uint64_t *const result) + { + static mach_timebase_info_data_t timebase_info; + int r = 0; + *result = mach_absolute_time(); + /* *result is now in units of Mach ticks. Convert that to + * nanoseconds using the timebase information that Mach + * provides. Note that 'timebase_info' is static, so it got + * zeroed out at the start of the program run; if its + * denominator is still zero, we've definitely not stored + * anything in it yet. */ + if (timebase_info.denom == 0) { + require_zero(mach_timebase_info(&timebase_info), 1); + } + *result = *result * timebase_info.numer / timebase_info.denom; + // Convert nanoseconds to microseconds. + *result /= NANO_PER_MICRO; + done: return r; + } + +#else + + // I have no clue what wacky platform you're on. +# error Unsupported timing platform + + int timing_get_wall(uint64_t *const result) + { + ignore(result); + return -1; + } + +#endif diff --git a/src/timing.h b/src/timing.h new file mode 100644 index 0000000..167e536 --- /dev/null +++ b/src/timing.h @@ -0,0 +1,32 @@ +/* timing.h -- cross-platform wall time + * Copyright (C) 2013 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +#ifndef TIMING_H +#define TIMING_H + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +int timing_get_wall(uint64_t *result); + +#endif diff --git a/src/tracer.c b/src/tracer.c new file mode 100644 index 0000000..be2f3cc --- /dev/null +++ b/src/tracer.c @@ -0,0 +1,133 @@ +/* tracer.c -- PPAML timing instrumentation + * Copyright (C) 2013 Galois, Inc. + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this library. If not, see . + * + * To contact Galois, complete the Web form at + * or write to Galois, Inc., 421 Southwest + * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include + +#include +#include + +#include "timing.h" +#include "require.h" + +const size_t ppaml_tracer_t_size = sizeof(ppaml_tracer_t); +const size_t ppaml_phase_t_size = sizeof(ppaml_phase_t); + +int ppaml_tracer_init( + ppaml_tracer_t *const tracer, + const char report_name_base[]) +{ + int r = 0; + // Initialize the file manager. + const uint32_t max_fds = 1024; // TODO: ulimit default on my system + tracer->manager = OTF_FileManager_open(max_fds); + require_nonnull(tracer->manager, 1); + // Initialize the writer. + tracer->writer = OTF_Writer_open(report_name_base, 1, tracer->manager); + require_nonnull(tracer->writer, 2); + // Record that we have a resolution of 1 microsecond. + require_one( + OTF_Writer_writeDefTimerResolution(tracer->writer, 0, 1000000), + 3); + // Define an OTF process (i.e., a thread). + require_one( + OTF_Writer_writeDefProcess(tracer->writer, 0, 1, "main", 0), + 4); +done: return r; +} + +int ppaml_tracer_done(ppaml_tracer_t *const tracer) +{ + int r = 0; + // Close the writer. + require_one(OTF_Writer_close(tracer->writer), 1); + tracer->writer = NULL; + // Close the file manager. + OTF_FileManager_close(tracer->manager); + tracer->manager = NULL; +done: return r; +} + +int ppaml_phase_init( + ppaml_tracer_t *const tracer, + ppaml_phase_t *const phase, + const char name[]) +{ + static uint32_t next_function_id = 1; + int r = 0; + require_one( + OTF_Writer_writeDefFunction( + tracer->writer, + 0, // stream id = 1 + next_function_id, + name, + 0, // no function group + 0), // no source code + 1); + phase->tracer = tracer; + phase->otf_function_id = next_function_id; + next_function_id++; +done: return r; +} + +int ppaml_phase_done(ppaml_phase_t *const phase) +{ + phase->tracer = NULL; + phase->otf_function_id = 0; + return 0; +} + +int ppaml_phase_start(ppaml_phase_t *const phase) +{ + int r = 0; + uint64_t now; + require_zero(timing_get_wall(&now), 1); + require_one( + OTF_Writer_writeEnter( + phase->tracer->writer, + now, + phase->otf_function_id, + 1, // process id = 1 + 0), // no source code + 2); +done: return r; +} + +int ppaml_phase_stop(ppaml_phase_t *const phase) +{ + int r = 0; + uint64_t now; + require_zero(timing_get_wall(&now), 1); + require_one( + OTF_Writer_writeLeave( + phase->tracer->writer, + now, + phase->otf_function_id, + 1, // process id = 1 + 0), // no source code + 2); +done: return r; +} -- cgit v1.2.3