diff options
Diffstat (limited to '')
193 files changed, 65476 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aae8e7c --- /dev/null +++ b/.gitignore @@ -0,0 +1,101 @@ +# automake +Makefile +Makefile.in +/ar-lib +/mdate-sh +/py-compile +/test-driver +/ylwrap +.deps/ +.dirstamp + +# autoconf +autom4te.cache +/config.h +/config.rpath +/autoscan.log +/autoscan-*.log +/aclocal.m4 +/compile +/config.guess +/config.h.in +/config.log +/config.status +/config.sub +/configure +/configure.scan +/depcomp +/install-sh +/missing +/stamp-h1 + +# libtool +/libtool +/ltmain.sh +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 +.libs +*.lo +*.la + +# texinfo +/texinfo.tex + +# autoreconf and gettext +/ABOUT-NLS +m4/ax_add_fortify_source.m4 +m4/ax_cxx_compile_stdcxx.m4 +m4/ax_pthread.m4 +m4/gettext.m4 +m4/host-cpu-c-abi.m4 +m4/iconv.m4 +m4/intlmacosx.m4 +m4/lib-ld.m4 +m4/lib-link.m4 +m4/lib-prefix.m4 +m4/nls.m4 +m4/pkg.m4 +m4/po.m4 +m4/progtest.m4 +po/POTFILES +po/Makevars.template +po/Rules-quot +po/boldquot.sed +po/en@boldquot.header +po/en@quot.header +po/insert-header.sin +po/quot.sed +po/remove-potcdate.sin +po/remove-potcdate.sed + +# gettext build artifacts +po/ca.gmo +po/cs_CZ.gmo +po/de_DE.gmo +po/en_GB.gmo +po/en_US.gmo +po/es_ES.gmo +po/hu_HU.gmo +po/id_ID.gmo +po/nl_NL.gmo +po/stamp-po +po/zh_TW.gmo + +# other generated files +/Doxyfile +src/css.h + +# object files +*.o +src/powertop + +# development tools +cscope.out +tags + +# doxygen +doc/html +Doxyfile.in.bak diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md new file mode 100644 index 0000000..4287d41 --- /dev/null +++ b/CONTRIBUTE.md @@ -0,0 +1,188 @@ +# How to Contribute to PowerTOP + +If you are interested in PowerTOP and wish to put some time and effort into it, +this is the document for you. Filing bug reports, translating text strings, +editing or creating documentation, helping fellow users, or making changes to +the program source code are some of the ways you can contribute to the project. + +Thank you for your interest in PowerTOP. We appreciate your effort, time, and +continued participation in this project. + + +# Official source code repository + +The official source code repository is hosted on GitHub*, so a GitHub account is +strongly recommended for effective collaboration. All bug filings, changes, and +releases are hosted there: +* [Official Upstream Repository][upstream] + +Developers, check out the "Code Conventions" section further down. We look +forward to your pull requests! + + +# Finding bugs + +No software is perfect. Since PowerTOP is a diagnostic/debug tool concerned +with your system, different hardware may behave differently than we expect, +resulting in weird behaviors (or crashes). There are plenty of bugs to be found +and squashed, and we appreciate your willingness to help. + +Bugs will be filed here: +* [Official Upstream Repository][upstream] + +It is important to note that bug filings are the start of a conversation, and +conversations are two-way streets. When you find a bug, do not merely "file and +forget". Expect follow-up questions to be asked. We may even ask you to patch, +re-compile, and re-run to see if our change(s) fix your issue, especially if +your system's particular behavior(s) have revealed the bug. + +If one of us asks you to do something that tests the limits of your comfort or +ability, say so, and we will do our best to help you. + + +# Writing documentation + +Here is the layout of PowerTOP's documentation: +* `CONTRIBUTE.md` is this document +* `README.md` covers cloning, building, and getting started with PowerTOP +* `doc/powertop.8` is the (roff) manual page for the project +* Code comments (or lack thereof) + +PowerTOP, at present, does not generate a library for use by other programs, so +there is no "PowerTOP API". The source code does have internal functions and +APIs for specific duties that are key to program functionality. Those need to +be thoroughly documented for future developers. + +Markdown documents follow the latest CommonMark spec. Generally speaking, +do not use GitHub's proprietary extensions to Markdown syntax. +* [CommonMark Specifications][cmark] + +The manual page uses roff syntax. +* `man 7 roff`, or +* [man 7 roff (in html)][manroff] + +Code comments are described in the "Code Conventions" section further down. + + +# Localization + +PowerTOP uses `gettext` for localization. Translating strings is done using PO +files, and those are contributed back to PowerTOP through a GitHub pull +request. + +If you are new to `gettext`, here is the official documentation for it: +* [Creating PO Files][gettext_create] + +The `gettext` project also has some links to commonly-used PO editors: +* [Editing PO Files][gettext_edit] + + +# Code conventions + +PowerTOP's maintainers will enforce the Linux* kernel coding style. +* [Linux Kernel Coding Style][kernel_style] + +That style guide is tailored for the Linux kernel, so "I" is Linus Torvalds. +For the purposes of the PowerTOP project, the maintainers of PowerTOP have the +final say on style. If a specific thing does not apply to PowerTOP, the essence +of the guidance almost surely does. This section will be expanded upon +as needed. + +While C++ is used in some parts of the codebase, C-style comments are +preferred. This is copy-pasted directly from the kernel style guide: + + /* + * This is the preferred style for multi-line + * comments in the Linux kernel source code. + * Please use it consistently. + * + * Description: A column of asterisks on the left side, + * with beginning and ending almost-blank lines. + */ + +There are sections of that style guide that are specific to the kernel-- the +"Allocating Memory" and "Don't re-invent the kernel macros" sections come to +mind. The essential take-aways from those sections are: "Use the right function +for the right job" and "do not re-invent existing functionality". That is sound +development advice for any software project. + +The PowerTOP code base is constantly evolving, and the code base has been +around for a while. Expect to see code that does not follow the kernel style +guide. If you find any such code, fix it or let us know. Those are style bugs +that need fixing. + +When you submit a patch to the PowerTOP project, we assume you agree to +what's written in the "License" section below. + + +# License + +PowerTOP is a GPLv2 project (see `COPYING` and `README.md`). All contributions +will be licensed under the terms of the GPLv2. + +If you create a new source file or header, here is the comment to be placed at +the beginning (from line 1) of the new file: + +``` +/* + * Copyright (C) yyyy name of author + * + * 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; version 2. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * SPDX-License-Identifier: GPL-2.0-only + */ +``` + +All contributions to PowerTOP *must* adhere to the Linux kernel's "Developer's +Certificate of Origin", which we will copy-paste here for completeness: + +By making a contribution to this project, you certify that: + +``` +a. The contribution was created in whole or in part by me and I have the right + to submit it under the open source license indicated in the file; or + +b. The contribution is based upon previous work that, to the best of my + knowledge, is covered under an appropriate open source license and I have the + right under that license to submit that work with modifications, whether + created in whole or in part by me, under the same open source license (unless I + am permitted to submit under a different license), as indicated in the file; or + +c. The contribution was provided directly to me by some other person who + certified (a), (b) or (c) and I have not modified it. + +d. I understand and agree that this project and the contribution are public and + that a record of the contribution (including all personal information I submit + with it, including my sign-off) is maintained indefinitely and may be + redistributed consistent with this project or the open source license(s) + involved. +``` + +From: [Developer's Cerificate of Origin][kernel_cos] + + +# Thank You! + +Again, thank you! Your time and effort are greatly appreciated! We look forward +to your contributions, and appreciate your continued participation in the +project! + + +[upstream]: https://github.com/fenrus75/powertop "Official PowerTOP Repository" +[cmark]: https://spec.commonmark.org/ "External Link: CommonMark Specifications" +[manroff]: http://man7.org/linux/man-pages/man7/roff.7.html "External Link: man 7 roff" +[gettext_create]: https://www.gnu.org/software/gettext/manual/html_node/Creating.html#Creating "External Link: Creating a PO File" +[gettext_edit]: https://www.gnu.org/software/gettext/manual/html_node/Editing.html#Editing "External Link: PO File Editors" +[kernel_style]: https://www.kernel.org/doc/html/latest/process/coding-style.html "External Link: Linux kernel coding style" +[kernel_cos]: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin "External Link: Developer's Certificate of Origin" @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/Doxyfile.in b/Doxyfile.in new file mode 100644 index 0000000..c354044 --- /dev/null +++ b/Doxyfile.in @@ -0,0 +1,2498 @@ +# Doxyfile 1.8.18 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "PowerTOP" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = @VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = "PowerTop.png" + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = NO + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = YES + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# (including Cygwin) ands Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = src \ + traceevent + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), +# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen +# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png The default and svg Looks nicer but requires the +# pdf2svg tool. +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = svg + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = YES + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = NativeMML + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using JavaScript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO, the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: NO. + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = YES + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = svg + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = YES + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..34d085c --- /dev/null +++ b/Makefile.am @@ -0,0 +1,17 @@ +AUTOMAKE_OPTIONS = subdir-objects +ACLOCAL_AMFLAGS = --install -I m4 + +SUBDIRS = \ + traceevent \ + src \ + po \ + doc \ + scripts/bash-completion + +EXTRA_DIST = \ + config.rpath \ + m4/ChangeLog \ + README \ + TODO \ + COPYING \ + autogen.sh diff --git a/PowerTop.png b/PowerTop.png Binary files differnew file mode 100644 index 0000000..838272b --- /dev/null +++ b/PowerTop.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..43bd5b2 --- /dev/null +++ b/README.md @@ -0,0 +1,201 @@ +# PowerTOP + +PowerTOP is a Linux* tool used to diagnose issues with power consumption and +power management. In addition to being a diagnostic tool, PowerTOP also has an +interactive mode you can use to experiment with various power management +settings, for cases where the Linux distribution has not enabled those +settings. + + +# Build dependencies + +PowerTOP is coded in C++. It was written for Linux-based operating systems. +GNU* libc (`glibc`) and Linux `pthreads` are needed for PowerTOP to function +properly. The GNU build system (`autoconf`, `automake`, `make`, `libtool`), as +well as `gettext`, are required to build PowerTOP. + +In addition, PowerTOP requires the following: + +* kernel version => 2.6.38 +* `ncurses-devel` (required) +* `libnl-devel` (required) +* `pciutils-devel` (is only required if you have PCI) +* `autoconf-archive` (for building) + +Example packages to install in Ubuntu*: + + sudo apt install libpci-dev libnl-3-dev libnl-genl-3-dev gettext \ + libgettextpo-dev autopoint gettext libncurses5-dev libncursesw5-dev libtool-bin \ + dh-autoreconf autoconf-archive pkg-config + + +## Building PowerTOP + +The `autogen.sh` script needs to be run only once to generate `configure`. +You need to re-run it only if the build system configuration files +(e.g. `configure.ac`) are modified. The remaining steps are required whenever +source files are modified. + +To build PowerTOP from the cloned source, use the following commands: + + ./autogen.sh + ./configure + make + + +# Running PowerTOP + +The following sections go over basic operation of PowerTOP. This includes +kernel configuration options (or kernel patches) needed for full functionality. +Run `powertop --help` to see all options. + + +## Kernel parameters and (optional) patches + +PowerTOP needs some kernel config options enabled to function +properly. As of linux-3.3.0, these are (the list probably is incomplete): + + CONFIG_NO_HZ + CONFIG_HIGH_RES_TIMERS + CONFIG_HPET_TIMER + CONFIG_CPU_FREQ_GOV_ONDEMAND + CONFIG_USB_SUSPEND + CONFIG_SND_AC97_POWER_SAVE + CONFIG_TIMER_STATS + CONFIG_PERF_EVENTS + CONFIG_PERF_COUNTERS + CONFIG_TRACEPOINTS + CONFIG_TRACING + CONFIG_EVENT_POWER_TRACING_DEPRECATED + CONFIG_X86_MSR + ACPI_PROCFS_POWER + CONFIG_DEBUG_FS + +Use these configs from linux-3.13.rc1: + + CONFIG_POWERCAP + CONFIG_INTEL_RAPL + +The patches in the `patches/` sub-directory are optional but enable *full* +PowerTOP functionality. + + +## Outputting a report + +When PowerTOP is executed as root and without arguments, it runs in +interactive mode. In this mode, PowerTOP most resembles `top`. + +For generating reports, or for filing functional bug reports, there are two +output modes: CSV and HTML. You can set sample times, the number of iterations, +a workload over which to run PowerTOP, and whether to include +`debug`-level output. + +For an HTML report, execute PowerTOP with this option: + + powertop --html=report.html + +This creates a static `report.html` file, suitable for sharing. + +For a CSV report, execute PowerTOP with this option: + + powertop --csv=report.csv + +This creates a static `powertop.csv` file, also suitable for sharing. + +If you wish to file a functional bug report, generate and share a +`debug`-mode HTML report and share it, using the following command: + + powertop --debug --html=report.html + +**Important Note:** As PowerTOP is intended for privileged (`root`) use, your +reports-- especially when run with `--debug`-- will contain verbose system +information. PowerTOP **does not** sanitize, scrub, or otherwise anonymize its +reports. Be mindful of this when sharing reports. + +**Developers:** If you make changes to the HTML reporting code, validate HTML +output by using the W3C* Markup Validation Service and the W3C CSS Validation +Service: +* http://validator.w3.org/#validate_by_upload +* http://jigsaw.w3.org/css-validator/#validate_by_upload + + +## Calibrating and power numbers + +PowerTOP, when running on battery, tracks power consumption and activity on +the system. Once there are sufficient measurements, PowerTOP can start to +report power estimates for various activities. You can help increase the +accuracy of the estimation by running a calibration cycle at least once: + + powertop --calibrate + +*Calibration* entails cycling through various display brightness levels +(including "off"), USB device activities, and other workloads. + + +## Extech Power Analyzer / Datalogger support + +Our analysis teams use the Extech* Power Analyzer/Datalogger (model +number 380803). PowerTOP supports this device over the serial cable by passing +the device node on the command line using this command: + + powertop --extech=/dev/ttyUSB0 + +(where ttyUSB0 is the devicenode of the serial-to-usb adapter on our system) + + +# Contributing to PowerTOP and getting support + +There are numerous ways you and your friends can contribute to PowerTOP. See +the `CONTRIBUTE.md` document for more details. Elevator summary: "fork, and +send PRs!". + +We have a mailing list: `powertop@lists.01.org`: +* Subscribe at: + * https://lists.01.org/postorius/lists/powertop.lists.01.org/ +* Browse archives at: + * https://lists.01.org/hyperkitty/list/powertop@lists.01.org/ + +If you find bugs, you can file an issue-- see `CONTRIBUTE.md` for further +details: +* File bugs/wishes at: + * https://github.com/fenrus75/powertop/issues + + +# Code from other open source projects + +PowerTOP contains some code from other open source projects; we'd like to thank +the authors of those projects for their work. Specifically, PowerTOP contains +code from + +``` +Parse Event Library - Copyright 2009, 2010 Red Hat Inc Steven Rostedt <srostedt@redhat.com> +nl80211 userspace tool - Copyright 2007, 2008 Johannes Berg <johannes@sipsolutions.net> +``` + + +# Copyright and License + + PowerTOP + Copyright (C) 2020 Intel Corporation + + 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; version 2. + + 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +See `COPYING` file for a copy of the aforementioned (GPLv2) license. + + +## SPDX Tag + + /* SPDX-License-Identifier: GPL-2.0-only */ + +From: https://spdx.org/licenses/GPL-2.0-only.html diff --git a/README.traceevent b/README.traceevent new file mode 100644 index 0000000..0747766 --- /dev/null +++ b/README.traceevent @@ -0,0 +1,20 @@ +traceevent: + +The traceevent library being built in PowerTOP is really a effort by +Steven Rostedt. The long term intent is for Steven to push the trace +event library to distributions, and consume it externally. Right now the +PowerTOP project is keeping in sync with his code posted in the Linux +kernel git under tools/lib/traceevent. We will not take patches into the +traceevent code directly, rather we will be re-basing against that code +base. + +If you find a bug in the trace event code, you should to one of two things. + +1. Send a patch to the PowerTOP mailing list, which will get forwared to + Steven if appropriate. + +2. Send a patch to the PowerTOP mailing list, and + CC: Steven Rostedt <rostedt@goodmis.org> + +Please do use the PowerTOP mailing list to discuss topics about +traceevent as its used with PowerTOP. @@ -0,0 +1,21 @@ +Needed for 2.2 +---------------------------------- + +* more translations / strings +* more end user documentation +* audio calibration? Need appropriate sample +* reporting for workload mode +* Add GPU stats to reports [csv,html] + + +Nice to Have +---------------------------------- +NCURSES STUB (anyone who may care to do this) + PowerTOP is intended to be run with ncurses. As such if there is any + distribution that can't or won't support ncurses, they need to supply + a separate stub to handle there issues. + +DONE for 2.2 +---------------------------------- +* interactive mode scrolling +* In tunables suggest writing min_power to all SATA ports diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..e210037 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +autoreconf --install --verbose diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f057463 --- /dev/null +++ b/configure.ac @@ -0,0 +1,169 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.69]) +AC_INIT([powertop], [2.15], [powertop@lists.01.org], [], [https://github.com/fenrus75/powertop]) +AM_INIT_AUTOMAKE([ + -Wall + 1.12.2 + foreign +]) +AC_LANG([C++]) +AC_CONFIG_FILES([ + Makefile + Doxyfile + src/Makefile + traceevent/Makefile + po/Makefile.in + doc/Makefile + scripts/bash-completion/Makefile +]) +AC_CONFIG_SRCDIR([src/main.cpp]) +AC_CONFIG_MACRO_DIR([m4]) +AC_USE_SYSTEM_EXTENSIONS +AC_CONFIG_HEADERS([config.h]) +GETTEXT_PACKAGE=powertop +AC_SUBST([GETTEXT_PACKAGE]) +AM_SILENT_RULES([yes]) +AM_GNU_GETTEXT([external]) +AM_GNU_GETTEXT_VERSION([0.18.2]) + +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +AX_REQUIRE_DEFINED([AX_ADD_FORTIFY_SOURCE]) +AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) +AX_REQUIRE_DEFINED([AX_PTHREAD]) +# Checks for programs. +AC_PROG_CPP +AC_PROG_CXX +AC_PROG_LIBTOOL +AC_PROG_CC +AC_PROG_INSTALL +AM_PROG_CC_C_O +AX_ADD_FORTIFY_SOURCE +AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) +PKG_PROG_PKG_CONFIG + +# Checks for libraries. +AX_PTHREAD([ + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + CC="$PTHREAD_CC" + ], [ + AC_MSG_ERROR([Could not configure pthreads support]) +]) + +# Checks for header files. +AC_CHECK_HEADERS([ \ + fcntl.h \ + libintl.h \ + limits.h \ + locale.h \ + malloc.h \ + ncurses.h \ + stdint.h \ + stdlib.h \ + string.h \ + sys/ioctl.h \ + sys/socket.h \ + sys/statfs.h \ + sys/time.h \ + termios.h \ + unistd.h \ +]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_INLINE +AC_TYPE_INT64_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_MMAP +AC_FUNC_REALLOC +AC_FUNC_STRERROR_R +AC_FUNC_STRTOD +AC_CHECK_FUNCS([ \ + clock_gettime \ + fdatasync \ + getpagesize \ + gettimeofday \ + memmove \ + memset \ + mkdir \ + munmap \ + pow \ + realpath \ + regcomp \ + select \ + setlocale \ + socket \ + sqrt \ + strcasecmp \ + strchr \ + strrchr \ + strdup \ + strerror \ + strncasecmp \ + strstr \ + strtoul \ + strtoull \ +]) + +AC_SEARCH_LIBS([clock_gettime], [rt]) + +PKG_CHECK_MODULES([NCURSES], [ncursesw ncurses], [LIBS="$LIBS $ncurses_LIBS"], [ + AC_SEARCH_LIBS([delwin], [ncursesw ncurses], [], [ + AC_MSG_ERROR([ncurses is required but was not found]) + ], []) +]) + +has_libpci=0 +PKG_CHECK_MODULES([PCIUTILS], [libpci],[has_libpci=1], [ + AC_SEARCH_LIBS([pci_get_dev], [pci],[has_libpci=1], [has_libpci=0]) +]) + + +has_libnl_ver=0 +dnl libnl-2 provides only libnl-2.0.pc file, so we check for separate +dnl libnl-genl-3.0.pc pkg-config file just for libnl-3.0 case. +PKG_CHECK_MODULES([LIBNL], [libnl-3.0 >= 3.0 libnl-genl-3.0 >= 3.0], [has_libnl_ver=3], [ + PKG_CHECK_MODULES([LIBNL], [libnl-2.0 >= 2.0], [has_libnl_ver=2], [ + PKG_CHECK_MODULES([LIBNL], [libnl-1], [has_libnl_ver=1], [has_libnl_ver=0]) + ]) +]) +AS_IF([test "$has_libnl_ver" -eq 0], [ + AC_MSG_ERROR([libnl and libnl-genl are required but were not found]) +]) +AS_IF([test "$has_libnl_ver" -gt 1], [ + AC_DEFINE([HAVE_LIBNL20], [1], [Define if you have libnl-2.0 or higher]) +]) + +AS_IF([test "$has_libpci" -eq 0], [ + AC_DEFINE([HAVE_NO_PCI], [1], [Define if pci is not supported]) + AC_MSG_WARN([ + ************* LIBPCI SUPPORT NOT CONFIGURED************** + If you need or want pci support, please install libpci + and re-configure PowerTOP. + ********************************************************* + ]) +]) + +AC_SEARCH_LIBS([inet_aton], [resolv], [], [ + AC_MSG_ERROR([libresolv is required but was not found]) +], []) + + +AS_IF([`${PKG_CONFIG} --exists bash-completion`], [ + bashcompletiondir=`${PKG_CONFIG} --variable=completionsdir --define-variable=prefix=${prefix} bash-completion` +], [ + bashcompletiondir=${datadir}/bash-completion/completions +]) +AC_SUBST([bashcompletiondir], [$bashcompletiondir]) + +AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..3fa3770 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,2 @@ +man_MANS = powertop.8 +EXTRA_DIST = powertop.8 diff --git a/doc/powertop.8 b/doc/powertop.8 new file mode 100644 index 0000000..60e3c73 --- /dev/null +++ b/doc/powertop.8 @@ -0,0 +1,103 @@ +.TH POWERTOP "8" "2014-08-02" "powertop manual" "System Administration" +.SH NAME +powertop \- a power consumption and power management diagnosis tool. +.SH SYNOPSIS +.B powertop +.RI [ options ] +.SH DESCRIPTION +.B powertop +is a program that helps to diagnose various issues with power consumption +and power management. It also has an interactive mode allowing one to +experiment with various power management settings. When invoking +powertop without arguments powertop starts in interactive mode. +.SH OPTIONS +.TP +.B \-\-auto\-tune +Set all tunable options to their good setting without interaction. +.TP +.BR \-c ", " \-\-calibrate +Runs powertop in calibration mode. When running on battery, powertop can +track power consumption as well as system activity. When there are +enough measurements, powertop can start to report power estimates. One +can get more accurate estimates by using this option to enable a +calibration cycle. This will cycle through various display levels and +USB device activities and workloads. +.TP +\fB\-C\fR, \fB\-\-csv\fR[=\fIfilename\fR] +Generate a CSV report. If a +.I filename +is not specified then the default name +.B powertop.csv +is used. The CSV report can be used for reporting and data analysis. +.TP +.B \-\-debug +Run in debug mode. +.TP +\fB\-\-extech\fR=\fIdevnode\fR +Use the Extech Power Analyzer for measurements. This allows one to +specify the serial device node of the serial to USB adaptor connecting to +the Extech Power Analyzer, for example +.IR /dev/ttyUSB0 . +.TP +\fB\-r\fR, \fB\-\-html\fR[=\fIfilename\fR] +Generate an HTML report. If a +.I filename +is not specified then the default name +.B powertop.html +is used. The HTML report can be sent to others to help diagnose power +issues. +.TP +\fB\-i\fR, \fB\-\-iteration\fR[=\fIiterations\fR] +Number of times to run each test. +.TP +.BR \-q ", " \-\-quiet +Suppress stderr output. +.TP +\fB\-t\fR, \fB\-\-time\fR[=\fIseconds\fR] +Generate a report for a specified number of +.IR seconds . +.TP +\fB\-w\fR, \fB\-\-workload\fR[=\fIworkload\fR] +Execute +.I workload +file as a part of calibration before making a report. +.TP +.BR \-V ", " \-\-version +Print version information and exit. +.TP +.BR \-h ", " \-\-help +Show the help message and exit. +.SH COMMANDS +In interactive mode, the following key bindings are available: +.IP +.TS +tab(@); +l l. +\fBTab\fR@Show next tab +\fBBackTab\fR@Show previous tab +\fBRight Arrow\fR@Scroll to the right +\fBLeft Arrow\fR@Scroll to the left +\fBUp Arrow\fR, \fBPageUp\fR@Scroll up or select previous item +\fBDown Arrow\fR, \fBPageDown\fR@Scroll down or select next item +\fBSpace\fR, \fBReturn\fR@Activate current item +\fBs\fR@Set refresh timeout +\fBr\fR@Refresh window +\fBq\fR, \fBCtrl-C\fR, \fBEscape\fR@Exit powertop +.TE +.SH BUGS +Send bug reports to +.MT powertop@lists.01.org +.ME +.SH SEE ALSO +The program is more fully described at +.UR https://01.org/powertop +.UE +.SH AUTHOR +powertop was written by +.MT arjan@\:linux.\:intel.\:com +Arjan van de Ven +.ME , +and is currently maintained by +.MT chris.\:e.\:ferron@\:linux.\:intel.\:com +Chris E Ferron +.ME . diff --git a/m4/ChangeLog b/m4/ChangeLog new file mode 100644 index 0000000..f415dc0 --- /dev/null +++ b/m4/ChangeLog @@ -0,0 +1,11 @@ +2016-08-03 gettextize <bug-gnu-gettext@gnu.org> + + * gettext.m4: New file, from gettext-0.18.2. + * iconv.m4: New file, from gettext-0.18.2. + * lib-ld.m4: New file, from gettext-0.18.2. + * lib-link.m4: New file, from gettext-0.18.2. + * lib-prefix.m4: New file, from gettext-0.18.2. + * nls.m4: New file, from gettext-0.18.2. + * po.m4: New file, from gettext-0.18.2. + * progtest.m4: New file, from gettext-0.18.2. + diff --git a/patches/linux-2.6.37-ahci-alpm-accounting.patch b/patches/linux-2.6.37-ahci-alpm-accounting.patch new file mode 100644 index 0000000..dbe897d --- /dev/null +++ b/patches/linux-2.6.37-ahci-alpm-accounting.patch @@ -0,0 +1,302 @@ +From: Arjan van de Ven <arjan@linux.intel.com> +Subject: [PATCH] libata: Add ALPM power state accounting to the AHCI driver + +PowerTOP wants to be able to show the user how effective the ALPM link +power management is for the user. ALPM is worth around 0.5W on a quiet +link; PowerTOP wants to be able to find cases where the "quiet link" isn't +actually quiet. + +This patch adds state accounting functionality to the AHCI driver for +PowerTOP to use. +The parts of the patch are +1) the sysfs logic of exposing the stats for each state in sysfs +2) the basic accounting logic that gets update on link change interrupts + (or when the user accesses the info from sysfs) +3) a "accounting enable" flag; in order to get the accounting to work, + the driver needs to get phyrdy interrupts on link status changes. + Normally and currently this is disabled by the driver when ALPM is + on (to reduce overhead); when PowerTOP is running this will need + to be on to get usable statistics... hence the sysfs tunable. + +The PowerTOP output currently looks like this: + +Recent SATA AHCI link activity statistics +Active Partial Slumber Device name + 0.5% 99.5% 0.0% host0 + +(work to resolve "host0" to a more human readable name is in progress) + +Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> + +--- + drivers/ata/ahci.h | 15 ++++ + drivers/ata/libahci.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 200 insertions(+), 2 deletions(-) + +Index: linux-2.6.37/drivers/ata/ahci.h +=================================================================== +--- linux-2.6.37.orig/drivers/ata/ahci.h ++++ linux-2.6.37/drivers/ata/ahci.h +@@ -262,6 +262,13 @@ struct ahci_em_priv { + unsigned long led_state; + }; + ++enum ahci_port_states { ++ AHCI_PORT_NOLINK = 0, ++ AHCI_PORT_ACTIVE = 1, ++ AHCI_PORT_PARTIAL = 2, ++ AHCI_PORT_SLUMBER = 3 ++}; ++ + struct ahci_port_priv { + struct ata_link *active_link; + struct ahci_cmd_hdr *cmd_slot; +@@ -280,6 +287,14 @@ struct ahci_port_priv { + int fbs_last_dev; /* save FBS.DEV of last FIS */ + /* enclosure management info per PM slot */ + struct ahci_em_priv em_priv[EM_MAX_SLOTS]; ++ ++ /* ALPM accounting state and stats */ ++ unsigned int accounting_active:1; ++ u64 active_jiffies; ++ u64 partial_jiffies; ++ u64 slumber_jiffies; ++ int previous_state; ++ int previous_jiffies; + }; + + struct ahci_host_priv { +Index: linux-2.6.37/drivers/ata/libahci.c +=================================================================== +--- linux-2.6.37.orig/drivers/ata/libahci.c ++++ linux-2.6.37/drivers/ata/libahci.c +@@ -58,6 +58,17 @@ MODULE_PARM_DESC(ignore_sss, "Ignore sta + + static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + unsigned hints); ++static ssize_t ahci_alpm_show_active(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_slumber(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_partial(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_accounting(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_set_accounting(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count); + static ssize_t ahci_led_show(struct ata_port *ap, char *buf); + static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, + size_t size); +@@ -117,6 +128,12 @@ static DEVICE_ATTR(ahci_host_caps, S_IRU + static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); + static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); + static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); ++static DEVICE_ATTR(ahci_alpm_active, S_IRUGO, ahci_alpm_show_active, NULL); ++static DEVICE_ATTR(ahci_alpm_partial, S_IRUGO, ahci_alpm_show_partial, NULL); ++static DEVICE_ATTR(ahci_alpm_slumber, S_IRUGO, ahci_alpm_show_slumber, NULL); ++static DEVICE_ATTR(ahci_alpm_accounting, S_IRUGO | S_IWUSR, ++ ahci_alpm_show_accounting, ahci_alpm_set_accounting); ++ + static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, + ahci_read_em_buffer, ahci_store_em_buffer); + +@@ -128,6 +145,10 @@ struct device_attribute *ahci_shost_attr + &dev_attr_ahci_host_cap2, + &dev_attr_ahci_host_version, + &dev_attr_ahci_port_cmd, ++ &dev_attr_ahci_alpm_active, ++ &dev_attr_ahci_alpm_partial, ++ &dev_attr_ahci_alpm_slumber, ++ &dev_attr_ahci_alpm_accounting, + &dev_attr_em_buffer, + NULL + }; +@@ -653,9 +674,14 @@ static int ahci_set_lpm(struct ata_link + * Disable interrupts on Phy Ready. This keeps us from + * getting woken up due to spurious phy ready + * interrupts. ++ * ++ * However, when accounting_active is set, we do want ++ * the interrupts for accounting purposes. + */ +- pp->intr_mask &= ~PORT_IRQ_PHYRDY; +- writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ if (!pp->accounting_active) { ++ pp->intr_mask &= ~PORT_IRQ_PHYRDY; ++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ } + + sata_link_scr_lpm(link, policy, false); + } +@@ -1570,6 +1596,162 @@ static void ahci_error_intr(struct ata_p + ata_port_abort(ap); + } + ++static int get_current_alpm_state(struct ata_port *ap) ++{ ++ u32 status = 0; ++ ++ ahci_scr_read(&ap->link, SCR_STATUS, &status); ++ ++ /* link status is in bits 11-8 */ ++ status = status >> 8; ++ status = status & 0x7; ++ ++ if (status == 6) ++ return AHCI_PORT_SLUMBER; ++ if (status == 2) ++ return AHCI_PORT_PARTIAL; ++ if (status == 1) ++ return AHCI_PORT_ACTIVE; ++ return AHCI_PORT_NOLINK; ++} ++ ++static void account_alpm_stats(struct ata_port *ap) ++{ ++ struct ahci_port_priv *pp; ++ ++ int new_state; ++ u64 new_jiffies, jiffies_delta; ++ ++ if (ap == NULL) ++ return; ++ pp = ap->private_data; ++ ++ if (!pp) return; ++ ++ new_state = get_current_alpm_state(ap); ++ new_jiffies = jiffies; ++ ++ jiffies_delta = new_jiffies - pp->previous_jiffies; ++ ++ switch (pp->previous_state) { ++ case AHCI_PORT_NOLINK: ++ pp->active_jiffies = 0; ++ pp->partial_jiffies = 0; ++ pp->slumber_jiffies = 0; ++ break; ++ case AHCI_PORT_ACTIVE: ++ pp->active_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_PARTIAL: ++ pp->partial_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_SLUMBER: ++ pp->slumber_jiffies += jiffies_delta; ++ break; ++ default: ++ break; ++ } ++ pp->previous_state = new_state; ++ pp->previous_jiffies = new_jiffies; ++} ++ ++static ssize_t ahci_alpm_show_active(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->active_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_partial(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->partial_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_slumber(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->slumber_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_accounting(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ ++ return sprintf(buf, "%u\n", pp->accounting_active); ++} ++ ++static ssize_t ahci_alpm_set_accounting(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long flags; ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ void __iomem *port_mmio; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return 1; ++ ++ pp = ap->private_data; ++ port_mmio = ahci_port_base(ap); ++ ++ if (!pp) ++ return 1; ++ if (buf[0] == '0') ++ pp->accounting_active = 0; ++ if (buf[0] == '1') ++ pp->accounting_active = 1; ++ ++ /* we need to enable the PHYRDY interrupt when we want accounting */ ++ if (pp->accounting_active) { ++ spin_lock_irqsave(ap->lock, flags); ++ pp->intr_mask |= PORT_IRQ_PHYRDY; ++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ spin_unlock_irqrestore(ap->lock, flags); ++ } ++ return count; ++} ++ ++ + static void ahci_port_intr(struct ata_port *ap) + { + void __iomem *port_mmio = ahci_port_base(ap); +@@ -1590,6 +1772,7 @@ static void ahci_port_intr(struct ata_po + /* if LPM is enabled, PHYRDY doesn't mean anything */ + if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { + status &= ~PORT_IRQ_PHYRDY; ++ account_alpm_stats(ap); + ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); + } + diff --git a/patches/linux-2.6.37-vfs-dirty-inode.patch b/patches/linux-2.6.37-vfs-dirty-inode.patch new file mode 100644 index 0000000..c218291 --- /dev/null +++ b/patches/linux-2.6.37-vfs-dirty-inode.patch @@ -0,0 +1,102 @@ +From 3950d3c04a6bf8ccf9ff912a49bdd242a2fe9e47 Mon Sep 17 00:00:00 2001 +From: Arjan van de Ven <arjan@linux.intel.com> +Date: Fri, 26 Nov 2010 12:18:03 -0800 +Subject: [PATCH] vfs: Add a trace point in the mark_inode_dirty function + +PowerTOP would like to be able to show who is keeping the disk +busy by dirtying data. The most logical spot for this is in the vfs +in the mark_inode_dirty() function, doing this on the block level +is not possible because by the time the IO hits the block layer the +guilty party can no longer be found ("kjournald" and "pdflush" are not +useful answers to "who caused this file to be dirty). + +The trace point follows the same logic/style as the block_dump code +and pretty much dumps the same data, just not to dmesg (and thus to +/var/log/messages) but via the trace events streams. + +Eventually we should be able to phase out the block dump code, but that's +for later on after a transition time. + +Signed-of-by: Arjan van de Ven <arjan@linux.intel.com> +--- + fs/fs-writeback.c | 3 +++ + include/linux/fs.h | 12 ++++++++++++ + include/trace/events/writeback.h | 28 ++++++++++++++++++++++++++++ + 3 files changed, 43 insertions(+) + +Index: linux-2.6.37/fs/fs-writeback.c +=================================================================== +--- linux-2.6.37.orig/fs/fs-writeback.c ++++ linux-2.6.37/fs/fs-writeback.c +@@ -952,6 +952,9 @@ void __mark_inode_dirty(struct inode *in + if ((inode->i_state & flags) == flags) + return; + ++ if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)) ++ trace_writeback_inode_dirty(inode, flags); ++ + if (unlikely(block_dump)) + block_dump___mark_inode_dirty(inode); + +Index: linux-2.6.37/include/linux/fs.h +=================================================================== +--- linux-2.6.37.orig/include/linux/fs.h ++++ linux-2.6.37/include/linux/fs.h +@@ -1677,6 +1677,18 @@ struct super_operations { + + #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) + ++#define INODE_DIRTY_FLAGS \ ++ { I_DIRTY_SYNC, "DIRTY-SYNC" }, \ ++ { I_DIRTY_DATASYNC, "DIRTY-DATASYNC" }, \ ++ { I_DIRTY_PAGES, "DIRTY-PAGES" }, \ ++ { I_NEW, "NEW" }, \ ++ { I_WILL_FREE, "WILL-FREE" }, \ ++ { I_FREEING, "FREEING" }, \ ++ { I_CLEAR, "CLEAR" }, \ ++ { I_SYNC, "SYNC" }, \ ++ { I_REFERENCED, "REFERENCED" } ++ ++ + extern void __mark_inode_dirty(struct inode *, int); + static inline void mark_inode_dirty(struct inode *inode) + { +Index: linux-2.6.37/include/trace/events/writeback.h +=================================================================== +--- linux-2.6.37.orig/include/trace/events/writeback.h ++++ linux-2.6.37/include/trace/events/writeback.h +@@ -186,6 +186,34 @@ DEFINE_EVENT(writeback_congest_waited_te + TP_ARGS(usec_timeout, usec_delayed) + ); + ++/* ++ * Tracepoint for dirtying an inode; used by PowerTOP ++ */ ++TRACE_EVENT(writeback_inode_dirty, ++ ++ TP_PROTO(struct inode *inode, int flags), ++ ++ TP_ARGS(inode, flags), ++ ++ TP_STRUCT__entry( ++ __field( __kernel_dev_t, dev ) ++ __field( ino_t, ino ) ++ __field( u32, flags ) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = inode->i_sb->s_dev; ++ __entry->ino = inode->i_ino; ++ __entry->flags = flags; ++ ), ++ ++ TP_printk("dev %d:%d ino %lu flags %d %s", MAJOR(__entry->dev), MINOR(__entry->dev), ++ (unsigned long) __entry->ino, ++ __entry->flags, ++ __print_flags(__entry->flags, "|", INODE_DIRTY_FLAGS) ++ ) ++); ++ + #endif /* _TRACE_WRITEBACK_H */ + + /* This part must be outside protection */ diff --git a/patches/linux-3.15-rc3-ahci-alpm-with-devslp-accounting.patch b/patches/linux-3.15-rc3-ahci-alpm-with-devslp-accounting.patch new file mode 100644 index 0000000..254f58b --- /dev/null +++ b/patches/linux-3.15-rc3-ahci-alpm-with-devslp-accounting.patch @@ -0,0 +1,340 @@ +From 9022555b1fc7c7a71adf3a0871ba3609fc2f4bc0 Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw2@infradead.org>
+Date: Mon, 1 Apr 2013 20:53:07 +0100
+Subject: [PATCH] Updated PowerTOP AHCI ALPM accounting for Device Sleep.
+
+This patch applies to v3.7 onwards (including 3.9-rc4), and adds devslp
+support to the AHCI state accounting. It's based on the patch at
+https://raw.github.com/fenrus75/powertop/master/patches/linux-3.3.0-ahci-alpm-accounting.patch
+
+From: Arjan van de Ven <arjan@linux.intel.com>
+Subject: libata: Add ALPM power state accounting to the AHCI driver
+
+PowerTOP wants to be able to show the user how effective the ALPM link
+power management is for the user. ALPM is worth around 0.5W on a quiet
+link; PowerTOP wants to be able to find cases where the "quiet link" isn't
+actually quiet.
+
+This patch adds state accounting functionality to the AHCI driver for
+PowerTOP to use.
+The parts of the patch are
+1) the sysfs logic of exposing the stats for each state in sysfs
+2) the basic accounting logic that gets update on link change interrupts
+ (or when the user accesses the info from sysfs)
+3) a "accounting enable" flag; in order to get the accounting to work,
+ the driver needs to get phyrdy interrupts on link status changes.
+ Normally and currently this is disabled by the driver when ALPM is
+ on (to reduce overhead); when PowerTOP is running this will need
+ to be on to get usable statistics... hence the sysfs tunable.
+
+The PowerTOP output currently looks like this:
+
+Recent SATA AHCI link activity statistics
+Active Partial Slumber Device name
+ 0.5% 99.5% 0.0% host0
+
+(work to resolve "host0" to a more human readable name is in progress)
+
+Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+---
+ drivers/ata/ahci.h | 17 ++++
+ drivers/ata/libahci.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 226 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
+index 2289efd..7a80e34 100644
+--- a/drivers/ata/ahci.h
++++ b/drivers/ata/ahci.h
+@@ -286,6 +286,14 @@ struct ahci_em_priv {
+ unsigned long led_state;
+ };
+
++enum ahci_port_states {
++ AHCI_PORT_NOLINK = 0,
++ AHCI_PORT_ACTIVE = 1,
++ AHCI_PORT_PARTIAL = 2,
++ AHCI_PORT_SLUMBER = 3,
++ AHCI_PORT_DEVSLP = 4
++};
++
+ struct ahci_port_priv {
+ struct ata_link *active_link;
+ struct ahci_cmd_hdr *cmd_slot;
+@@ -307,6 +315,15 @@ struct ahci_port_priv {
+ /* enclosure management info per PM slot */
+ struct ahci_em_priv em_priv[EM_MAX_SLOTS];
+ char *irq_desc; /* desc in /proc/interrupts */
++
++ /* ALPM accounting state and stats */
++ unsigned int accounting_active:1;
++ u64 active_jiffies;
++ u64 partial_jiffies;
++ u64 slumber_jiffies;
++ u64 devslp_jiffies;
++ int previous_state;
++ int previous_jiffies;
+ };
+
+ struct ahci_host_priv {
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index 36605ab..4e69272 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -99,6 +99,19 @@ static ssize_t ahci_activity_store(struct ata_device *dev,
+ enum sw_activity val);
+ static void ahci_init_sw_activity(struct ata_link *link);
+
++static ssize_t ahci_alpm_show_active(struct device *dev,
++ struct device_attribute *attr, char *buf);
++static ssize_t ahci_alpm_show_slumber(struct device *dev,
++ struct device_attribute *attr, char *buf);
++static ssize_t ahci_alpm_show_devslp(struct device *dev,
++ struct device_attribute *attr, char *buf);
++static ssize_t ahci_alpm_show_partial(struct device *dev,
++ struct device_attribute *attr, char *buf);
++static ssize_t ahci_alpm_show_accounting(struct device *dev,
++ struct device_attribute *attr, char *buf);
++static ssize_t ahci_alpm_set_accounting(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count);
+ static ssize_t ahci_show_host_caps(struct device *dev,
+ struct device_attribute *attr, char *buf);
+ static ssize_t ahci_show_host_cap2(struct device *dev,
+@@ -119,6 +132,13 @@ static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
+ static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
+ static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
+ static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
++static DEVICE_ATTR(ahci_alpm_active, S_IRUGO, ahci_alpm_show_active, NULL);
++static DEVICE_ATTR(ahci_alpm_partial, S_IRUGO, ahci_alpm_show_partial, NULL);
++static DEVICE_ATTR(ahci_alpm_slumber, S_IRUGO, ahci_alpm_show_slumber, NULL);
++static DEVICE_ATTR(ahci_alpm_devslp, S_IRUGO, ahci_alpm_show_devslp, NULL);
++static DEVICE_ATTR(ahci_alpm_accounting, S_IRUGO | S_IWUSR,
++ ahci_alpm_show_accounting, ahci_alpm_set_accounting);
++
+ static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO,
+ ahci_read_em_buffer, ahci_store_em_buffer);
+ static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL);
+@@ -131,6 +151,11 @@ struct device_attribute *ahci_shost_attrs[] = {
+ &dev_attr_ahci_host_cap2,
+ &dev_attr_ahci_host_version,
+ &dev_attr_ahci_port_cmd,
++ &dev_attr_ahci_alpm_active,
++ &dev_attr_ahci_alpm_partial,
++ &dev_attr_ahci_alpm_slumber,
++ &dev_attr_ahci_alpm_devslp,
++ &dev_attr_ahci_alpm_accounting,
+ &dev_attr_em_buffer,
+ &dev_attr_em_message_supported,
+ NULL
+@@ -225,6 +250,182 @@ static void ahci_enable_ahci(void __iomem *mmio)
+ WARN_ON(1);
+ }
+
++static int get_current_alpm_state(struct ata_port *ap)
++{
++ u32 status = 0;
++
++ ahci_scr_read(&ap->link, SCR_STATUS, &status);
++
++ /* link status is in bits 11-8 */
++ status = status >> 8;
++ status = status & 0xf;
++
++ if (status == 8)
++ return AHCI_PORT_DEVSLP;
++ if (status == 6)
++ return AHCI_PORT_SLUMBER;
++ if (status == 2)
++ return AHCI_PORT_PARTIAL;
++ if (status == 1)
++ return AHCI_PORT_ACTIVE;
++ return AHCI_PORT_NOLINK;
++}
++
++static void account_alpm_stats(struct ata_port *ap)
++{
++ struct ahci_port_priv *pp;
++
++ int new_state;
++ u64 new_jiffies, jiffies_delta;
++
++ if (ap == NULL)
++ return;
++ pp = ap->private_data;
++
++ if (!pp) return;
++
++ new_state = get_current_alpm_state(ap);
++ new_jiffies = jiffies;
++
++ jiffies_delta = new_jiffies - pp->previous_jiffies;
++
++ switch (pp->previous_state) {
++ case AHCI_PORT_NOLINK:
++ pp->active_jiffies = 0;
++ pp->partial_jiffies = 0;
++ pp->slumber_jiffies = 0;
++ break;
++ case AHCI_PORT_ACTIVE:
++ pp->active_jiffies += jiffies_delta;
++ break;
++ case AHCI_PORT_PARTIAL:
++ pp->partial_jiffies += jiffies_delta;
++ break;
++ case AHCI_PORT_SLUMBER:
++ pp->slumber_jiffies += jiffies_delta;
++ break;
++ case AHCI_PORT_DEVSLP:
++ pp->devslp_jiffies += jiffies_delta;
++ break;
++ default:
++ break;
++ }
++ pp->previous_state = new_state;
++ pp->previous_jiffies = new_jiffies;
++}
++
++static ssize_t ahci_alpm_show_active(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct ata_port *ap = ata_shost_to_port(shost);
++ struct ahci_port_priv *pp;
++
++ if (!ap || ata_port_is_dummy(ap))
++ return -EINVAL;
++
++ pp = ap->private_data;
++ account_alpm_stats(ap);
++
++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->active_jiffies));
++}
++
++static ssize_t ahci_alpm_show_partial(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct ata_port *ap = ata_shost_to_port(shost);
++ struct ahci_port_priv *pp;
++
++ if (!ap || ata_port_is_dummy(ap))
++ return -EINVAL;
++
++ pp = ap->private_data;
++ account_alpm_stats(ap);
++
++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->partial_jiffies));
++}
++
++static ssize_t ahci_alpm_show_slumber(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct ata_port *ap = ata_shost_to_port(shost);
++ struct ahci_port_priv *pp;
++
++ if (!ap || ata_port_is_dummy(ap))
++ return -EINVAL;
++
++ pp = ap->private_data;
++ account_alpm_stats(ap);
++
++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->slumber_jiffies));
++}
++
++static ssize_t ahci_alpm_show_devslp(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct ata_port *ap = ata_shost_to_port(shost);
++ struct ahci_port_priv *pp;
++
++ if (!ap || ata_port_is_dummy(ap))
++ return -EINVAL;
++
++ pp = ap->private_data;
++ account_alpm_stats(ap);
++
++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->devslp_jiffies));
++}
++
++static ssize_t ahci_alpm_show_accounting(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct ata_port *ap = ata_shost_to_port(shost);
++ struct ahci_port_priv *pp;
++
++ if (!ap || ata_port_is_dummy(ap))
++ return -EINVAL;
++
++ pp = ap->private_data;
++
++ return sprintf(buf, "%u\n", pp->accounting_active);
++}
++
++static ssize_t ahci_alpm_set_accounting(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ unsigned long flags;
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct ata_port *ap = ata_shost_to_port(shost);
++ struct ahci_port_priv *pp;
++ void __iomem *port_mmio;
++
++ if (!ap || ata_port_is_dummy(ap))
++ return 1;
++
++ pp = ap->private_data;
++ port_mmio = ahci_port_base(ap);
++
++ if (!pp)
++ return 1;
++ if (buf[0] == '0')
++ pp->accounting_active = 0;
++ if (buf[0] == '1')
++ pp->accounting_active = 1;
++
++ /* we need to enable the PHYRDY interrupt when we want accounting */
++ if (pp->accounting_active) {
++ spin_lock_irqsave(ap->lock, flags);
++ pp->intr_mask |= PORT_IRQ_PHYRDY;
++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
++ spin_unlock_irqrestore(ap->lock, flags);
++ }
++ return count;
++}
++
+ static ssize_t ahci_show_host_caps(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -680,9 +881,14 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
+ * Disable interrupts on Phy Ready. This keeps us from
+ * getting woken up due to spurious phy ready
+ * interrupts.
++ *
++ * However, when accounting_active is set, we do want
++ * the interrupts for accounting purposes.
+ */
+- pp->intr_mask &= ~PORT_IRQ_PHYRDY;
+- writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
++ if (!pp->accounting_active) {
++ pp->intr_mask &= ~PORT_IRQ_PHYRDY;
++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
++ }
+
+ sata_link_scr_lpm(link, policy, false);
+ }
+@@ -1696,6 +1902,7 @@ static void ahci_handle_port_interrupt(struct ata_port *ap,
+ /* if LPM is enabled, PHYRDY doesn't mean anything */
+ if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) {
+ status &= ~PORT_IRQ_PHYRDY;
++ account_alpm_stats(ap);
+ ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG);
+ }
+
+--
+1.7.10.4
diff --git a/patches/linux-3.3.0-ahci-alpm-accounting.patch b/patches/linux-3.3.0-ahci-alpm-accounting.patch new file mode 100644 index 0000000..8b2f892 --- /dev/null +++ b/patches/linux-3.3.0-ahci-alpm-accounting.patch @@ -0,0 +1,307 @@ +From 3d1f00627a8db9d71091db32cd8109962f69ec43 Mon Sep 17 00:00:00 2001 +From: Arjan van de Ven <arjan at linux.intel.com> +Date: Sat, 31 Mar 2012 20:35:12 +0200 +Subject: [PATCH 2/2] libata: Add ALPM power state accounting to the AHCI + driver + +PowerTOP wants to be able to show the user how effective the ALPM link +power management is for the user. ALPM is worth around 0.5W on a quiet +link; PowerTOP wants to be able to find cases where the "quiet link" isn't +actually quiet. + +This patch adds state accounting functionality to the AHCI driver for +PowerTOP to use. +The parts of the patch are +1) the sysfs logic of exposing the stats for each state in sysfs +2) the basic accounting logic that gets update on link change interrupts + (or when the user accesses the info from sysfs) +3) a "accounting enable" flag; in order to get the accounting to work, + the driver needs to get phyrdy interrupts on link status changes. + Normally and currently this is disabled by the driver when ALPM is + on (to reduce overhead); when PowerTOP is running this will need + to be on to get usable statistics... hence the sysfs tunable. + +The PowerTOP output currently looks like this: + +Recent SATA AHCI link activity statistics +Active Partial Slumber Device name + 0.5% 99.5% 0.0% host0 + +(work to resolve "host0" to a more human readable name is in progress) + +Signed-off-by: Arjan van de Ven <arjan at linux.intel.com> +--- + drivers/ata/ahci.h | 15 ++++ + drivers/ata/libahci.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 200 insertions(+), 2 deletions(-) + +diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h +index b175000..38297f9 100644 +--- a/drivers/ata/ahci.h ++++ b/drivers/ata/ahci.h +@@ -264,6 +264,13 @@ struct ahci_em_priv { + unsigned long led_state; + }; + ++enum ahci_port_states { ++ AHCI_PORT_NOLINK = 0, ++ AHCI_PORT_ACTIVE = 1, ++ AHCI_PORT_PARTIAL = 2, ++ AHCI_PORT_SLUMBER = 3 ++}; ++ + struct ahci_port_priv { + struct ata_link *active_link; + struct ahci_cmd_hdr *cmd_slot; +@@ -282,6 +289,14 @@ struct ahci_port_priv { + int fbs_last_dev; /* save FBS.DEV of last FIS */ + /* enclosure management info per PM slot */ + struct ahci_em_priv em_priv[EM_MAX_SLOTS]; ++ ++ /* ALPM accounting state and stats */ ++ unsigned int accounting_active:1; ++ u64 active_jiffies; ++ u64 partial_jiffies; ++ u64 slumber_jiffies; ++ int previous_state; ++ int previous_jiffies; + }; + + struct ahci_host_priv { +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index a72bfd0..5859215 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -58,6 +58,17 @@ MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ig + + static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + unsigned hints); ++static ssize_t ahci_alpm_show_active(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_slumber(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_partial(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_accounting(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_set_accounting(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count); + static ssize_t ahci_led_show(struct ata_port *ap, char *buf); + static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, + size_t size); +@@ -118,6 +129,12 @@ static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); + static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); + static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); + static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); ++static DEVICE_ATTR(ahci_alpm_active, S_IRUGO, ahci_alpm_show_active, NULL); ++static DEVICE_ATTR(ahci_alpm_partial, S_IRUGO, ahci_alpm_show_partial, NULL); ++static DEVICE_ATTR(ahci_alpm_slumber, S_IRUGO, ahci_alpm_show_slumber, NULL); ++static DEVICE_ATTR(ahci_alpm_accounting, S_IRUGO | S_IWUSR, ++ ahci_alpm_show_accounting, ahci_alpm_set_accounting); ++ + static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, + ahci_read_em_buffer, ahci_store_em_buffer); + static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); +@@ -130,6 +147,10 @@ struct device_attribute *ahci_shost_attrs[] = { + &dev_attr_ahci_host_cap2, + &dev_attr_ahci_host_version, + &dev_attr_ahci_port_cmd, ++ &dev_attr_ahci_alpm_active, ++ &dev_attr_ahci_alpm_partial, ++ &dev_attr_ahci_alpm_slumber, ++ &dev_attr_ahci_alpm_accounting, + &dev_attr_em_buffer, + &dev_attr_em_message_supported, + NULL +@@ -673,9 +694,14 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + * Disable interrupts on Phy Ready. This keeps us from + * getting woken up due to spurious phy ready + * interrupts. ++ * ++ * However, when accounting_active is set, we do want ++ * the interrupts for accounting purposes. + */ +- pp->intr_mask &= ~PORT_IRQ_PHYRDY; +- writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ if (!pp->accounting_active) { ++ pp->intr_mask &= ~PORT_IRQ_PHYRDY; ++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ } + + sata_link_scr_lpm(link, policy, false); + } +@@ -1633,6 +1659,162 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) + ata_port_abort(ap); + } + ++static int get_current_alpm_state(struct ata_port *ap) ++{ ++ u32 status = 0; ++ ++ ahci_scr_read(&ap->link, SCR_STATUS, &status); ++ ++ /* link status is in bits 11-8 */ ++ status = status >> 8; ++ status = status & 0x7; ++ ++ if (status == 6) ++ return AHCI_PORT_SLUMBER; ++ if (status == 2) ++ return AHCI_PORT_PARTIAL; ++ if (status == 1) ++ return AHCI_PORT_ACTIVE; ++ return AHCI_PORT_NOLINK; ++} ++ ++static void account_alpm_stats(struct ata_port *ap) ++{ ++ struct ahci_port_priv *pp; ++ ++ int new_state; ++ u64 new_jiffies, jiffies_delta; ++ ++ if (ap == NULL) ++ return; ++ pp = ap->private_data; ++ ++ if (!pp) return; ++ ++ new_state = get_current_alpm_state(ap); ++ new_jiffies = jiffies; ++ ++ jiffies_delta = new_jiffies - pp->previous_jiffies; ++ ++ switch (pp->previous_state) { ++ case AHCI_PORT_NOLINK: ++ pp->active_jiffies = 0; ++ pp->partial_jiffies = 0; ++ pp->slumber_jiffies = 0; ++ break; ++ case AHCI_PORT_ACTIVE: ++ pp->active_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_PARTIAL: ++ pp->partial_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_SLUMBER: ++ pp->slumber_jiffies += jiffies_delta; ++ break; ++ default: ++ break; ++ } ++ pp->previous_state = new_state; ++ pp->previous_jiffies = new_jiffies; ++} ++ ++static ssize_t ahci_alpm_show_active(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->active_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_partial(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->partial_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_slumber(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->slumber_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_accounting(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ ++ return sprintf(buf, "%u\n", pp->accounting_active); ++} ++ ++static ssize_t ahci_alpm_set_accounting(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long flags; ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ void __iomem *port_mmio; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return 1; ++ ++ pp = ap->private_data; ++ port_mmio = ahci_port_base(ap); ++ ++ if (!pp) ++ return 1; ++ if (buf[0] == '0') ++ pp->accounting_active = 0; ++ if (buf[0] == '1') ++ pp->accounting_active = 1; ++ ++ /* we need to enable the PHYRDY interrupt when we want accounting */ ++ if (pp->accounting_active) { ++ spin_lock_irqsave(ap->lock, flags); ++ pp->intr_mask |= PORT_IRQ_PHYRDY; ++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ spin_unlock_irqrestore(ap->lock, flags); ++ } ++ return count; ++} ++ ++ + static void ahci_port_intr(struct ata_port *ap) + { + void __iomem *port_mmio = ahci_port_base(ap); +@@ -1653,6 +1835,7 @@ static void ahci_port_intr(struct ata_port *ap) + /* if LPM is enabled, PHYRDY doesn't mean anything */ + if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { + status &= ~PORT_IRQ_PHYRDY; ++ account_alpm_stats(ap); + ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); + } + +-- +1.7.8.5 + diff --git a/patches/linux-3.3.0-vfs-dirty-inode.patch b/patches/linux-3.3.0-vfs-dirty-inode.patch new file mode 100644 index 0000000..4177093 --- /dev/null +++ b/patches/linux-3.3.0-vfs-dirty-inode.patch @@ -0,0 +1,103 @@ +From 9f7c5d04fdee46dbe715f2758152bb1664d4259c Mon Sep 17 00:00:00 2001 +From: Arjan van de Ven <arjan at linux.intel.com> +Date: Fri, 26 Nov 2010 12:18:03 -0800 +Subject: [PATCH 1/2] vfs: Add a trace point in the mark_inode_dirty function + +PowerTOP would like to be able to show who is keeping the disk +busy by dirtying data. The most logical spot for this is in the vfs +in the mark_inode_dirty() function, doing this on the block level +is not possible because by the time the IO hits the block layer the +guilty party can no longer be found ("kjournald" and "pdflush" are not +useful answers to "who caused this file to be dirty). + +The trace point follows the same logic/style as the block_dump code +and pretty much dumps the same data, just not to dmesg (and thus to +/var/log/messages) but via the trace events streams. + +Eventually we should be able to phase out the block dump code, but that's +for later on after a transition time. +--- + fs/fs-writeback.c | 3 +++ + include/linux/fs.h | 11 +++++++++++ + include/trace/events/writeback.h | 28 ++++++++++++++++++++++++++++ + 3 files changed, 42 insertions(+), 0 deletions(-) + +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index 5b4a936..5ef5bb0 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -1081,6 +1081,9 @@ void __mark_inode_dirty(struct inode *inode, int flags) + if ((inode->i_state & flags) == flags) + return; + ++ if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)) ++ trace_writeback_inode_dirty(inode, flags); ++ + if (unlikely(block_dump)) + block_dump___mark_inode_dirty(inode); + +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 69cd5bb..e0ac37c 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1768,6 +1768,18 @@ struct super_operations { + + #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) + ++#define INODE_DIRTY_FLAGS \ ++ { I_DIRTY_SYNC, "DIRTY-SYNC" }, \ ++ { I_DIRTY_DATASYNC, "DIRTY-DATASYNC" }, \ ++ { I_DIRTY_PAGES, "DIRTY-PAGES" }, \ ++ { I_NEW, "NEW" }, \ ++ { I_WILL_FREE, "WILL-FREE" }, \ ++ { I_FREEING, "FREEING" }, \ ++ { I_CLEAR, "CLEAR" }, \ ++ { I_SYNC, "SYNC" }, \ ++ { I_REFERENCED, "REFERENCED" } ++ ++ + extern void __mark_inode_dirty(struct inode *, int); + static inline void mark_inode_dirty(struct inode *inode) + { +diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h +index 5973410..5f1e2a3 100644 +--- a/include/trace/events/writeback.h ++++ b/include/trace/events/writeback.h +@@ -408,6 +408,34 @@ DEFINE_EVENT(writeback_congest_waited_template, writeback_wait_iff_congested, + TP_ARGS(usec_timeout, usec_delayed) + ); + ++/* ++ * Tracepoint for dirtying an inode; used by PowerTOP ++ */ ++TRACE_EVENT(writeback_inode_dirty, ++ ++ TP_PROTO(struct inode *inode, int flags), ++ ++ TP_ARGS(inode, flags), ++ ++ TP_STRUCT__entry( ++ __field( __kernel_dev_t, dev ) ++ __field( ino_t, ino ) ++ __field( u32, flags ) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = inode->i_sb->s_dev; ++ __entry->ino = inode->i_ino; ++ __entry->flags = flags; ++ ), ++ ++ TP_printk("dev %d:%d ino %lu flags %d %s", MAJOR(__entry->dev), MINOR(__entry->dev), ++ (unsigned long) __entry->ino, ++ __entry->flags, ++ __print_flags(__entry->flags, "|", INODE_DIRTY_FLAGS) ++ ) ++); ++ + DECLARE_EVENT_CLASS(writeback_single_inode_template, + + TP_PROTO(struct inode *inode, +-- +1.7.8.5 + diff --git a/patches/linux-3.9.0-ahci-alpm-accounting.patch b/patches/linux-3.9.0-ahci-alpm-accounting.patch new file mode 100644 index 0000000..e7d8df6 --- /dev/null +++ b/patches/linux-3.9.0-ahci-alpm-accounting.patch @@ -0,0 +1,306 @@ +From 9abcb86b6dffd17a90e841e8ae3ddd1a841f2feb Mon Sep 17 00:00:00 2001 +From: Arjan van de Ven <arjan at linux.intel.com> +Date: Sat, 31 Mar 2012 20:35:12 +0200 +Subject: [PATCH] libata: Add ALPM power state accounting to the AHCI driver + +PowerTOP wants to be able to show the user how effective the ALPM link +power management is for the user. ALPM is worth around 0.5W on a quiet +link; PowerTOP wants to be able to find cases where the "quiet link" isn't +actually quiet. + +This patch adds state accounting functionality to the AHCI driver for +PowerTOP to use. +The parts of the patch are +1) the sysfs logic of exposing the stats for each state in sysfs +2) the basic accounting logic that gets update on link change interrupts + (or when the user accesses the info from sysfs) +3) a "accounting enable" flag; in order to get the accounting to work, + the driver needs to get phyrdy interrupts on link status changes. + Normally and currently this is disabled by the driver when ALPM is + on (to reduce overhead); when PowerTOP is running this will need + to be on to get usable statistics... hence the sysfs tunable. + +The PowerTOP output currently looks like this: + +Recent SATA AHCI link activity statistics +Active Partial Slumber Device name + 0.5% 99.5% 0.0% host0 + +(work to resolve "host0" to a more human readable name is in progress) + +Signed-off-by: Arjan van de Ven <arjan at linux.intel.com> +--- + drivers/ata/ahci.h | 15 ++++ + drivers/ata/libahci.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 200 insertions(+), 2 deletions(-) + +diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h +index b830e6c..b7075da 100644 +--- a/drivers/ata/ahci.h ++++ b/drivers/ata/ahci.h +@@ -286,6 +286,13 @@ struct ahci_em_priv { + unsigned long led_state; + }; + ++enum ahci_port_states { ++ AHCI_PORT_NOLINK = 0, ++ AHCI_PORT_ACTIVE = 1, ++ AHCI_PORT_PARTIAL = 2, ++ AHCI_PORT_SLUMBER = 3 ++}; ++ + struct ahci_port_priv { + struct ata_link *active_link; + struct ahci_cmd_hdr *cmd_slot; +@@ -306,6 +313,14 @@ struct ahci_port_priv { + int fbs_last_dev; /* save FBS.DEV of last FIS */ + /* enclosure management info per PM slot */ + struct ahci_em_priv em_priv[EM_MAX_SLOTS]; ++ ++ /* ALPM accounting state and stats */ ++ unsigned int accounting_active:1; ++ u64 active_jiffies; ++ u64 partial_jiffies; ++ u64 slumber_jiffies; ++ int previous_state; ++ int previous_jiffies; + }; + + struct ahci_host_priv { +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index 34c8216..cf0d61d 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -59,6 +59,17 @@ MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ig + + static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + unsigned hints); ++static ssize_t ahci_alpm_show_active(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_slumber(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_partial(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_accounting(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_set_accounting(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count); + static ssize_t ahci_led_show(struct ata_port *ap, char *buf); + static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, + size_t size); +@@ -120,6 +131,12 @@ static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); + static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); + static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); + static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); ++static DEVICE_ATTR(ahci_alpm_active, S_IRUGO, ahci_alpm_show_active, NULL); ++static DEVICE_ATTR(ahci_alpm_partial, S_IRUGO, ahci_alpm_show_partial, NULL); ++static DEVICE_ATTR(ahci_alpm_slumber, S_IRUGO, ahci_alpm_show_slumber, NULL); ++static DEVICE_ATTR(ahci_alpm_accounting, S_IRUGO | S_IWUSR, ++ ahci_alpm_show_accounting, ahci_alpm_set_accounting); ++ + static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, + ahci_read_em_buffer, ahci_store_em_buffer); + static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); +@@ -132,6 +149,10 @@ struct device_attribute *ahci_shost_attrs[] = { + &dev_attr_ahci_host_cap2, + &dev_attr_ahci_host_version, + &dev_attr_ahci_port_cmd, ++ &dev_attr_ahci_alpm_active, ++ &dev_attr_ahci_alpm_partial, ++ &dev_attr_ahci_alpm_slumber, ++ &dev_attr_ahci_alpm_accounting, + &dev_attr_em_buffer, + &dev_attr_em_message_supported, + NULL +@@ -679,9 +700,14 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + * Disable interrupts on Phy Ready. This keeps us from + * getting woken up due to spurious phy ready + * interrupts. ++ * ++ * However, when accounting_active is set, we do want ++ * the interrupts for accounting purposes. + */ +- pp->intr_mask &= ~PORT_IRQ_PHYRDY; +- writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ if (!pp->accounting_active) { ++ pp->intr_mask &= ~PORT_IRQ_PHYRDY; ++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ } + + sata_link_scr_lpm(link, policy, false); + } +@@ -1655,6 +1681,162 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) + ata_port_abort(ap); + } + ++static int get_current_alpm_state(struct ata_port *ap) ++{ ++ u32 status = 0; ++ ++ ahci_scr_read(&ap->link, SCR_STATUS, &status); ++ ++ /* link status is in bits 11-8 */ ++ status = status >> 8; ++ status = status & 0x7; ++ ++ if (status == 6) ++ return AHCI_PORT_SLUMBER; ++ if (status == 2) ++ return AHCI_PORT_PARTIAL; ++ if (status == 1) ++ return AHCI_PORT_ACTIVE; ++ return AHCI_PORT_NOLINK; ++} ++ ++static void account_alpm_stats(struct ata_port *ap) ++{ ++ struct ahci_port_priv *pp; ++ ++ int new_state; ++ u64 new_jiffies, jiffies_delta; ++ ++ if (ap == NULL) ++ return; ++ pp = ap->private_data; ++ ++ if (!pp) return; ++ ++ new_state = get_current_alpm_state(ap); ++ new_jiffies = jiffies; ++ ++ jiffies_delta = new_jiffies - pp->previous_jiffies; ++ ++ switch (pp->previous_state) { ++ case AHCI_PORT_NOLINK: ++ pp->active_jiffies = 0; ++ pp->partial_jiffies = 0; ++ pp->slumber_jiffies = 0; ++ break; ++ case AHCI_PORT_ACTIVE: ++ pp->active_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_PARTIAL: ++ pp->partial_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_SLUMBER: ++ pp->slumber_jiffies += jiffies_delta; ++ break; ++ default: ++ break; ++ } ++ pp->previous_state = new_state; ++ pp->previous_jiffies = new_jiffies; ++} ++ ++static ssize_t ahci_alpm_show_active(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->active_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_partial(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->partial_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_slumber(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->slumber_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_accounting(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ ++ return sprintf(buf, "%u\n", pp->accounting_active); ++} ++ ++static ssize_t ahci_alpm_set_accounting(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long flags; ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ void __iomem *port_mmio; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return 1; ++ ++ pp = ap->private_data; ++ port_mmio = ahci_port_base(ap); ++ ++ if (!pp) ++ return 1; ++ if (buf[0] == '0') ++ pp->accounting_active = 0; ++ if (buf[0] == '1') ++ pp->accounting_active = 1; ++ ++ /* we need to enable the PHYRDY interrupt when we want accounting */ ++ if (pp->accounting_active) { ++ spin_lock_irqsave(ap->lock, flags); ++ pp->intr_mask |= PORT_IRQ_PHYRDY; ++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ spin_unlock_irqrestore(ap->lock, flags); ++ } ++ return count; ++} ++ ++ + static void ahci_handle_port_interrupt(struct ata_port *ap, + void __iomem *port_mmio, u32 status) + { +@@ -1672,6 +1854,7 @@ static void ahci_handle_port_interrupt(struct ata_port *ap, + /* if LPM is enabled, PHYRDY doesn't mean anything */ + if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { + status &= ~PORT_IRQ_PHYRDY; ++ account_alpm_stats(ap); + ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); + } + +-- +1.8.0 + diff --git a/patches/linux-3.9.0-ahci-alpm-with-devslp-accounting.patch b/patches/linux-3.9.0-ahci-alpm-with-devslp-accounting.patch new file mode 100644 index 0000000..b3f2073 --- /dev/null +++ b/patches/linux-3.9.0-ahci-alpm-with-devslp-accounting.patch @@ -0,0 +1,334 @@ +commit 1caeadb62f68b2f7c0e2cfc2b6de1f11b0314752 +Author: David Woodhouse <dwmw2@infradead.org> +Date: Mon Apr 1 20:53:07 2013 +0100 + + Updated PowerTOP AHCI ALPM accounting for Device Sleep. + + This patch applies to v3.7 onwards (including 3.9-rc4), and adds devslp + support to the AHCI state accounting. It's based on the patch at + https://raw.github.com/fenrus75/powertop/master/patches/linux-3.3.0-ahci-alpm-accounting.patch + + From: Arjan van de Ven <arjan@linux.intel.com> + Subject: libata: Add ALPM power state accounting to the AHCI driver + + PowerTOP wants to be able to show the user how effective the ALPM link + power management is for the user. ALPM is worth around 0.5W on a quiet + link; PowerTOP wants to be able to find cases where the "quiet link" isn't + actually quiet. + + This patch adds state accounting functionality to the AHCI driver for + PowerTOP to use. + The parts of the patch are + 1) the sysfs logic of exposing the stats for each state in sysfs + 2) the basic accounting logic that gets update on link change interrupts + (or when the user accesses the info from sysfs) + 3) a "accounting enable" flag; in order to get the accounting to work, + the driver needs to get phyrdy interrupts on link status changes. + Normally and currently this is disabled by the driver when ALPM is + on (to reduce overhead); when PowerTOP is running this will need + to be on to get usable statistics... hence the sysfs tunable. + + The PowerTOP output currently looks like this: + + Recent SATA AHCI link activity statistics + Active Partial Slumber Device name + 0.5% 99.5% 0.0% host0 + + (work to resolve "host0" to a more human readable name is in progress) + + Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> + Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> + +diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h +index b830e6c..981976b 100644 +--- a/drivers/ata/ahci.h ++++ b/drivers/ata/ahci.h +@@ -286,6 +286,14 @@ struct ahci_em_priv { + unsigned long led_state; + }; + ++enum ahci_port_states { ++ AHCI_PORT_NOLINK = 0, ++ AHCI_PORT_ACTIVE = 1, ++ AHCI_PORT_PARTIAL = 2, ++ AHCI_PORT_SLUMBER = 3, ++ AHCI_PORT_DEVSLP = 4 ++}; ++ + struct ahci_port_priv { + struct ata_link *active_link; + struct ahci_cmd_hdr *cmd_slot; +@@ -306,6 +314,15 @@ struct ahci_port_priv { + int fbs_last_dev; /* save FBS.DEV of last FIS */ + /* enclosure management info per PM slot */ + struct ahci_em_priv em_priv[EM_MAX_SLOTS]; ++ ++ /* ALPM accounting state and stats */ ++ unsigned int accounting_active:1; ++ u64 active_jiffies; ++ u64 partial_jiffies; ++ u64 slumber_jiffies; ++ u64 devslp_jiffies; ++ int previous_state; ++ int previous_jiffies; + }; + + struct ahci_host_priv { +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index 34c8216..3c7331b 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -100,6 +100,19 @@ static ssize_t ahci_activity_store(struct ata_device *dev, + enum sw_activity val); + static void ahci_init_sw_activity(struct ata_link *link); + ++static ssize_t ahci_alpm_show_active(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_slumber(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_devslp(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_partial(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_show_accounting(struct device *dev, ++ struct device_attribute *attr, char *buf); ++static ssize_t ahci_alpm_set_accounting(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count); + static ssize_t ahci_show_host_caps(struct device *dev, + struct device_attribute *attr, char *buf); + static ssize_t ahci_show_host_cap2(struct device *dev, +@@ -120,6 +133,13 @@ static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); + static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); + static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); + static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); ++static DEVICE_ATTR(ahci_alpm_active, S_IRUGO, ahci_alpm_show_active, NULL); ++static DEVICE_ATTR(ahci_alpm_partial, S_IRUGO, ahci_alpm_show_partial, NULL); ++static DEVICE_ATTR(ahci_alpm_slumber, S_IRUGO, ahci_alpm_show_slumber, NULL); ++static DEVICE_ATTR(ahci_alpm_devslp, S_IRUGO, ahci_alpm_show_devslp, NULL); ++static DEVICE_ATTR(ahci_alpm_accounting, S_IRUGO | S_IWUSR, ++ ahci_alpm_show_accounting, ahci_alpm_set_accounting); ++ + static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, + ahci_read_em_buffer, ahci_store_em_buffer); + static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); +@@ -132,6 +152,11 @@ struct device_attribute *ahci_shost_attrs[] = { + &dev_attr_ahci_host_cap2, + &dev_attr_ahci_host_version, + &dev_attr_ahci_port_cmd, ++ &dev_attr_ahci_alpm_active, ++ &dev_attr_ahci_alpm_partial, ++ &dev_attr_ahci_alpm_slumber, ++ &dev_attr_ahci_alpm_devslp, ++ &dev_attr_ahci_alpm_accounting, + &dev_attr_em_buffer, + &dev_attr_em_message_supported, + NULL +@@ -224,6 +249,182 @@ static void ahci_enable_ahci(void __iomem *mmio) + WARN_ON(1); + } + ++static int get_current_alpm_state(struct ata_port *ap) ++{ ++ u32 status = 0; ++ ++ ahci_scr_read(&ap->link, SCR_STATUS, &status); ++ ++ /* link status is in bits 11-8 */ ++ status = status >> 8; ++ status = status & 0xf; ++ ++ if (status == 8) ++ return AHCI_PORT_DEVSLP; ++ if (status == 6) ++ return AHCI_PORT_SLUMBER; ++ if (status == 2) ++ return AHCI_PORT_PARTIAL; ++ if (status == 1) ++ return AHCI_PORT_ACTIVE; ++ return AHCI_PORT_NOLINK; ++} ++ ++static void account_alpm_stats(struct ata_port *ap) ++{ ++ struct ahci_port_priv *pp; ++ ++ int new_state; ++ u64 new_jiffies, jiffies_delta; ++ ++ if (ap == NULL) ++ return; ++ pp = ap->private_data; ++ ++ if (!pp) return; ++ ++ new_state = get_current_alpm_state(ap); ++ new_jiffies = jiffies; ++ ++ jiffies_delta = new_jiffies - pp->previous_jiffies; ++ ++ switch (pp->previous_state) { ++ case AHCI_PORT_NOLINK: ++ pp->active_jiffies = 0; ++ pp->partial_jiffies = 0; ++ pp->slumber_jiffies = 0; ++ break; ++ case AHCI_PORT_ACTIVE: ++ pp->active_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_PARTIAL: ++ pp->partial_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_SLUMBER: ++ pp->slumber_jiffies += jiffies_delta; ++ break; ++ case AHCI_PORT_DEVSLP: ++ pp->devslp_jiffies += jiffies_delta; ++ break; ++ default: ++ break; ++ } ++ pp->previous_state = new_state; ++ pp->previous_jiffies = new_jiffies; ++} ++ ++static ssize_t ahci_alpm_show_active(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->active_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_partial(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->partial_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_slumber(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->slumber_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_devslp(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ account_alpm_stats(ap); ++ ++ return sprintf(buf, "%u\n", jiffies_to_msecs(pp->devslp_jiffies)); ++} ++ ++static ssize_t ahci_alpm_show_accounting(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return -EINVAL; ++ ++ pp = ap->private_data; ++ ++ return sprintf(buf, "%u\n", pp->accounting_active); ++} ++ ++static ssize_t ahci_alpm_set_accounting(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long flags; ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ struct ahci_port_priv *pp; ++ void __iomem *port_mmio; ++ ++ if (!ap || ata_port_is_dummy(ap)) ++ return 1; ++ ++ pp = ap->private_data; ++ port_mmio = ahci_port_base(ap); ++ ++ if (!pp) ++ return 1; ++ if (buf[0] == '0') ++ pp->accounting_active = 0; ++ if (buf[0] == '1') ++ pp->accounting_active = 1; ++ ++ /* we need to enable the PHYRDY interrupt when we want accounting */ ++ if (pp->accounting_active) { ++ spin_lock_irqsave(ap->lock, flags); ++ pp->intr_mask |= PORT_IRQ_PHYRDY; ++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ spin_unlock_irqrestore(ap->lock, flags); ++ } ++ return count; ++} ++ + static ssize_t ahci_show_host_caps(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -679,9 +880,14 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + * Disable interrupts on Phy Ready. This keeps us from + * getting woken up due to spurious phy ready + * interrupts. ++ * ++ * However, when accounting_active is set, we do want ++ * the interrupts for accounting purposes. + */ +- pp->intr_mask &= ~PORT_IRQ_PHYRDY; +- writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ if (!pp->accounting_active) { ++ pp->intr_mask &= ~PORT_IRQ_PHYRDY; ++ writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); ++ } + + sata_link_scr_lpm(link, policy, false); + } +@@ -1672,6 +1878,7 @@ static void ahci_handle_port_interrupt(struct ata_port *ap, + /* if LPM is enabled, PHYRDY doesn't mean anything */ + if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { + status &= ~PORT_IRQ_PHYRDY; ++ account_alpm_stats(ap); + ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); + } + diff --git a/po/.tx/config b/po/.tx/config new file mode 100644 index 0000000..f1603f2 --- /dev/null +++ b/po/.tx/config @@ -0,0 +1,3 @@ +[main] +host = https://www.transifex.com + diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 0000000..11de90c --- /dev/null +++ b/po/ChangeLog @@ -0,0 +1,11 @@ +2016-08-03 gettextize <bug-gnu-gettext@gnu.org> + + * Makefile.in.in: Upgrade to gettext-0.18.2. + * boldquot.sed: New file, from gettext-0.18.2. + * en@boldquot.header: New file, from gettext-0.18.2. + * en@quot.header: New file, from gettext-0.18.2. + * insert-header.sin: New file, from gettext-0.18.2. + * quot.sed: New file, from gettext-0.18.2. + * remove-potcdate.sin: New file, from gettext-0.18.2. + * Rules-quot: New file, from gettext-0.18.2. + diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 0000000..5939602 --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,11 @@ +# set of available languages +ca +cs_CZ +de_DE +en_GB +en_US +es_ES +hu_HU +id_ID +nl_NL +zh_TW diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 0000000..fce63a6 --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,453 @@ +# Makefile for PO directory in any package using GNU gettext. +# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu> +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU General Public +# License but which still want to provide support for the GNU gettext +# functionality. +# Please note that the actual code of GNU gettext is covered by the GNU +# General Public License and is *not* in the public domain. +# +# Origin: gettext-0.18.2 +GETTEXT_MACRO_VERSION = 0.18 + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +datadir = @datadir@ +localedir = @localedir@ +gettextsrcdir = $(datadir)/gettext/po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +# We use $(mkdir_p). +# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as +# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, +# @install_sh@ does not start with $(SHELL), so we add it. +# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined +# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake +# versions, $(mkinstalldirs) and $(install_sh) are unused. +mkinstalldirs = $(SHELL) @install_sh@ -d +install_sh = $(SHELL) @install_sh@ +MKDIR_P = @MKDIR_P@ +mkdir_p = @mkdir_p@ + +GMSGFMT_ = @GMSGFMT@ +GMSGFMT_no = @GMSGFMT@ +GMSGFMT_yes = @GMSGFMT_015@ +GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) +MSGFMT_ = @MSGFMT@ +MSGFMT_no = @MSGFMT@ +MSGFMT_yes = @MSGFMT_015@ +MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) +XGETTEXT_ = @XGETTEXT@ +XGETTEXT_no = @XGETTEXT@ +XGETTEXT_yes = @XGETTEXT_015@ +XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +MSGMERGE = msgmerge +MSGMERGE_UPDATE = @MSGMERGE@ --update +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +UPDATEPOFILES = @UPDATEPOFILES@ +DUMMYPOFILES = @DUMMYPOFILES@ +DISTFILES.common = Makefile.in.in remove-potcdate.sin \ +$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) +DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ +$(POFILES) $(GMOFILES) \ +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) + +POTFILES = \ + +CATALOGS = @CATALOGS@ + +# Makevars gets inserted here. (Don't remove this line!) + +.SUFFIXES: +.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update + +.po.mo: + @echo "$(MSGFMT) -c -o $@ $<"; \ + $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ + +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ + cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + +.sin.sed: + sed -e '/^#/d' $< > t-$@ + mv t-$@ $@ + + +all: all-@USE_NLS@ + +all-yes: stamp-po +all-no: + +# Ensure that the gettext macros and this Makefile.in.in are in sync. +CHECK_MACRO_VERSION = \ + test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ + || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ + exit 1; \ + } + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, stamp-po is a nop (i.e. a phony target). + +# stamp-po is a timestamp denoting the last time at which the CATALOGS have +# been loosely updated. Its purpose is that when a developer or translator +# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, +# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent +# invocations of "make" will do nothing. This timestamp would not be necessary +# if updating the $(CATALOGS) would always touch them; however, the rule for +# $(POFILES) has been designed to not touch files that don't need to be +# changed. +stamp-po: $(srcdir)/$(DOMAIN).pot + @$(CHECK_MACRO_VERSION) + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch stamp-po" && \ + echo timestamp > stamp-poT && \ + mv stamp-poT stamp-po; \ + } + +# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', +# otherwise packages like GCC can not be built if only parts of the source +# have been downloaded. + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +# The determination of whether the package xyz is a GNU one is based on the +# heuristic whether some file in the top level directory mentions "GNU xyz". +# If GNU 'find' is available, we avoid grepping through monster files. +$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed + if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \ + LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \ + else \ + LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \ + fi; \ + } | grep -v 'libtool:' >/dev/null; then \ + package_gnu='GNU '; \ + else \ + package_gnu=''; \ + fi; \ + if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_gnu}@PACKAGE@" \ + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + esac + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) \ + && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ + esac; \ + }; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + for file in $(DISTFILES.common) Makevars.template; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + for file in Makevars; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +install-data-no: all +install-data-yes: all + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +install-strip: install + +installdirs: installdirs-exec installdirs-data +installdirs-exec: +installdirs-data: installdirs-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi +installdirs-data-no: +installdirs-data-yes: + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: uninstall-exec uninstall-data +uninstall-exec: +uninstall-data: uninstall-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in $(DISTFILES.common) Makevars.template; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +uninstall-data-no: +uninstall-data-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +check: all + +info dvi ps pdf html tags TAGS ctags CTAGS ID: + +mostlyclean: + rm -f remove-potcdate.sed + rm -f stamp-poT + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f stamp-po $(GMOFILES) + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: + $(MAKE) update-po + @$(MAKE) dist2 +# This is a separate target because 'update-po' must be executed before. +dist2: stamp-po $(DISTFILES) + dists="$(DISTFILES)"; \ + if test "$(PACKAGE)" = "gettext-tools"; then \ + dists="$$dists Makevars.template"; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + dists="$$dists $(DOMAIN).pot stamp-po"; \ + fi; \ + if test -f $(srcdir)/ChangeLog; then \ + dists="$$dists ChangeLog"; \ + fi; \ + for i in 0 1 2 3 4 5 6 7 8 9; do \ + if test -f $(srcdir)/ChangeLog.$$i; then \ + dists="$$dists ChangeLog.$$i"; \ + fi; \ + done; \ + if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ + for file in $$dists; do \ + if test -f $$file; then \ + cp -p $$file $(distdir) || exit 1; \ + else \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + fi; \ + done + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + esac; \ + }; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: + +# Recreate Makefile by invoking config.status. Explicitly invoke the shell, +# because execution permission bits may not work on the current file system. +# Use @SHELL@, which is the shell determined by autoconf for the use by its +# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. +Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ + cd $(top_builddir) \ + && @SHELL@ ./config.status $(subdir)/$@.in po-directories + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/Makevars b/po/Makevars new file mode 100644 index 0000000..fbf0a76 --- /dev/null +++ b/po/Makevars @@ -0,0 +1,53 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --keyword=__ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Intel Corporation + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = "powertop@lists.01.org" + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = + +# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' +# context. Possible values are "yes" and "no". Set this to yes if the +# package uses functions taking also a message context, like pgettext(), or +# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. +USE_MSGCTXT = no + +# These options get passed to msgmerge. +# Useful options are in particular: +# --previous to keep previous msgids of translated messages, +# --quiet to reduce the verbosity. +MSGMERGE_OPTIONS = diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..b466978 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,45 @@ +# List of source files which contain translatable strings. + +src/calibrate/calibrate.cpp +src/cpu/abstract_cpu.cpp +src/cpu/cpu_core.cpp +src/cpu/cpu.cpp +src/cpu/cpu_linux.cpp +src/cpu/cpu_package.cpp +src/cpu/intel_cpus.cpp +src/cpu/intel_gpu.cpp +src/devices/ahci.cpp +src/devices/alsa.cpp +src/devices/devfreq.cpp +src/devices/device.cpp +src/devices/network.cpp +src/devices/rfkill.cpp +src/devices/runtime_pm.cpp +src/devices/usb.cpp +src/devlist.cpp +src/display.cpp +src/lib.cpp +src/lib.h +src/main.cpp +src/parameters/persistent.cpp +src/perf/perf_bundle.cpp +src/perf/perf.cpp +src/process/do_process.cpp +src/report/report.cpp +src/report/report-maker.h +src/tuning/bluetooth.cpp +src/tuning/ethernet.cpp +src/tuning/nl80211.h +src/tuning/runtime.cpp +src/tuning/tunable.cpp +src/tuning/tuning.cpp +src/tuning/tuningi2c.cpp +src/tuning/tuningsysfs.cpp +src/tuning/tuningusb.cpp +src/tuning/wifi.cpp +src/wakeup/waketab.cpp +src/wakeup/wakeup.cpp +src/wakeup/wakeup_ethernet.cpp +src/wakeup/wakeup_usb.cpp +traceevent/event-parse.h +traceevent/parse-utils.c diff --git a/po/bn_IN.po b/po/bn_IN.po new file mode 100644 index 0000000..1f083c0 --- /dev/null +++ b/po/bn_IN.po @@ -0,0 +1,1037 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# rajeshpro <rajeshdey606@gmail.com>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Bengali (India) (http://www.transifex.com/projects/p/PowerTOP/" +"language/bn_IN/)\n" +"Language: bn_IN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "সাময়িক ফাইল তৈরি করতে পারবেন না\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Calibrating: CPU usage on %i threads\n" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" +"Calibrating: সিপিইউ -র ওয়েকআপ ক্ষমতা গ্রহণ\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" +"কেলিবেটি ইউএসবি ডিভাইস\n" +"\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" +" ... ডিভাইস %s\n" +"\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" +"Calibrating রেডিও ডিভাইস\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" +"Calibrating বেকলাইট\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" +"Calibrating অলস\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" +"Calibrating: ডিস্ক ব্যবহার\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" +"পাওষ়ারটপ শক্তি অনুমান ক্রমাঙ্কন শুরু\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" +"পাওষ়ারটপ শক্তি অনুমান ক্রমাঙ্কন সমাপ্তি\n" +"\n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "" +"ক্রমাঙ্কন-র পরে প্যারামিটারগুলি:\n" +"\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "সিপিইউ প্যাকেজ %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "cpu 'র প্যাকেজ" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "সিপিইউ প্যাকেজ %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, c-format +msgid "Core %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:573 +#, c-format +msgid "GPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "সিপিইউ-র ব্যবহার" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "সিপিইউ-র ব্যবহার" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" +"cpu_idle ইভেন্ট কোনও অবস্থাষ় ফিরে আসেনি?\n" +"\n" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 polling" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "C0 সক্রিয়" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA সংযোগ: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA ডিস্ক: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 সক্রিয়" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Audio codec %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "অডিও কোডেক %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "ডিভাইস পরিসংখ্যান" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "The battery reports a discharge rate of %sW\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "System baseline power is estimated at %sW\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "" +"বিদ্যুৎ est. ব্যবহার ডিভাইস নাম\n" +"\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "" +" ব্যবহারের ডিভাইস নাম\n" +"\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "The battery reports a discharge rate of %sW\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "System baseline power is estimated at %sW\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "ব্যবহার" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "ডিভাইস পরিসংখ্যান" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "নেটওয়ার্ক ইন্টারফেস: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "রেডিও ডিভাইস: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "ডিভাইস পরিসংখ্যান" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "পিসিআই ডিভাইস: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "ইউএসবি ডিভাইস: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "ইউএসবি ডিভাইস: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "পরিদর্শন" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "অলস পরিসংখ্যান" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "কম্পাংক পরিসংখ্যান" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "ডিভাইস পরিসংখ্যান" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "প্রস্থান" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS / 2, টাচপ্যাড / কীবোর্ড / মাউস" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA নিয়ন্ত্রণ" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "ইন্টেল নির্মিত USB হাব" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "পাওষ়ারটপ অনুবাদ" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "রিফ্রেশ সময় আউট সেট করুন" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "ব্যবহার: পাওষ়ারটপ [বিকল্প]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "মোডে সঞ্চালিত " + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "একটি csv রিপোর্ট তৈরি কর " + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "\"ডিবাগ\" মোডে চালানো" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=ডেভনোড]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "পরিমাপের জন্য একটি Extech পাওয়ার বিশ্লেষক ব্যবহার" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "একটি এইচটিএমএল রিপোর্ট তৈরি কর " + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "[= পুনরাবৃত্তিও] প্রত্যেক পরীক্ষা চালাতে সময়ের সংখ্যা" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=সেকেন্ডস]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "'x' সেকেন্ডের জন্য একটি প্রতিবেদন তৈরি করুন" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "প্রিন্ট সংস্করণ সংক্রান্ত তথ্য" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "এই সাহায্য মেনু মুদ্রণ কর" + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "আরও সাহায্যের জন্য README পড়ুন দয়া করে" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "পাওষ়ারটপ মেমরি হয়ে গেছে । পাওষ়ারটপ বাতিল করছে" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" +"পরিমাপ গ্রহণ করতে প্রস্তুত \n" +"\n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "প্রতিটি %d সেকেন্ড(গুলি) এর একটি সময়কালের জন্য %d পরিমাপ(গুলি) গ্রহণ করছে\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "পাওষ়ারটপ " + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "" +"প্রস্থান করছে...\n" +"\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" +"debugfs মাউন্ট করতে ব্যর্থ!\n" +"\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "পাওষ়ারটপ বন্ধ হচেছ" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "" +"লোডকৃত %i আগের পরিমাপ\n" +"\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" +"PowerTOP %s 'perf' সাবসিস্টেম সমর্থন করতে কার্নেল প্রয়োজন বোধ করে\n" +"\n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "" +"কার্নেলে ছাপ বিন্দুর জন্য সমর্থন হিসেবে যত ভাল:\n" +"\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" +"আনুমানিক অবশিষ্ট সময় হল %i ঘন্টা, %i মিনিট\n" +"\n" +"\n" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "সারাংশ" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "ওষ়েকআপস/সেকেন্ড" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "জিপিইউ ops/সেকেন্ড" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "ভিএফএস OPS / সেকেন্ড এবং" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "সিপিইউ-র ব্যবহার" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "শক্তি অনুমান" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "ইভেন্টস / গুলি" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "বিভাগ" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "বিবরণ" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "ওষ়েকআপস/ গুলি" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "জিপিইউ ops/ গুলি" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "ডিস্ক IO / গুলি" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX ওষ়েকআপস/ গুলি" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "সফ্টওয়্যার পাওয়ার কনজিউমার্স রূপরেখা" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "ওষ়েকআপস/ গুলি" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "ব্যবহার" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "জিপিইউ ops/ গুলি" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "ওষ়েকআপস/ গুলি" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "সফ্টওয়্যার পাওয়ার কনজিউমার্স রূপরেখা" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "পাওষ়ারটপ অনুবাদ" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "পাওষ়ারটপ অনুবাদ" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "প্রিন্ট সংস্করণ সংক্রান্ত তথ্য" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "সাময়িক ফাইল তৈরি করতে পারবেন না\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "ভাল" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "খারাপ" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "অজানা" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "ব্লুটুথ ডিভাইসের ইন্টারফেস অবস্থা" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "ডিভাইস %sএর জন্য LAN অবস্থা অন কর" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Runtime PM for %s device %s" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s device %s has no runtime power management" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI Device %s has no runtime power management" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "পিসিআই ডিভাইস %sএর জন্য রানটাইম PM" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "অডিও কোডেকর অধিকার ব্যবস্থাপনা সক্রিয় করুন" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI পাহরাদার বন্ধ করা উচিত" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "সিপিইউ সময়-তালিকা নির্ধারণ ব্যবস্থার বিদ্যুৎ সচেতন" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "VM writeback সময়সীমা" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "সুরেলা " + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr " <ESC> থেকে প্রস্থান করুন | <Enter> টগল করুন সুরেলা | <r> উইন্ডো রিফ্রেশ করুন" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Runtime PM for %s device %s" + +#: ../src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s device %s has no runtime power management" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "অডিও কোডেকর অধিকার ব্যবস্থাপনা সক্রিয় করুন" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "অজানা ইউএসবি ডিভাইস %s.(%s: %s) এর জন্য Autosuspend" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "ইউএসবি ডিভাইস %s[%s] এর জন্য Autosuspend " + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Wireless Power Saving for interface %s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "ওষ়েকআপস/ গুলি" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr " <ESC> থেকে প্রস্থান করুন | <Enter> টগল করুন সুরেলা | <r> উইন্ডো রিফ্রেশ করুন" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "ডিভাইস %sএর জন্য LAN অবস্থা অন কর" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enable" +msgstr "সুরেলা " + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "ডিভাইস %sএর জন্য LAN অবস্থা অন কর" + +#~ msgid "Actual" +#~ msgstr "প্রকৃত" + +#~ msgid "Power Consumption Summary" +#~ msgstr "বিদ্যুত ব্যবহার সারাংশ" + +#~ msgid "GPU ops/second" +#~ msgstr "জিপিইউ ops/সেকেন্ড" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS ops/sec" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "ভিএফএস OPS / সেকেন্ড " + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "'ondemand' cpufreq গভর্নর ব্যবহার করছে" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=ফাইলনেইম]" diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 0000000..3f66c8e --- /dev/null +++ b/po/ca.po @@ -0,0 +1,975 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# capimans, 2012 +# Il_Tifossi <lluita_i_no_dorm@hotmail.com>, 2011 +# Juanma Hernández <juanmah@gmail.com>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Catalan (http://www.transifex.com/projects/p/PowerTOP/" +"language/ca/)\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "No es pot crear el fitxer temporal\n" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Calibrant: ús de CPU en %i discussions\n" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Calibrant: consum d'energia de l'encesa de CPU\n" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Calibrant dispositius USB\n" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... dispositiu %s\n" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Calibrant dispositius de ràdio\n" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Calibrant llum de fons\n" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Calibrant repòs\n" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Calibrant: ús de disc\n" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Iniciant calibrat d'estimació d'energia PowerTOP\n" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Finalitzant calibració d'estimació d'energia de PowerTOP\n" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Paràmetres després del calibrat:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr "" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "Paquet CPU %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "paquet cpu" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Paquet CPU %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, c-format +msgid "Core %d" +msgstr "" + +#: src/cpu/cpu.cpp:579 +#, c-format +msgid "GPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:602 +msgid "CPU" +msgstr "" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, c-format +msgid "CPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "l'event cpu_idle no ha retornat cap estat?\n" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 sondejant" + +#: src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 actiu" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "Connexió SATA: %s" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "Disc SATA: %s" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 actiu" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Còdec d'àudio %s: %s (%s)" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Còdec d'àudio %s: %s" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Estadístiques del dispositiu" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "La bateria reporta un nivell de descàrrega de %sW\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "La línia base d'energia del sistema està estimada en %sW\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Energia est. Ús Nom del dispositiu\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Ús Nom del dispositiu\n" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "La bateria reporta un nivell de descàrrega de %sW\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "La línia base d'energia del sistema està estimada en %sW\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Estadístiques del dispositiu" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Interfície de xarxa: %s(%s)" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Dispositiu de ràdio: %s" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Estadístiques del dispositiu" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "Dispositiu PCI: %s" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "Dispositiu USB: %s" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "Dispositiu USB: %s (%s)" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Informació general" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Estadístiques de repòs" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Estadístiques de freqüència" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Estadístiques del dispositiu" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "Surt" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Touchpad / Teclat / Ratolí" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "Controlador SATA" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel connectat a port USB" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP " + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "" + +#: src/main.cpp:138 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "sortint...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, c-format +msgid "modprobe msr failed\n" +msgstr "" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Últimes mesuracions de %i carregades\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s necessita que el kernel suporti el subsistema 'perf'\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "així com suport per a punts de seguiment en el kernel:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Potència estimada: %5.1f Potència mesurada: %5.1f Suma: %5.1f\n" +"\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP " + +#: src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "No es pot crear el fitxer temporal\n" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Bo" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Malament" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Desconegut" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Estat de la interfície del dispositiu Bluetooth" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Estat Wake-on-lan per a dispositiu %s" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Temps d'execució PM per %s dispositiu %s" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s dispositiu %s no té administració d'energia en el funcionament" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "El dispositiu PCI %s no té administració d'energia en temps d'execució" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "Temps d'execució PM per dispositiu PCI %s" + +#: src/tuning/runtime.cpp:80 +#, fuzzy, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "Temps d'execució PM per %s dispositiu %s" + +#: src/tuning/runtime.cpp:83 +#, fuzzy, c-format +msgid "Runtime PM for disk %s" +msgstr "Temps d'execució PM per %s dispositiu %s" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Habilita administració d'energia del còdec d'àudio" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "S'hauria d'apagar la vigilància NMI" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Planificador de CPU conscient d'energia" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "Temps límint de reescriptura VM" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Optimitzables" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "<ESC> Sortir | <ENTRAR> canvia optimitzable | <r> Actualitza finestra" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Temps d'execució PM per %s dispositiu %s" + +#: src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s dispositiu %s no té administració d'energia en el funcionament" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Habilita administració d'energia del còdec d'àudio" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Autosuspès per a dispositiu USB desconegut %s (%s:%s)" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Autosuspès per a dipositiu USB %s [%s]" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Estalvi d'energia sense cable per a interfície %s" + +#: src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "<ESC> Sortir | <ENTRAR> canvia optimitzable | <r> Actualitza finestra" + +#: src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Estat Wake-on-lan per a dispositiu %s" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enabled" +msgstr "Optimitzables" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Estat Wake-on-lan per a dispositiu %s" + +#~ msgid "Actual" +#~ msgstr "Autèntic" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "Dispositiu PCI: %s" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Utilitzant governador de la freqüència CPU 'ondemand'" diff --git a/po/cs_CZ.po b/po/cs_CZ.po new file mode 100644 index 0000000..18cc30a --- /dev/null +++ b/po/cs_CZ.po @@ -0,0 +1,1002 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Alois Nešpor <info@aloisnespor.info>, 2013 +# Otto Bříza <otto.briza@gmail.com>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/" +"PowerTOP/language/cs_CZ/)\n" +"Language: cs_CZ\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Nelze vytvořit dočasný soubor\n" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Kalibrace: CPU použito na %i vláken\n" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Kalibrace: spotřeba energie na probuzení CPU\n" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Kalibrace USB zařízení\n" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... zařízení %s \n" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Kalibrace radio zařízení\n" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Kalibrace podsvícení\n" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Kalibrace nečinnosti\n" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Kalibrace: užití disku \n" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Začínání kalibrace odhadování energie PowerTOP\n" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Ukončování kalibrace odhadování energie PowerTOP\n" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parametry po kalibraci:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(HW)" +msgstr " Jádro" + +#: src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(OS)" +msgstr " Jádro" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr " Jádro" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "cpu svazek %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "cpu svazek" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Balíček %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "Balíček" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Jádro %i" + +#: src/cpu/cpu.cpp:579 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:602 +#, fuzzy +msgid "CPU" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "cpu_idle událost nevrátila stav?\n" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" +"power nebo cpu_frequecny událost nevrátila žádný stav?\n" +"\n" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 sdílení" + +#: src/cpu/cpu_linux.cpp:242 +#, fuzzy, c-format +msgid " CPU(OS) %i" +msgstr " CPU %i" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr " CPU %i" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr " Balíček" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 aktivní" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA link: %s" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA disk: %s" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 aktivní" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Audio kodek %s: %s (%s)" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Audio kodek %s: %s" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Zařízení" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "Spotřeba při chodu na baterii: %sW\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Systém základního napájení je odhadován na %sW\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Energie zbývá Použití Jméno zařízení\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Použití Jméno zařízení\n" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "Spotřeba při chodu na baterii: %sW\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Systém základního napájení je odhadován na %sW\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Využití" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Zařízení" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Síťové rozhraní: %s (%s)" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Radio zařízení: %s" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Zařízení" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI Zařízení: %s" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB zařízení: %s" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB zařízení: %s (%s)" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Přehled" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Nečinné" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frekvence" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Zařízení" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "Konec" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Touchpad / Klávesnice / Myš" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA ovladač" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel vestavěný v USB hubu" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP verze" + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "Nastavit čas obnovení" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "Použití: powertop [VOLBY]" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "spustit powertop v kalibračním režimu" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "vytvoření csv hlášení" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "spustit v \"debug\" módu" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "[=devnode]" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "využití Extech Power Analyzéru pro měření" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "vytvoření html hlášení" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "[=iterace] počet spuštění každého testu" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "[=sekundy]" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "vytvoření hlášení pro \"x\" sekund" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "[=zatížení]" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "soubor ke spuštění pro zatížení" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "vypíše informace o verzi" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "vypíše tuto nápovědu" + +#: src/main.cpp:138 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Pro více nápovědy přejděte prosím do README" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "Neznámý problém při spuštění zatížení!\n" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTOPu došla paměť. Power TOP je přerušen." + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Příprava k měření\n" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "Změřeno %d výsledků za dobu trvání %d vteřin každý.\n" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "Měření zatížení %s.\n" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "ukončuji...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, fuzzy, c-format +msgid "modprobe msr failed\n" +msgstr "Selhal tichý mód!\n" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Selhalo připojení debugfs!\n" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, fuzzy, c-format +msgid "Quiet mode failed!\n" +msgstr "Selhal tichý mód!\n" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "Ukončuji PowerTOP" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Nelze uložit soubor" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Nelze načíst ze souboru" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "" +"Nahráno %i měření\n" +"\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s potřebuje jádro k podpoře 'perf' subsystému\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "stejně jako podpora pro sledované body v jádru:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Odhad energie: %5.1f Změřená energie: %5.1f Součet: %5.1f\n" +"\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "Odhadovaný zbývající čas do vybití baterie je %i hodin, %i minut\n" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Souhrn" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "probuzení/sekund" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU ops/sekund" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS ops/sec a" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "využití CPU" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Energie zbývá" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Událost/i" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Kategorie" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Popis" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Probuzení/s" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU ops/s" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Disk IO/s" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX Probuzení/s" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Přehled Software Power uživatelů" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Probuzení/s" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Využití" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU ops/s" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Probuzení/s" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Přehled Software Power uživatelů" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP verze" + +#: src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTOP verze" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "vypíše informace o verzi" + +#: src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Nelze vytvořit dočasný soubor\n" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Dobré" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Špatné" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Neznámé" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Status rozhraní zařízení Bluetooth" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Wake-on-lan status zařízení %s" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Runtime PM pro %s zařízení %s" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s zařízení %s nemá spustitelnou správu napájení" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI Zařízení %s nemá spustitelnou správu napájení" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "Trvání PM pro PCI zařízení %s" + +#: src/tuning/runtime.cpp:80 +#, fuzzy, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "Runtime PM pro %s zařízení %s" + +#: src/tuning/runtime.cpp:83 +#, fuzzy, c-format +msgid "Runtime PM for disk %s" +msgstr "Runtime PM pro %s zařízení %s" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Zapnout správu napájení audio kodeku" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "Hlídací pes NMI by měl být vypnutý" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Power Aware CPU plánovač" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "VM writeback timeout" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Možnosti vyladění" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr " <ESC> Konec | <Enter> Přepnout změnitelné | <r> Obnovit okno" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Runtime PM pro %s zařízení %s" + +#: src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s zařízení %s nemá spustitelnou správu napájení" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Zapnout správu napájení SATA linku pro %s" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Automatické uspání pro neznámé USB zařízení %s (%s:%s)" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Automatické uspání pro USB zařízení %s [%s]" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Úspora energie bezdrátových zařízení %s" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Probuzení/s" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr " <ESC> Konec | <Enter> Přepnout změnitelné | <r> Obnovit okno" + +#: src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Wake-on-lan status zařízení %s" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enabled" +msgstr "Možnosti vyladění" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Wake-on-lan status zařízení %s" + +#~ msgid "Actual" +#~ msgstr "Aktuální" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "PCI Zařízení: %s" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=JMENOSOUBORU]" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Užití 'ondemand' cpufreq regulátoru" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Souhrn spotřeby energie" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU ops/sekund" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS ops/sekund" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX probuzení/sek a" diff --git a/po/da_DK.po b/po/da_DK.po new file mode 100644 index 0000000..9301e91 --- /dev/null +++ b/po/da_DK.po @@ -0,0 +1,951 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Danish (Denmark) (http://www.transifex.com/projects/p/" +"PowerTOP/language/da_DK/)\n" +"Language: da_DK\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, c-format +msgid "package-%i" +msgstr "" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, c-format +msgid "Core %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:573 +#, c-format +msgid "GPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:594 +msgid "CPU" +msgstr "" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, c-format +msgid "CPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +msgid "Active" +msgstr "" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "" + +#: ../src/devices/devfreq.cpp:261 +msgid "Device Freq stats" +msgstr "" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "" + +#: ../src/devices/device.cpp:256 +msgid "The battery reports a discharge rate of: " +msgstr "" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +msgid "The system baseline power is estimated at: " +msgstr "" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: ../src/devices/device.cpp:278 +msgid "Device Name" +msgstr "" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +msgid "Device" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, c-format +msgid "PowerTOP version " +msgstr "" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "" + +#: ../src/main.cpp:137 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: ../src/report/report.cpp:122 +msgid "PowerTOP Version" +msgstr "" + +#: ../src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: ../src/report/report.cpp:195 +#, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, c-format +msgid "Enable SATA link power management for %s" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +msgid "Wake status of the devices" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Enable" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, c-format +msgid "Wake status for USB device %s" +msgstr "" diff --git a/po/de_DE.po b/po/de_DE.po new file mode 100644 index 0000000..66d894d --- /dev/null +++ b/po/de_DE.po @@ -0,0 +1,1011 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Ettore Atalan <atalanttore@googlemail.com>, 2012-2013 +# Fabian Affolter <fab@fedoraproject.org>, 2011 +# uhofemei <ulf.hofemeier@intel.com>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 19:48+0000\n" +"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n" +"Language-Team: German (Germany) (http://www.transifex.com/projects/p/" +"PowerTOP/language/de_DE/)\n" +"Language: de_DE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Temporäre Datei konnte nicht erzeugt werden\n" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Kalibriere CPU-Auslastung bei %i Thread\n" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Kalibriere CPU-Aufwach-Leistungsaufnahme\n" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Kalibriere USB-Geräte\n" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... Gerät %s\n" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Kalibriere Funkvorrichtungen\n" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Kalibriere Hintergrundbeleuchtung\n" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Kalibriere Leerlauf\n" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Kalibriere Festplattennutzung\n" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Starte Kalibrierung der PowerTOP-Leistungsschätzung\n" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Schließe Kalibrierung der PowerTOP-Leistungsschätzung ab\n" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parameter nach der Kalibrierung:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(HW)" +msgstr "Kern" + +#: src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(OS)" +msgstr "Kern" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr "Kern" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "CPU-Paket %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "CPU-Paket" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Paket %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "Paket" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Kern %i" + +#: src/cpu/cpu.cpp:579 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:602 +#, fuzzy +msgid "CPU" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "cpu_idle-Ereignis gab keinen Status zurück?\n" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "power- oder cpu_frequency-Ereignis gab kein Status zurück?\n" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 sammeln" + +#: src/cpu/cpu_linux.cpp:242 +#, fuzzy, c-format +msgid " CPU(OS) %i" +msgstr "CPU %i" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr "CPU %i" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "Paket" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 aktiv" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA-Verbindung: %s" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA-Festplatte: %s" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 aktiv" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Audiocodec %s: %s (%s)" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Audiocodec %s: %s" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Gerät-Statistiken" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "Die Batterie meldet eine Entladungsrate von %sW\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Leistungsaufnahme bei Grundauslastung beträgt %sW\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Gesch. Leistung Auslastung Gerätename\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Auslastung Gerätename\n" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "Die Batterie meldet eine Entladungsrate von %sW\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Leistungsaufnahme bei Grundauslastung beträgt %sW\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Auslastung" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Gerät-Statistiken" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Netzwerkschnittstelle: %s (%s)" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Funk-Gerät:%s" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Gerät-Statistiken" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI-Gerät: %s" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB-Gerät: %s" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB-Gerät: %s (%s)" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Übersicht" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Leerlauf-Statistiken" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frequenz-Statistiken" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Gerät-Statistiken" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "Beenden" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2-Tastfeld / Tastatur / Maus" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA-Controller" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel integrierter USB Hub" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP-Version" + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "Aktualisierungs-Zeitüberschreitung festlegen" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "Verwendung: powertop [OPTIONEN]" + +#: src/main.cpp:124 +#, fuzzy +msgid "sets all tunable options to their GOOD setting" +msgstr "Legt für alle einstellbaren Optionen die jeweils GUTE Einstellung fest" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "führt Powertop im Kalibrierungsmodus aus" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "Einen CSV-Bericht generieren" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "in \"Debug\"-Modus ausführen" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "[=Entwicklungsmodus]" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "verwendet einen Extech Leistungsanalysator für Messungen" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "Einen HTML-Bericht generieren" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "[=Wiederholungen] Anzahl der Wiederholungen für jeden Testlauf" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "stderr-Ausgabe unterdrücken" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "[=Sekunden]" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "Einen Bericht für 'x'-Sekunden generieren" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "[=Auslastung]" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "Für Auslastung auszuführende Datei" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "Versionsinformation ausgeben" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "Dieses Hilfemenü ausgeben" + +#: src/main.cpp:138 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Für weitere Hilfe ziehen Sie bitte die README zu Rate" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "Unbekanntes Ergebnis beim Ausführen der Arbeitsbelastung\n" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" +"PowerTOP hat keinen Speicherplatz mehr im Hauptspeicher. PowerTOP wird " +"abgebrochen" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Das Vornehmen von Messungen wird vorbereitet\n" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" +"%d Messung(en) mit einer Dauer von je %d Sekunde(n) wird/werden " +"vorgenommen.\n" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "Auslastung %s wird gemessen.\n" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "Verlassen ...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, c-format +msgid "modprobe msr failed\n" +msgstr "" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Das Einhängen von debugfs ist gescheitert!\n" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "PowerTOP wird verlassen" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Kann Datei nicht abspeichern" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Kann nicht von Datei laden" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "%i geladene vorherige Messungen\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" +"Zu viele offene Dateien. Bitte erhöhen Sie die Begrenzung von offenen " +"Dateideskriptoren.\n" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" +"PowerTOP %s benötigt einen Kernel der das 'perf'-Subsystem unterstützt\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "sowie Unterstützung für Ablaufverfolgungspunkte im Kernel:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Geschätzter Stromverbrauch: %5.1f Gemessener Stromverbrauch: %5.1f " +"Summe: %5.1f\\n\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "Die geschätzte Restzeit beträgt %i Stunden, %i Minuten\n" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Zusammenfassung" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "Aufwachvorgänge/Sekunde" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU-Operationen/Sekunde" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS-Operationen/Sekunde und" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "CPU-Nutzung" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Gesch. Leistung" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Ereignisse/s" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Kategorie" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Beschreibung" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Aufwachvorgänge/s" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU-Operationen/s" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Platten-Ein-/Ausgabe/s" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX-Aufwachvorgänge/s" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Übersicht der Software-Leistungsverbraucher" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Aufwachvorgänge/s" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Auslastung" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU-Operationen/s" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Aufwachvorgänge/s" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Übersicht der Software-Leistungsverbraucher" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP-Version" + +#: src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTOP-Version" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "Versionsinformation ausgeben" + +#: src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Temporäre Datei konnte nicht erzeugt werden\n" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Gut" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Schlecht" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Unbekannt" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Bluetooth-Gerät Schnittstellenstatus" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Wake-On-LAN-Status für Gerät %s" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Laufzeit-Energieverwaltung für %s Gerät %s" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s Gerät %s hat keine Energieverwaltung zur Laufzeit" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI-Gerät %s hat keine Energieverwaltung zur Laufzeit" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "Laufzeit-Energieverwaltung für PCI-Gerät %s" + +#: src/tuning/runtime.cpp:80 +#, fuzzy, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "Laufzeit-Energieverwaltung für %s Gerät %s" + +#: src/tuning/runtime.cpp:83 +#, fuzzy, c-format +msgid "Runtime PM for disk %s" +msgstr "Laufzeit-Energieverwaltung für %s Gerät %s" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Energieverwaltung für Audiocodec aktivieren" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI watchdog sollte ausgeschaltet sein" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Leistungsbewusster CPU-Scheduler" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "Zeitüberschreitung beim VM zurückschreiben" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Abstimmbare Optionen" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" +" <ESC> Beenden | <Enter> Abstimmbare Option umschalten | <r> Fenster " +"aktualisieren" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Laufzeit-Energieverwaltung für %s Gerät %s" + +#: src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s Gerät %s hat keine Energieverwaltung zur Laufzeit" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Energieverwaltung für SATA-Verbindung %s aktivieren" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "AutoSuspend für unbekanntes USB-Gerät %s (%s:%s)" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "AutoSuspend für USB-Gerät %s [%s]" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Drahtloses Stromsparen für Schnittstelle %s" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Aufwachvorgänge/s" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" +" <ESC> Beenden | <Enter> Abstimmbare Option umschalten | <r> Fenster " +"aktualisieren" + +#: src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Wake-On-LAN-Status für Gerät %s" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enabled" +msgstr "Abstimmbare Optionen" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Wake-On-LAN-Status für Gerät %s" + +#~ msgid "Actual" +#~ msgstr "Aktuell" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "PCI-Gerät: %s" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=DATEINAME]" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "CPU-Frequenzregler 'bei Bedarf' verwenden" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Zusammenfassung der Leistungsaufnahme" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU-Operationen/Sekunde" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS-Operationen/Sek" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX-Aufwachen/Sek und" diff --git a/po/en_GB.po b/po/en_GB.po new file mode 100644 index 0000000..f3b6c1e --- /dev/null +++ b/po/en_GB.po @@ -0,0 +1,967 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Margie Foster <margie@linux.intel.com>, 2012 +# Patrick McCarty <patrick.mccarty@linux.intel.com>, 2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/" +"PowerTOP/language/en_GB/)\n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr "" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "CPU package %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "CPU package" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "CPU package %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, c-format +msgid "Core %d" +msgstr "" + +#: src/cpu/cpu.cpp:579 +#, c-format +msgid "GPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:602 +msgid "CPU" +msgstr "" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, c-format +msgid "CPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 polling" + +#: src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 active" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 active" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Device stats" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "The battery reports a discharge rate of %sW\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "System baseline power is estimated at %sW\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Power est. Usage Device name\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "The battery reports a discharge rate of %sW\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "System baseline power is estimated at %sW\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Usage" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Device stats" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Device stats" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Overview" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Idle stats" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frequency stats" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Device stats" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Touchpad / Keyboard / Mouse" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA controller" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel built in USB hub" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, c-format +msgid "PowerTOP version " +msgstr "" + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "" + +#: src/main.cpp:138 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "" + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, c-format +msgid "modprobe msr failed\n" +msgstr "" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Loaded %i prior measurements\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "as well as support for trace points in the kernel:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Usage" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: src/report/report.cpp:122 +msgid "PowerTOP Version" +msgstr "" + +#: src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: src/report/report.cpp:195 +#, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: src/tuning/runtime.cpp:80 +#, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "" + +#: src/tuning/runtime.cpp:83 +#, c-format +msgid "Runtime PM for disk %s" +msgstr "" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: src/tuning/tuningsysfs.cpp:123 +#, c-format +msgid "Enable SATA link power management for %s" +msgstr "" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#: src/wakeup/waketab.cpp:170 +msgid "Wake status of the devices" +msgstr "" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Enabled" +msgstr "" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, c-format +msgid "Wake status for USB device %s" +msgstr "" + +#~ msgid "Actual" +#~ msgstr "Actual" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "Device stats" diff --git a/po/en_US.po b/po/en_US.po new file mode 100644 index 0000000..d84a26a --- /dev/null +++ b/po/en_US.po @@ -0,0 +1,972 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Dimitris Glezos <glezos@indifex.com>, 2011 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: English (United States) (http://www.transifex.com/projects/p/" +"PowerTOP/language/en_US/)\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Cannot create temp file\n" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Calibrating: CPU usage on %i threads\n" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Calibrating: CPU wakeup power consumption\n" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Calibrating USB devices\n" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... device %s \n" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Calibrating radio devices\n" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Calibrating backlight\n" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Calibrating idle\n" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Calibrating: disk usage \n" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Starting PowerTOP power estimate calibration \n" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Finishing PowerTOP power estimate calibration \n" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parameters after calibration:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr "" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "cpu package %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "cpu package" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "cpu package %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, c-format +msgid "Core %d" +msgstr "" + +#: src/cpu/cpu.cpp:579 +#, c-format +msgid "GPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:602 +msgid "CPU" +msgstr "" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, c-format +msgid "CPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 polling" + +#: src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 active" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA link: %s" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA disk: %s" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 active" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Audio codec %s: %s (%s)" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Audio codec %s: %s" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Device stats" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "The battery reports a discharge rate of %sW\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "System baseline power is estimated at %sW\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Power est. Usage Device name\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Usage Device name\n" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "The battery reports a discharge rate of %sW\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "System baseline power is estimated at %sW\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Device stats" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Network interface: %s (%s)" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Radio device: %s" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Device stats" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI Device: %s" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB device: %s" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB device: %s (%s)" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Overview" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Idle stats" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frequency stats" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Device stats" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Touchpad / Keyboard / Mouse" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA controller" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel built in USB hub" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP " + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "" + +#: src/main.cpp:138 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "exiting...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, c-format +msgid "modprobe msr failed\n" +msgstr "" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Loaded %i prior measurements\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "as well as support for trace points in the kernel:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP " + +#: src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Cannot create temp file\n" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Good" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Bad" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Unknown" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Bluetooth device interface status" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Wake-on-lan status for device %s" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Runtime PM for %s device %s" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s device %s has no runtime power management" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI Device %s has no runtime power management" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "Runtime PM for PCI Device %s" + +#: src/tuning/runtime.cpp:80 +#, fuzzy, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "Runtime PM for %s device %s" + +#: src/tuning/runtime.cpp:83 +#, fuzzy, c-format +msgid "Runtime PM for disk %s" +msgstr "Runtime PM for %s device %s" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Enable Audio codec power management" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI watchdog should be turned off" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Power Aware CPU scheduler" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "VM writeback timeout" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Tunables" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Runtime PM for %s device %s" + +#: src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s device %s has no runtime power management" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Enable Audio codec power management" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Autosuspend for unknown USB device %s (%s:%s)" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Autosuspend for USB device %s [%s]" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Wireless Power Saving for interface %s" + +#: src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#: src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Wake-on-lan status for device %s" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enabled" +msgstr "Tunables" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Wake-on-lan status for device %s" + +#~ msgid "Actual" +#~ msgstr "Actual" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "PCI Device: %s" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Using 'ondemand' cpufreq governor" diff --git a/po/es_CO.po b/po/es_CO.po new file mode 100644 index 0000000..84eb433 --- /dev/null +++ b/po/es_CO.po @@ -0,0 +1,951 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Spanish (Colombia) (http://www.transifex.com/projects/p/" +"PowerTOP/language/es_CO/)\n" +"Language: es_CO\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, c-format +msgid "package-%i" +msgstr "" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, c-format +msgid "Core %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:573 +#, c-format +msgid "GPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:594 +msgid "CPU" +msgstr "" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, c-format +msgid "CPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +msgid "Active" +msgstr "" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "" + +#: ../src/devices/devfreq.cpp:261 +msgid "Device Freq stats" +msgstr "" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "" + +#: ../src/devices/device.cpp:256 +msgid "The battery reports a discharge rate of: " +msgstr "" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +msgid "The system baseline power is estimated at: " +msgstr "" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: ../src/devices/device.cpp:278 +msgid "Device Name" +msgstr "" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +msgid "Device" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, c-format +msgid "PowerTOP version " +msgstr "" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "" + +#: ../src/main.cpp:137 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: ../src/report/report.cpp:122 +msgid "PowerTOP Version" +msgstr "" + +#: ../src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: ../src/report/report.cpp:195 +#, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, c-format +msgid "Enable SATA link power management for %s" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +msgid "Wake status of the devices" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Enable" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, c-format +msgid "Wake status for USB device %s" +msgstr "" diff --git a/po/es_ES.po b/po/es_ES.po new file mode 100644 index 0000000..8693c9a --- /dev/null +++ b/po/es_ES.po @@ -0,0 +1,980 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Andres <andreshko9@hotmail.com>, 2011 +# Patrick McCarty <patrick.mccarty@linux.intel.com>, 2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Spanish (Spain) (http://www.transifex.com/projects/p/PowerTOP/" +"language/es_ES/)\n" +"Language: es_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "No puede crear archivo temp\n" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Calibrando: uso de CPU en %i discusiones\n" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Calibrando: consumo de energía del despertado de la CPU\n" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Calibrando dispositivos USB\n" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... dispositivo %s \n" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Calibrando dispositivos de radio\n" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Calibrando luz trasera\n" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Calibrando parado\n" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Calibrando: uso de disco \n" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Iniciando calibración de estimado de energía PowerTOP \n" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Finalizando calibración de estimación de energía de PowerTOP \n" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parámetros tras calibración:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr "" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "package cpu %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "paquete cpu" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "package cpu %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, c-format +msgid "Core %d" +msgstr "" + +#: src/cpu/cpu.cpp:579 +#, fuzzy, c-format +msgid "GPU %d" +msgstr " CPU %i" + +#: src/cpu/cpu.cpp:602 +#, fuzzy +msgid "CPU" +msgstr " CPU %i" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, fuzzy, c-format +msgid "CPU %d" +msgstr " CPU %i" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 sondeando" + +#: src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 activo" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr " CPU %i" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "Enlace SATA: %s" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "Disco SATA: %s" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 activo" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Codec de audio %s: %s (%s)" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Codec de audio %s: %s" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Estadísticas del dispositivo" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "La batería reporta una tasa de descarga de %sW\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Linea base de energía del sistema es estimada en %sW\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Power est. Usage Device name\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Uso Nombre del dispositivo\n" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "La batería reporta una tasa de descarga de %sW\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Linea base de energía del sistema es estimada en %sW\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Estadísticas del dispositivo" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Interfaz de red: %s (%s)" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Dispositivo de radio: %s" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Estadísticas del dispositivo" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "Dispositivo PCI: %s" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "Dispositivo USB: %s" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "Dispositivo USB: %s (%s)" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Información general" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Estadísticas de parado" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Estadísticas de frecuencia" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Estadísticas del dispositivo" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "Salida" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Touchpad / Teclado / Ratón" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "Controlador SATA" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel construido en concentrador USB" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP " + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "Actualización Set time out" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "" + +#: src/main.cpp:138 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "saliendo...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, c-format +msgid "modprobe msr failed\n" +msgstr "" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Cargado %i medidas previas\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s necesita que el kernel soporte el subsistema 'perf'\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "así como soporte para puntos de seguimiento en el kernel:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Energía estimada: %5.1f Energía medida: %5.1f Sum: %5.1f\n" +"\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Resumen" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP " + +#: src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "No puede crear archivo temp\n" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Bueno" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Malo" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Desconocido" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Estado de la interfaz de dispositivo Bluetooth" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Estado Wake-on-lan para dispositivo %s" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Tiempo de ejecución PM para %s dispositivo %s" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" +"%s dispositivo %s no tiene administración de energía en tiempo de ejecución" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" +"Dispositivo PCI %s no tiene administración de energía en tiempo de ejecución" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "Tiempo de ejecución PM para dispositivo PCI %s" + +#: src/tuning/runtime.cpp:80 +#, fuzzy, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "Tiempo de ejecución PM para %s dispositivo %s" + +#: src/tuning/runtime.cpp:83 +#, fuzzy, c-format +msgid "Runtime PM for disk %s" +msgstr "Tiempo de ejecución PM para %s dispositivo %s" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Habilitar administración de energía del codec de Audio " + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "Vigilancia NMI se debe apagar" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Planificador de CPU Consciente de Energía " + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "Tiempo límite de reescritura VM" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Optimizables" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" +" Salida de <ESC>| <Enter>Palanca ajustable | Actualización de <r>ventana" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Tiempo de ejecución PM para %s dispositivo %s" + +#: src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" +"%s dispositivo %s no tiene administración de energía en tiempo de ejecución" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Habilitar administración de energía del codec de Audio " + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Autosuspender para dispositivo USB desconocido %s (%s:%s)" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Autosuspender para dispositivo USB %s [%s]" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Ahorro de Energía Wireless para interfaz %s" + +#: src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" +" Salida de <ESC>| <Enter>Palanca ajustable | Actualización de <r>ventana" + +#: src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Estado Wake-on-lan para dispositivo %s" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enabled" +msgstr "Optimizables" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Estado Wake-on-lan para dispositivo %s" + +#~ msgid "Actual" +#~ msgstr "Actual" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "Dispositivo PCI: %s" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Usando 'ondemand' cpufreq governor" diff --git a/po/fy.po b/po/fy.po new file mode 100644 index 0000000..44361f3 --- /dev/null +++ b/po/fy.po @@ -0,0 +1,992 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Sietse <sietse@vdmolen.eu>, 2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Western Frisian (http://www.transifex.com/projects/p/PowerTOP/" +"language/fy/)\n" +"Language: fy\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Kin gjin tydlike triem meitsje\\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Kalibrearjen: CPU gebrúk op %i threads\\n" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Kalibrearjen: CPU wakeup krêft gebrúk\\n" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "USB Apparaten oan it kalibrearjen\\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... apparaat %s \\n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Radio apparaten oan it kalibrearjen\\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Eftergrûnljocht oan it kalibrearjen\\n" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Kalibrearjen yn rêst\\n" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Kalibrearjen: skiff gebrúk\\n" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "PowerTOP krêft skatting kalibraasje wurd start\\n" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "PowerTOP krêft skatting kalibraasje wurd beëine\\n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parameters nei kalibraasje:\\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "cpu pakket %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "cpu pakket" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Pakket %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Kern %i" + +#: ../src/cpu/cpu.cpp:573 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "cpu_idle event hat gjin steat werom jûn?\\n" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 polling" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "C0 aktyf" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA ferbyning: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA skiif: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 aktyf" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Audio codec %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Audio codec %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "Apparaat statistiken" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "De batterij rapportearret in ûntladings snelheid fan %sW\\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Basiskrêft fan it systeem is skat op %sW\\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Skatte krêft bruk Apparaatnamme\\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "Bruk Apparaatnamme\\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "De batterij rapportearret in ûntladings snelheid fan %sW\\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Basiskrêft fan it systeem is skat op %sW\\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Gebrúk" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Apparaat statistiken" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Netwurk ynterface: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Radio apparaat: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Apparaat statistiken" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI Apparaat: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB apparaat: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB apparaat: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "Oersicht" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "Ûnbrûkt statistiken" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frekwinsje statistiken" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "Apparaat statistiken" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "Ôfslúte" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "0 mW" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Touchpad / Kaaiboerd / Mûs" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA stjoerder" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel ynbouwde USB hub" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP ferzje" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "Set ferfarskings tiid" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "Bruk: powertop [OPSJES]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "rint powertop yn kalibraasje stân" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "generearje in csv rapport" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "rin in \"debug\" stân" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=devnode]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "Bruket in Extech Power Analyzer foar mjittingen" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "generearje in html rapport" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "[=iterations] oantal kearen dat eltse test rinne moat" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "underdruk stderr útfier" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=sekondes]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "generearje in rapport foar 'x' sekonden" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "[=wurklading]" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "bestân om út te fieren foar wurklading" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "print ferzje ynformaasje" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "print dit help menu" + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Foar mear help, lês de README" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTOP hat gjin geheugen mear. PowerTOP stoppet" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Oan it klearmeitsjen om te mjitten\\n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "Nim %d mjitting(en) foar in duraasje fan %d sekonde(n) elts.\\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "Wurklading %s wurd mjitten.\\n" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "slút ôf...\\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Keppeljen fan debugfs mislearre!\\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "PowerTOP wurd ferlitten" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Kin net nei triem skriuwe" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Kin net fan triem lêze" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "%i eardere mjittingen laden\\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTop %s hat in kernel nedich dy't it 'perf' subsysteem stypet\\n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "en ek trasearingspunten yn de kernel:\\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "Skatte krêft: %5.1f Mjitten krêft: %5.1f Som: %5.1f\\n\\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "The skatte restearjende tiid is %i oeren, %i minuten\\n" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Gearfetting" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "wakeups/sekonde" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU ops/sekondes" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS ops/sek en" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "CPU gebrúk" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Krêft skatting" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Events/s" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Kategory" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Beskriuwing" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Wakeups/s" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU ops/s" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Disk IO/s" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX Wakeups/s" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Oersjoch fan Software Krêft Brûkers" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Wakeups/s" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Gebrúk" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU ops/s" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Wakeups/s" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Oersjoch fan Software Krêft Brûkers" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP ferzje" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTOP ferzje" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "print ferzje ynformaasje" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Kin gjin tydlike triem meitsje\\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Goed" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Min" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Unbekind" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Bluetooth apparaat ynterface status" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Wake-on-lan status foar apparaat %s" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Runtime PM foar %s apparaat %s" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s apparaat %s hat gjin runtime krêft regelder" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI Apparaat %s hat gjin runtime krêft regelder" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "Runtime KR for PCI Apparaat %s" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Skeakelje Audio codec krêft behearder yn" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI wachthûn soe útset wurde moatte" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "VM writeback timeout" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Ôfstellers" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "<ESC> Ôfslúte | <Enter> Skeakelje ôfsteller | <r> Ferfarskje skerm" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Runtime PM foar %s apparaat %s" + +#: ../src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s apparaat %s hat gjin runtime krêft regelder" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Skeakelje SATA link krêft behear yn foar %s" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Autosliepstân foan ûnbekind USB apparaat %s (%s:%s)" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Autosliepstân foar USB apparaat %s [%s]" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Triedleaze Krêft Sparring foar ynterface %s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Wakeups/s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "<ESC> Ôfslúte | <Enter> Skeakelje ôfsteller | <r> Ferfarskje skerm" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Wake-on-lan status foar apparaat %s" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enable" +msgstr "Ôfstellers" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Wake-on-lan status foar apparaat %s" + +#~ msgid "Actual" +#~ msgstr "Aktueel" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Krêft Bruk Oersjoch" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU ops/sekonde" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS ops/sek" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX wakes/sek en" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Brukt 'ondemand' cpufreq ynsteller" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=FILENAME]" diff --git a/po/hi.po b/po/hi.po new file mode 100644 index 0000000..5fa3bb7 --- /dev/null +++ b/po/hi.po @@ -0,0 +1,996 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# piyushkumarchauhan <piyushkumarchauhan@live.in>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Hindi (http://www.transifex.com/projects/p/PowerTOP/language/" +"hi/)\n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "अस्थायी फ़ाइल नहीं बना सकते\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "केलिब्रतिंग: सीपीयू की खपत %i है लड़ियाँ पे\n" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "केलिब्रतिंग: सीपीयू के सतर्क होने के समय की शक्ति की खपत\n" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "यूएसबी उपकरण केलिब्रेट हो रहे हैं\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "...उपकरण %s\n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "रेडियो उपकरण केलिब्रेट हो रहे हैं\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "बेकलाईट केलिब्रेट हो रहा है \n" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "निष्क्रिय केलिब्रेट हो रहा है\n" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "कलिब्रटिंग: डिस्क की खपत \n" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "PowerTOP की शक्ति का अनुमान का केलिब्रेसन सुरु हो रहा हैं\n" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "PowerTOP की शक्ति का अनुमान का केलिब्रेसन समाप्त हो रहा हैं\n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "केलिब्रेसन के बाद पैरामीटर्स:\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "सीपीयू पैकेज %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "सीपीयू पैकेज" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "सीपीयू पैकेज %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, c-format +msgid "Core %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:573 +#, c-format +msgid "GPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "सीपीयू उपयोग" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "सीपीयू उपयोग" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "cpu_idle की घटना ने किसी भी तरीके की स्थिति नहीं लोटायी है?\n" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 मतदान" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "C0 सक्रिय" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA कड़ी: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA डिस्क: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 सक्रिय" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "श्रव्य कोडेक %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "श्रव्य कोडेक %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr " उपकरण आँकड़े" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "" +"बैटरी रिपोर्ट कर रही हैं %sW की चुकौती दर\n" +"\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "प्रणाली आधारभूत शक्ति का अनुमान %sW से लगाया जा चूका हैं\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "शक्ति अनुमानित उपयोग उपकरण का नाम \n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "खपत उपकरण नाम\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "" +"बैटरी रिपोर्ट कर रही हैं %sW की चुकौती दर\n" +"\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "प्रणाली आधारभूत शक्ति का अनुमान %sW से लगाया जा चूका हैं\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "खपत" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr " उपकरण आँकड़े" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "संजाल अंतराफलक: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "रेडियो उपकरण: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr " उपकरण आँकड़े" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "पीसीआई उपकरण: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "यूएसबी उपकरण: %s " + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "यूएसबी उपकरण: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr " विवरण" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "निष्क्रिय आँकड़े" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr " आवृति आँकड़े" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr " उपकरण आँकड़े" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "बाहर निकलें" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "0 मेगावाट" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "पीएस/2 टचपैड / कुंजीपटल / माउस " + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA नियंत्रक" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "इंटेल में निर्मित यूएसबी हब " + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP संस्करण" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "ताज़ा करने के टाइम-आउट को नियत करें" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "खपत: पॉवरटॉप [विकल्प]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "पॉवरटॉप को केलिब्रेसन मोड में चलाता हैं" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "एक सीएसवी रिपोर्ट उत्पन्न करना" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "\"डिबग\" मोड में चलाये" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=devnode]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "माप के लिए एक Extech पावर विश्लेषक का उपयोग करता है" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "एक एचटीएमएल रिपोर्ट उत्पन्न करना" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "[=संतृप्ति] प्रत्येक परीक्षा को चलाने की संख्या" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=सेकण्ड्स]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "'x' सेकंड के लिए एक रिपोर्ट उत्पन्न करना" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "संस्करण जानकारी को छापें" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "इस सहायक मेन्यू को छापें" + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "अधिक सहायता के लिए कृपया रीडमी देखें" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTOP स्मृति से बाहर है. PowerTOP रद्द कर रहा है" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "माप लेने के लिए तैयार होना \n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "%d का माप लिया जा रहा है प्रत्येक %d सेकण्ड की अवधि के लिए.\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "बाहर हो रहे है ...\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Debugfs को आरोहित करने में असफल रहे!\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "PowerTOP को छोड़ना" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "%i पूर्व माप लोड किया जा चूका हैं \n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s को 'perf' उपतंत्र को समर्थन देने के लिए kernel की जरुरत होती है \n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "तथा kernel के ट्रेस अंक को समर्थन:\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "अनुमानित शक्ति: %5.1f मापित शक्ति: %5.1f जोड़: %5.1f\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "अनुमानित शेष समय %i घंटे, %i मिनट हैं \n" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "संक्षेप" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "वेकअप/सेकेंड" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU ऑप्स/सेकण्ड्स" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS ऑप्स/सेकंड और" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "सीपीयू उपयोग" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "शक्ति अनुमानित." + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "घटना/सेकेंड" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "श्रेणी" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "विवरण" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "वेकअप/सेकेंड" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU ऑप्स/सेकेंड" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "डिस्क IO/सेकेंड" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX वेकअप/सेकेंड" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "सॉफ्टवेयर बिजली उपभोक्ताओं का विवरण" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "वेकअप/सेकेंड" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "खपत" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU ऑप्स/सेकेंड" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "वेकअप/सेकेंड" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "सॉफ्टवेयर बिजली उपभोक्ताओं का विवरण" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP संस्करण" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTOP संस्करण" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "संस्करण जानकारी को छापें" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "अस्थायी फ़ाइल नहीं बना सकते\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "अच्छा" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "बुरा" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "अनजान" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "ब्लूटूथ उपकरण अंतराफलक की स्थिति" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "स्थानीय क्षेत्र तंत्र की स्थिति को उपकरण %s के लिए जागृत करना " + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "%s उपकरण %s के लिए PM कार्यावधि करे " + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s उपकरण %s के पास कार्यावधि शक्ति प्रबंधन नहीं हैं " + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "पीसीआई उपकरण %s के पास कार्यावधि शक्ति प्रबंधन नहीं हैं " + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "पीसीआई उपकरण %s के लिए PM कार्यावधि करे" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "श्रव्य कोडेक ऊर्जा प्रबंधन को सक्षम बनाए" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "एनएमआई पर निगरानी को बंद कर दिया जाएँ" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "पावर अवगत सीपीयू अनुसूचक " + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "VM को प्रतिलेखन करने का समय समाप्त " + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "ट्यून करने योग्य" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "<ESC> बाहर निकलें | <Enter> टॉगल tunable | <r> विंडो ताजा करे " + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "%s उपकरण %s के लिए PM कार्यावधि करे " + +#: ../src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s उपकरण %s के पास कार्यावधि शक्ति प्रबंधन नहीं हैं " + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "श्रव्य कोडेक ऊर्जा प्रबंधन को सक्षम बनाए" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "अज्ञात यूएसबी उपकरण के लिए स्वतःस्थगित होना %s (%s:%s) " + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "यूएसबी उपकरण के लिए स्वतःस्थगित होना %s [%s]" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "बेतार संप्रेषण शक्ति बचत के लिए अंतराफलक %s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "वेकअप/सेकेंड" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "<ESC> बाहर निकलें | <Enter> टॉगल tunable | <r> विंडो ताजा करे " + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "स्थानीय क्षेत्र तंत्र की स्थिति को उपकरण %s के लिए जागृत करना " + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enable" +msgstr "ट्यून करने योग्य" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "स्थानीय क्षेत्र तंत्र की स्थिति को उपकरण %s के लिए जागृत करना " + +#~ msgid "Actual" +#~ msgstr "वास्तविक" + +#~ msgid "Power Consumption Summary" +#~ msgstr "विद्युत उपभोग सारांश" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU ऑप्स/सेकेंड" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS ऑप्स/सेकेंड" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX वेक/सेकेंड और" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "'ondemand' सीपीयू आवृति नियन्त्रक का उपयोग" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=फ़ाइलनाम]" diff --git a/po/hu_HU.po b/po/hu_HU.po new file mode 100644 index 0000000..e9d985e --- /dev/null +++ b/po/hu_HU.po @@ -0,0 +1,1002 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# ceferron <chris.e.ferron@linux.intel.com>, 2012 +# Márton Németh <nemeth.marton@gmail.com>, 2012 +# Márton Németh <nm127@freemail.hu>, 2012 +# Zoltan Hoppár <hopparz@gmail.com>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/" +"PowerTOP/language/hu_HU/)\n" +"Language: hu_HU\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Nem tudok létrehozni ideiglenes fájlt\n" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Kalibrálás: CPU használtság %i szálon\n" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Kalibrálás: CPU felébredési teljesítményfelvétel\n" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "USB eszközök kalibrálása\n" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... %s eszköz \n" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Rádiós eszközök kalibrálása\n" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Háttérvilágítás kalibrálása\n" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Üresjárat kalibrálása\n" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Kalibrálás: lemezhasználat \n" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "PowerTop teljesítménybecslés kalibrálás indítása \n" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "PowerTop teljesítménybecslés-kalibrálás befejezése \n" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Paraméterek a kalibrálás után:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr "" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "CPU tok %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "CPU tok" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Csomag %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Mag %i" + +#: src/cpu/cpu.cpp:579 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:602 +#, fuzzy +msgid "CPU" +msgstr "CPU %i" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU %i" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "a CPU üresjáratesemény nem adott vissza állapotot?\n" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 ciklikus lekérdezés" + +#: src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 aktív" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA kapcsolat: %s" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA lemez: %s" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 aktív" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Hangkodek %s: %s (%s)" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Hangkodek %s: %s" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Eszközstatisztika" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "Az akkumulátor %sW kisülési sebességet jelent\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "%sW a rendszer becsült alapteljesítménye\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Becsült telj. Használat Eszköz név\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Használat Eszköz név\n" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "Az akkumulátor %sW kisülési sebességet jelent\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "%sW a rendszer becsült alapteljesítménye\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Használat" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Eszközstatisztika" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Hálózati csatoló: %s (%s)" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Rádiós eszköz: %s" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Eszközstatisztika" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI eszköz: %s" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB eszköz: %s" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB eszköz: %s (%s)" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Áttekintés" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Üresjárat-statisztika" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frekvenciastatisztika" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Eszközstatisztika" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "Kilépés" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 tapipad / billentyűzet / egér" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA vezérlő" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Beépített Intel USB hub" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP verzió" + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "Frissítés időkorlát leteltének beállítása" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "Használat: powertop [OPCIÓK]" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "a powertop futtatása kalibrációs módban" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "CSV jelentés készítése" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "futtatás hibakeresési módban" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "[=eszköznév]" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "Extech Power Analyzer eszköz használata a mérésekhez" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "HTML jelentés készítése" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "[=iterációk] ennyiszer fusson le minden egyes teszt" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "szabványos hibakimenet elnyomása" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "[=másodperc]" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "ennyi másodpercig készüljön a jelentés" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "[=terhelés]" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "végrehajtandó fájl a terheléshez" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "verzió-információ kiíratása" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "e súgó kiíratása" + +#: src/main.cpp:138 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "További információk a README fájlban találhatók" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "Nincs elég memória a PowerTOP-nak. A PowerTOP futása megszakad" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Előkészülés a mérések elvégzéséhez\n" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "%d darab, egyenként %d másodperces mérés készítése.\n" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "Terhelés mérése %s.\n" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "kilépés...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, c-format +msgid "modprobe msr failed\n" +msgstr "" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Nem tudtam csatolni a debugfs-t!\n" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "A PowerTOP elhagyása" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Nem lehet elmenteni a fájlba " + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Nem lehet betölteni a fájlból" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "%i korábbi mérés betöltve\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" +"A PowerTOP %s verziójának szüksége van arra, hogy a rendszermag támogassa a " +"„perf” alrendszert\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "valamint a nyomkövetési pontokra is a rendszermagban:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Becsült teljesítmény: %5.1f Mért teljesítmény: %5.1f Összeg: %5.1f\n" +"\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "Becsült hátralévő idő %i óra %i perc\n" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Összefoglalás" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "felébredés/másodperc" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU művelet/másodperc" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS művelet/másodperc" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "CPU használtság" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Becsült telj." + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Esemény/s" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Kategória" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Leírás" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Felébredés/s" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU művelet/s" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Lemez BK/s" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX felébredés/s" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Szofver teljesítményfogyasztók áttekintése" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Felébredés/s" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Használat" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU művelet/s" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Felébredés/s" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Szofver teljesítményfogyasztók áttekintése" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP verzió" + +#: src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTOP verzió" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "verzió-információ kiíratása" + +#: src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Nem tudok létrehozni ideiglenes fájlt\n" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Jó" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Rossz" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Ismeretlen" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Bluetooth eszközcsatoló állapota" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Felébredés hálózati eseményre (wake-on-lan) állapot a(z) %s eszközön" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Futásidejű energiagazdálkodás a(z) %s buszon és %s eszközön" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "A(z) %s busz %s eszközének nincs futásidejű energiagazdálkodása" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "A(z) %s PCI eszköznek nincs futásidejű energiagazdálkodása" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "Futásidejű energiagazdálkodás a(z) %s PCI eszközön" + +#: src/tuning/runtime.cpp:80 +#, fuzzy, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "Futásidejű energiagazdálkodás a(z) %s buszon és %s eszközön" + +#: src/tuning/runtime.cpp:83 +#, fuzzy, c-format +msgid "Runtime PM for disk %s" +msgstr "Futásidejű energiagazdálkodás a(z) %s buszon és %s eszközön" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "A hang kodek energiagazdálkodásának engedélyezése" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI felügyeletnek (watchdog) kikapcsolva kellene lennie" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Teljesítményt figyelembevevő CPU ütemező" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "VM visszaírás időtúllépése" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Hangolások" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr " <ESC> Kilépés | <Enter> Hangolás átkapcsolása | <r> Ablak frissítése" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Futásidejű energiagazdálkodás a(z) %s buszon és %s eszközön" + +#: src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "A(z) %s busz %s eszközének nincs futásidejű energiagazdálkodása" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "SATA link energiaszabályozás engedélyezése %s számára" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Automatikus felfüggesztés a(z) %s (%s:%s) ismeretlen USB eszközön" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Automatikus felfüggesztés a(z) %s [%s] USB eszközön" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Vezeték nélküli teljesítménymegtakarítás a(z) %s illesztőegységen" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Felébredés/s" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr " <ESC> Kilépés | <Enter> Hangolás átkapcsolása | <r> Ablak frissítése" + +#: src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Felébredés hálózati eseményre (wake-on-lan) állapot a(z) %s eszközön" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enabled" +msgstr "Hangolások" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Felébredés hálózati eseményre (wake-on-lan) állapot a(z) %s eszközön" + +#~ msgid "Actual" +#~ msgstr "Aktuális" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "PCI eszköz: %s" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=FÁJLNÉV]" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Igény szerinti (ondemand) cpufreq vezérlő használata" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Teljesítményfelvétel összefoglaló" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU művelet/másodperc" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS művelet/mp" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX felébredés/mp és" diff --git a/po/id_ID.po b/po/id_ID.po new file mode 100644 index 0000000..ef1d8c5 --- /dev/null +++ b/po/id_ID.po @@ -0,0 +1,997 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Andika Triwidada <andika@gmail.com>, 2012-2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/" +"PowerTOP/language/id_ID/)\n" +"Language: id_ID\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Tak bisa membuat berkas temp\n" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Kalibrasi: Pemakaian CPU pada %i thread \n" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Kalibrasi: Konsumsi daya CPU bangun \n" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Kalibrasi perangkat USB \n" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... perangkat %s \n" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Kalibrasi perangkat radio \n" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Kalibrasi cahaya latar \n" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Kalibrasi menganggur \n" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Kalibrasi: pemakaian disk \n" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Memulai kalibrasi estimasi daya PowerTop \n" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Mengakhiri kalibrasi estimasi daya PowerTop \n" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parameter setelah kalibrasi:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(HW)" +msgstr " Core" + +#: src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(OS)" +msgstr " Core" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr " Core" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "paket %i cpu" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "paket cpu" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Paket %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "Paket" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Core %i" + +#: src/cpu/cpu.cpp:579 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:602 +#, fuzzy +msgid "CPU" +msgstr "CPU %i" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU %i" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "kejadian cpu_idle tak mengembalikan keadaan?\n" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "kejadian power atau cpu_frequency tak mengembalikan keadaan?\n" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 polling" + +#: src/cpu/cpu_linux.cpp:242 +#, fuzzy, c-format +msgid " CPU(OS) %i" +msgstr " CPU %i" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr " CPU %i" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "Paket" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 aktif" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "Link SATA: %s" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "Disk SATA: %s" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 aktif" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Codec audio %s: %s (%s)" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Codec audio %s: %s" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Stat perangkat" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "Baterai melaporkan laju pengosongan %sW\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Daya baseline sistem diperkirakan %sW\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Est. daya Pakai Nama perangkat\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Pakai Nama perangkat\n" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "Baterai melaporkan laju pengosongan %sW\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Daya baseline sistem diperkirakan %sW\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Pakai" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Stat perangkat" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Antarmuka jaringa: %s (%s)" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Perangkat radio: %s" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Stat perangkat" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "Perangkat PCI: %s" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "Perangkat USB: %s" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "Perangkat USB: %s (%s)" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Ringkasan" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Stat menganggur" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Stat frekuensi" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Stat perangkat" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "Keluar" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Touchpad / Keyboard / Mouse" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "Pengendali SATA" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Hub USB built in Intel" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTop versi" + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "Tata tenggang waktu penyegaran" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "Cara pakai: powertop [OPSI]" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "jalankan powertop dalam mode kalibrasi" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "buat laporan csv" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "jalankan dalam mode \"debug\"" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "[=devnode]" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "pakai Extech Power Analyzer untuk pengukuran" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "buat laporan html" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "[=iterasi] berapa kali menjalankan tiap tes" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "redam keluaran stderr" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "[=detik]" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "buat laporan untuk 'x' detik" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "[=beban kerja]" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "berkas yang akan dieksekusi untuk beban kerja" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "cetak informasi versi" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "cetik menu bantuan ini" + +#: src/main.cpp:138 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Untuk bantuan lebih lanjut lihatlah README" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "Masalah tak dikenal saat menjalankan beban!\n" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTop kehabisan memori. PowerTop digugurkan." + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Bersiap melakukan pengkukuran\n" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "Melakukan %d pengukuran selama masing-masing %d detik.\n" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "Mengukur beban kerja %s.\n" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "keluar...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, fuzzy, c-format +msgid "modprobe msr failed\n" +msgstr "Mode hening gagal!\n" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Gagal mengait debugfs!\n" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, fuzzy, c-format +msgid "Quiet mode failed!\n" +msgstr "Mode hening gagal!\n" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "Meninggalkan PowerTop" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Tak bisa menyimpan ke berkas" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Tak bisa memuat dari berkas" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Dimuat %i pengukuran sebelumnya\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTop %s memerlukan kernel yang mendukung subsistem 'perf'\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "dan juga dukungan trace point dalam kernel:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Perkiraan daya: %5.1f Daya terukur: %5.1f Jumlah: %5.1f\n" +"\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "Perkiraan sisa waktu adalah %i jam, %i menit\n" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Ringkasan" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "bangun/detik" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "op GPU/detik" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "op VFS/detik" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "pakai CPU" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Est. daya" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Kejadian/d" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Kategori" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Deskripsi" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Bangun/d" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "Op GPU/d" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "IO Disk/d" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX Bangun/d" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Ringkasan Pemakai Daya Perangkat Lunak" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Bangun/d" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Pakai" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "Op GPU/d" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Bangun/d" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Ringkasan Pemakai Daya Perangkat Lunak" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTop versi" + +#: src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTop versi" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "cetak informasi versi" + +#: src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Tak bisa membuat berkas temp\n" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Baik" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Buruk" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Tak diketahui" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Status antarmuka perangkat Bluetooth" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Status wake-on-lan bagi perangkat %s" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "PM runtime bagi %s perangkat %s" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s perangkat %s tak memiliki manajemen daya runtime" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "Perangkat PCI %s tak memiliki manajemen daya runtime" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "PM runtime bagi Perangkat PCI %s" + +#: src/tuning/runtime.cpp:80 +#, fuzzy, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "PM runtime bagi %s perangkat %s" + +#: src/tuning/runtime.cpp:83 +#, fuzzy, c-format +msgid "Runtime PM for disk %s" +msgstr "PM runtime bagi %s perangkat %s" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Aktifkan manajemen daya codec audio" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "Watchdog NMI mesti dimatikan" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Scheduler CPU Sadar Daya" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "Tenggang waktu writeback VM" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Tunables" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr " <ESC> Keluar | <Enter> Jungkit tunable | <r> Segarkan jendela" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "PM runtime bagi %s perangkat %s" + +#: src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s perangkat %s tak memiliki manajemen daya runtime" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Fungsikan Manajemen daya link SATA bagi %s" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Suspensi otomatis bagi perangkat USB tak dikenal %s (%s:%s)" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Suspensi otomatis bagi perangkat USB %s [%s]" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Penghematan Daya Nirkabel bagi antarmuka %s" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Bangun/d" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr " <ESC> Keluar | <Enter> Jungkit tunable | <r> Segarkan jendela" + +#: src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Status wake-on-lan bagi perangkat %s" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enabled" +msgstr "Tunables" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Status wake-on-lan bagi perangkat %s" + +#~ msgid "Actual" +#~ msgstr "Aktual" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "Perangkat PCI: %s" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=NAMAFILE]" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Memakai governor cpufreq 'ondemand'" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Ringkasan Konsumsi Daya" + +#~ msgid "GPU ops/second" +#~ msgstr "Op GPU/detik" + +#~ msgid "VFS ops/sec" +#~ msgstr "Op VFS/det" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX bangu/det dan" diff --git a/po/it_IT.po b/po/it_IT.po new file mode 100644 index 0000000..a3164c7 --- /dev/null +++ b/po/it_IT.po @@ -0,0 +1,994 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Random_R, 2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Italian (Italy) (http://www.transifex.com/projects/p/PowerTOP/" +"language/it_IT/)\n" +"Language: it_IT\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Impossibile creare file temporaneo\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Calibrazione: uso CPU su %i threads\n" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Calibrazione: consumo energetico wakeup CPU\n" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Calibrazione dispositivi USB\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... dispositivo %s \n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Calibrazione dispositivi radio\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Calibrazione retroilluminazione\n" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Calibrazione idle\n" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Calibrazione: uso disco \n" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Avvio calibrazione stima energetica PowerTOP \n" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Termino calibrazione stima energetica PowerTOP \n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parametri dopo la calibrazione:\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(HW)" +msgstr " Core" + +#: ../src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(OS)" +msgstr " Core" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr " Core" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "pacchetto cpu %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "pacchetto cpu" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Pacchetto %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "Pacchetto" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Core %i" + +#: ../src/cpu/cpu.cpp:573 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "l'evento cpu_idle non ha riportato alcuno stato?\n" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 polling" + +#: ../src/cpu/cpu_linux.cpp:242 +#, fuzzy, c-format +msgid " CPU(OS) %i" +msgstr " CPU %i" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr " CPU %i" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr " Pacchetto" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "C0 attivo" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "Link SATA: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "Disco SATA: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 attivo" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Codec audio %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Codec audio %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "Stat. dispos." + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "La batteria riporta un tasso di scarica di %sW\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "La potenza di base del sistema è stimata sui %sW\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Potenza stim. Uso Nome dispositivo\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Uso Nome dispositivo\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "La batteria riporta un tasso di scarica di %sW\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "La potenza di base del sistema è stimata sui %sW\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Uso" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Stat. dispos." + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Interfaccia di rete: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Dispositivo Radio: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Stat. dispos." + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "Dispositivo PCI: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "Dispositivo USB: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "Dispositivo USB: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "Riepilogo" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "Stat. idle" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "Stat. frequenza" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "Stat. dispos." + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "Esci" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "0 mW" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "Touchpad / Tastiera / Mouse PS/2" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "Controller SATA" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Hub USB Intel integrato" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "Versione PowerTOP" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "Imposta time out del refresh" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "Uso: powertop [OPZIONI]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "avvia powertop in modalità calibrazione" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "genera un resoconto csv" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "avvia in modalità \"debug\"" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=devnode]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "usa un Analizzatore Energetico Extech per le misurazioni" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "genera un resoconto html" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "[=iterazioni] numero di esecuzioni per ogni test" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "sopprimi output stderr" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=secondi]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "genera un resoconto per 'x' secondi" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "stampa informazioni sulla versione" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "stampa questo menu di aiuto" + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Per ulteriore aiuto si prega di rivolgersi al README" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTOP non ha memoria disponibile. Uscita da PowerTOP" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Preparazione per il rilevamento delle misure\n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" +"Rilevamento di %d misurazione(i) per una durata di %d secondo(i) ciascuna.\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "uscita...\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Impossibile montare debugfs!\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "Uscita da PowerTOP" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Impossibile salvare nel file" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Impossibile caricare dal file" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Caricati %i prima delle misurazioni\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s richiede il kernel per supportare il sottosistema 'perf'\n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "e per supportare i trace points nel kernel:\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Potenza stimata: %5.1f Potenza misurata: %5.1f Som: %5.1f\n" +"\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "Il tempo rimanente stimato è di %i ore, %i minuti\n" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Riepilogo" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "wakeup/secondo" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU op/secondo" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS op/sec e" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "uso CPU" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Stima energetica" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Eventi/s" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Categoria" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Descrizione" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Wakeup/s" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU op/s" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Disco IO/s" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX Wakeup/s" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Wakeup/s" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Uso" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU op/s" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Wakeup/s" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "Versione PowerTOP" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "Versione PowerTOP" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "stampa informazioni sulla versione" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Impossibile creare file temporaneo\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Positivo" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Negativo" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Sconosciuto" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Stato interfaccia dispositivo bluetooth" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Stato wake-on-lan per il dispositivo %s" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "PM runtime per %s dispositivo %s" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s dispositivo %s non ha alcuna gestione energetica runtime" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "Il dispositivo PCI %s non ha alcuna gestione energetica runtime" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "PM runtime per il dispositivo PCI %s" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Abilitazione della gestione energetica dei codec audio" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI watchdog dovrebbe essere disattivato" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "Timeout del VM writeback" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Regolazioni" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr " <ESC> Esci | <Invio> Commuta regolazione | <r> Aggiorna finestra" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "PM runtime per %s dispositivo %s" + +#: ../src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s dispositivo %s non ha alcuna gestione energetica runtime" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Abilita gestione energetica link SATA per %s" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Autosospensione per il dispositivo USB sconosciuto %s (%s:%s)" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Autosospensione per il dispositivo USB %s [%s]" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Risparmio energetico del dispositivo senza fili per l'interfaccia %s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Wakeup/s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr " <ESC> Esci | <Invio> Commuta regolazione | <r> Aggiorna finestra" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Stato wake-on-lan per il dispositivo %s" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enable" +msgstr "Regolazioni" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Stato wake-on-lan per il dispositivo %s" + +#~ msgid "Actual" +#~ msgstr "Attuale" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Riepilogo Consumo Energetico" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU op/secondo" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS op/sec" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX wake/sec e" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Uso del regolatore \"ondemand\" della frequenza della CPU" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=NOMEFILE]" diff --git a/po/ja_JP.po b/po/ja_JP.po new file mode 100644 index 0000000..ff83211 --- /dev/null +++ b/po/ja_JP.po @@ -0,0 +1,951 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/" +"PowerTOP/language/ja_JP/)\n" +"Language: ja_JP\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, c-format +msgid "package-%i" +msgstr "" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, c-format +msgid "Core %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:573 +#, c-format +msgid "GPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:594 +msgid "CPU" +msgstr "" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, c-format +msgid "CPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +msgid "Active" +msgstr "" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "" + +#: ../src/devices/devfreq.cpp:261 +msgid "Device Freq stats" +msgstr "" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "" + +#: ../src/devices/device.cpp:256 +msgid "The battery reports a discharge rate of: " +msgstr "" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +msgid "The system baseline power is estimated at: " +msgstr "" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: ../src/devices/device.cpp:278 +msgid "Device Name" +msgstr "" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +msgid "Device" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, c-format +msgid "PowerTOP version " +msgstr "" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "" + +#: ../src/main.cpp:137 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: ../src/report/report.cpp:122 +msgid "PowerTOP Version" +msgstr "" + +#: ../src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: ../src/report/report.cpp:195 +#, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, c-format +msgid "Enable SATA link power management for %s" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +msgid "Wake status of the devices" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Enable" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, c-format +msgid "Wake status for USB device %s" +msgstr "" diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000..994ff20 --- /dev/null +++ b/po/ko.po @@ -0,0 +1,955 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Patrick McCarty <patrick.mccarty@linux.intel.com>, 2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Korean (http://www.transifex.com/projects/p/PowerTOP/language/" +"ko/)\n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "cpu 패키지 %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "cpu 패키지" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "cpu 패키지 %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, c-format +msgid "Core %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:573 +#, c-format +msgid "GPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:594 +msgid "CPU" +msgstr "" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, c-format +msgid "CPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +msgid "Active" +msgstr "" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "장치 통계" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "" + +#: ../src/devices/device.cpp:256 +msgid "The battery reports a discharge rate of: " +msgstr "" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +msgid "The system baseline power is estimated at: " +msgstr "" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "장치 통계" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "장치 통계" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "개요" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "유휴 통계" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "주파수 통계" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "장치 통계" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, c-format +msgid "PowerTOP version " +msgstr "" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "" + +#: ../src/main.cpp:137 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "로드 %i 사전 측정\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: ../src/report/report.cpp:122 +msgid "PowerTOP Version" +msgstr "" + +#: ../src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: ../src/report/report.cpp:195 +#, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "나쁜" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, c-format +msgid "Enable SATA link power management for %s" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +msgid "Wake status of the devices" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Enable" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, c-format +msgid "Wake status for USB device %s" +msgstr "" diff --git a/po/lt.po b/po/lt.po new file mode 100644 index 0000000..c1debf2 --- /dev/null +++ b/po/lt.po @@ -0,0 +1,993 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Simonas Kazlauskas <simonas@kazlauskas.me>, 2012-2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Lithuanian (http://www.transifex.com/projects/p/PowerTOP/" +"language/lt/)\n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" +"%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Negalima sukurti laikino failo\\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Kalibruojama: procesoriaus sąnaudos veikiant %i gijoms\\n" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Kalibruojama: procesoriaus pabudimų energijos sąnaudos\\n" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Kalibruojami USB įrenginiai\\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "… įrenginys %s\\n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Kalibruojami radijo imtuvai\\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Kalibruojamas apšvietimas\\n" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Kalibruojama neveika\\n" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Kalibruojama: disko naudojimas\\n" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Pradedama PowerTop energijos vertinimo kalibracija\\n" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Užbaigiama PowerTOP energijos vertinimo kalibracija\\n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parametrai po kalibracijos:\\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(HW)" +msgstr "Branduolys" + +#: ../src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(OS)" +msgstr "Branduolys" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "Branduolys" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "%i procesorių paketas" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "procesorių paketas" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "%i paketas" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "Paketas" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, fuzzy, c-format +msgid "Core %d" +msgstr "%i branduolys" + +#: ../src/cpu/cpu.cpp:573 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "%i vaizdo plokštė" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "%i procesorius" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "%i procesorius" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "cpu_idle įvykis negrąžino būsenos?\\n" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "power arba cpu_frequency įvykis negrąžino būsenos?\\n" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 laukia" + +#: ../src/cpu/cpu_linux.cpp:242 +#, fuzzy, c-format +msgid " CPU(OS) %i" +msgstr "%i procesorius" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "%i procesorius" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "Paketas" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "C0 aktyvus" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "%i vaizdo plokštė" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA sąsaja: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA diskas: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 aktyvus" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Garso kodekas %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Garso kodekas %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "Įrenginių statistika" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "Akumuliatorius praneša %sW išsikrovimo greitį\\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Apytikrė Sistemos bazinė energija yra %sW\\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Apytikrė energija Naudojimas Įrenginio vardas\\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "Sąnaudos Įrenginio pavadinimas\\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "Akumuliatorius praneša %sW išsikrovimo greitį\\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Apytikrė Sistemos bazinė energija yra %sW\\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Naudojimas" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Įrenginių statistika" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Tinklo sąsaja: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Radijo imtuvas: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Įrenginių statistika" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI įrenginys: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB įrenginys: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB įrenginys: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "Apžvalga" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "Neveikos statistika" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "Dažnių statistika" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "Įrenginių statistika" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "Išeiti" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "0 mW" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Jutiklinis kilimėlis / Klaviatūra / Pėlė" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA kontroleris" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Integruotas Intel USB centras" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP versija" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "Nustatyti atnaujimui skirtą laiką" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "Naudojimas: powertop [NUOSTATOS]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "leidžia powertop kalibravimo režimu" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "generuoti raportą csv formatu" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "paleisti derinimo režimu" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=įrenginio mazgas]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "Matavimams naudojamas Extech energijos analizatorius" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "generuoti raportą html formatu" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "[=iteracijos] kiekvieno testo atlikimų skaičius" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "Užtildyti stderr išvestį" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=sekundės]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "generuoti x sekundžių raportą" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "[=apkrova]" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "Failas kurį vykdyti apkrovai" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "spausdinti informaciją apie versiją" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "spausdina šį pagalbos pranešimą" + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Daugiau pagalbos ieškokite README faile" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "Nežinoma klaida vykdant apkrovą!\\n" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTOP neužtenka atminties. PowerTOP išjungiamas" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Ruošiamasi matavimams\\n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "Imami %d matavimas(–ai) kas %d sekundę(–es).\\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "Skaičiuojama apkrova %s.\\n" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "išjungiama...\\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Nepavyko prijungti debugfs!\\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, fuzzy, c-format +msgid "Quiet mode failed!\n" +msgstr "Tylusis režimas nepavyko!\\n" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "PowerTOP išjungiamas" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Nepavyko išsaugoti į failą" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Nepavyko įkelti iš failo" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Įkelti %i ankstesni matavimai\\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s reikalingas 'perf' posistemės\\n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "ir sekimo taškų palaikymas branduolyje:\\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "Apytikrė energija: %5.1f Pamatuota energija: %5.1f Suma: %5.1f\\n\\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "Apskaičiuotas likęs laikas – %i valandos ir %i minutės\\n" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Santrauka" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "pabudimai/sekundę" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "Grafikos posistemės operacijos/sekundes" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "Virtualios failų sistemos operacijos/sek ir" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "Procesoriaus naudojimas" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Energijos įvertis" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Įvykiai/s" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Kategorija" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Aprašymas" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Pabudimai/s" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "Grafikos posistemės operacijos/s" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Disko operacijos/s" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX pabudimai/s" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Programinės įrangos energijos naudojimo apžvalga" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Pabudimai/s" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Naudojimas" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "Grafikos posistemės operacijos/s" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Pabudimai/s" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Programinės įrangos energijos naudojimo apžvalga" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP versija" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTOP versija" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "spausdinti informaciją apie versiją" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Negalima sukurti laikino failo\\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Gerai" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Blogai" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Nežinoma" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Bluetooth įrenginio sąsajos būsena" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Wake-on-lan būsena įrenginiui %s" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "%s įrengnio %s energijos valdymas jo veikimo metu" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s įrenginys %s neturi energijos valdymo veikimo metu" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI įrenginys %s neturi energijos valdymo veikimo metu" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "PCI įrenginio %s energijos valdymas jo veikimo metu" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Įjungti garso kodekų energijos valdymą" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI kontrolierius turėtų būti išjungtas" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Energijos sąnaudas suprantantis procesoriaus valdytojas" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "Laikas iki virtualiosios mašinos kešo išrašymo" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Deriniai" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "<ESC> Išeiti | <Enter> Perjungti derinį | <r> Perkrauti langą" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "%s įrengnio %s energijos valdymas jo veikimo metu" + +#: ../src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s įrenginys %s neturi energijos valdymo veikimo metu" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Įjungti SATA sąsajos energijos valdymą %s" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Automatinis nežinomo USB įrenginio %s (%s:%s) užmigdymas" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Automatinis USB įrenginio %s [%s] užmigdymas" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Energijos saugojimas bevielio ryšio įrenginiui %s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Pabudimai/s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "<ESC> Išeiti | <Enter> Perjungti derinį | <r> Perkrauti langą" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Wake-on-lan būsena įrenginiui %s" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enable" +msgstr "Deriniai" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Wake-on-lan būsena įrenginiui %s" + +#~ msgid "Actual" +#~ msgstr "Tikrasis" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Energijos sąnaudų aprašymas" + +#~ msgid "GPU ops/second" +#~ msgstr "Grafikos posistemės operacijos/sekundę" + +#~ msgid "VFS ops/sec" +#~ msgstr "Virtualios failų sistemos operacijos/sek" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX pabudimai/sek ir" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Naudojamas 'ondemand' cpufreq valdytojas" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=FAILO VARDAS]" diff --git a/po/nl_NL.po b/po/nl_NL.po new file mode 100644 index 0000000..d333e20 --- /dev/null +++ b/po/nl_NL.po @@ -0,0 +1,967 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# auke <auke-jan.h.kok@intel.com>, 2012 +# JanCeuleers <jan.ceuleers@computer.org>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Dutch (Netherlands) (http://www.transifex.com/projects/p/" +"PowerTOP/language/nl_NL/)\n" +"Language: nl_NL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parameters na calibratie:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr "" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "cpu package %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "cpu package" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "cpu package %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, c-format +msgid "Core %d" +msgstr "" + +#: src/cpu/cpu.cpp:579 +#, c-format +msgid "GPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:602 +msgid "CPU" +msgstr "" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, c-format +msgid "CPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 polling" + +#: src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 active" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 active" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "Apparaat stats" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "" + +#: src/devices/device.cpp:256 +msgid "The battery reports a discharge rate of: " +msgstr "" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +msgid "The system baseline power is estimated at: " +msgstr "" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Apparaat stats" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Apparaat stats" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "Overzicht" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "Rust stats" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frekwentie stats" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "Apparaat stats" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP" + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "Stel verversingstijd in" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "" + +#: src/main.cpp:138 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Voorbereiding om metingen te nemen\n" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP" + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "afsluiten...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, c-format +msgid "modprobe msr failed\n" +msgstr "" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Kan debugfs niet aankoppelen!\n" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "%i eerdere metingen ingeladen\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP" + +#: src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: src/report/report.cpp:195 +#, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Goed" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Slecht" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Onbekend" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: src/tuning/runtime.cpp:80 +#, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "" + +#: src/tuning/runtime.cpp:83 +#, c-format +msgid "Runtime PM for disk %s" +msgstr "" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Audio codec energiebeheer inschakelen" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI watchdog is beter uitgeschakeld" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Audio codec energiebeheer inschakelen" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#: src/wakeup/waketab.cpp:170 +msgid "Wake status of the devices" +msgstr "" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Enabled" +msgstr "" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, c-format +msgid "Wake status for USB device %s" +msgstr "" + +#~ msgid "Actual" +#~ msgstr "Huidig" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "Apparaat stats" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "'ondemand' cpufreq governor in gebruik" diff --git a/po/pl_PL.po b/po/pl_PL.po new file mode 100644 index 0000000..38e76ab --- /dev/null +++ b/po/pl_PL.po @@ -0,0 +1,991 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Michal Plichta <mplichta@gmail.com>, 2013 +# kostur86 <m.kosturek@gmail.com>, 2013 +# kostur86 <m.kosturek@gmail.com>, 2012 +# Michal Plichta <mplichta@gmail.com>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Polish (Poland) (http://www.transifex.com/projects/p/PowerTOP/" +"language/pl_PL/)\n" +"Language: pl_PL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Nie można utworzyć pliku tymczasowego\\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Kalibracja urządzeń USB\\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "... urządzenie %s \\n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Kalibracja urządzeń radiowych\\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Zakończenie PowerTOP po zebraniu estymaty mocy\\n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parametry po kalibracji:\\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(HW)" +msgstr "Rdzeń" + +#: ../src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(OS)" +msgstr "Rdzeń" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "Rdzeń" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "pakiet cpu %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "pakiet cpu" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Pakiet %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "Paczka" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Jądro %i" + +#: ../src/cpu/cpu.cpp:573 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 polling" + +#: ../src/cpu/cpu_linux.cpp:242 +#, fuzzy, c-format +msgid " CPU(OS) %i" +msgstr "CPU %i" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "CPU %i" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "Paczka" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "C0 aktywny" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "Łącze SATA: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "Dysk SATA: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 aktywny" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Kodek audio %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Kodek audio %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "Statystyki urządzeń" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "Tempo rozładowywania baterii: %sW \\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Bazową moc systemu oszacowano na %sW \\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Szac. moc Użycie Nazwa urządzenia \\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Użycie Nazwa urządzenia \\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "Tempo rozładowywania baterii: %sW \\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Bazową moc systemu oszacowano na %sW \\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Użycie" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Statystyki urządzeń" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Interfejs sieciowy: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Urządzenie radiowe: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Statystyki urządzeń" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "Urządzenie PCI: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "Urządzenie USB: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "Urządzenie USB: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "Przegląd" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "Stan jałowy" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "Statystyki częstotliwości" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "Statystyki urządzeń" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "Wyjście" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "0 mW" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Touchpad / Klawiatura / Mysz" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "kontroler SATA" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel wbudowany w hub USB" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "Wersja PowerTOP" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "Ustaw czas odświerzania" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "Użycie: powertop [OPTIONS]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "uruchom powertop w trybie kalibracji" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "generuje raport csv" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "uruchom w trybie \"debug\"" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=devnode]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "do pomiarów użyj Extech Power Analyzer" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "generuje raport html" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr " [=iteracji] liczba powtórzeń każdego testu" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=sekund]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "generuje raport dla 'x' sekund" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "[=obciążenie]" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "wypisz informacje o wersji" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "wypisuje tę informację " + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Więcej pomocy znajduje się w pliku README" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "Brak pamięci. PowerTop kończy działanie" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Przygotowywanie to pomiarów\\n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "Wykonywanie %d pomiaru(ów) o długości %d sekund(y) każdy \\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "wychodzenie...\\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Błąd montowania debugfs!\\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "Zamykanie PowerTop" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Nie można zapisać do pliku" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Nie można załadować z pliku" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Wczytano %i poprzednich pomiarów \\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s wymaga aby kernel wspierał narzędzie 'perf' \\n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "tak jak wsparcie kernela dla tracepoit-ów: \\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "Moc szacunkowa: %5.1f Moc zmierzona: %5.1f Suma: %5.1f\\n\\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Podsumowanie" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "Pobudki/sekunda" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU operacji/sekunde" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS operacji/sek i" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "Zużywanie CPU" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Estymacja mocy" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Zdarzenie/nia" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Kategoria" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Opis" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Pobutka/i" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GUP opercji/s" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Wejścia/Wyjścia dysku" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX Wakeups/s" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Przedląd programowych odbiorników energii" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Pobutka/i" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Użycie" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GUP opercji/s" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Pobutka/i" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Przedląd programowych odbiorników energii" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "Wersja PowerTOP" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "Wersja PowerTOP" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "wypisz informacje o wersji" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Nie można utworzyć pliku tymczasowego\\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Dobrze" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Źle" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Nieznany" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Status interfejsu urządzenia Bluetooth" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Status Wake-on-lan dla urządzenia %s" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Zarządzanie zasilaniem kodeka audio włączone" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "Watchdog NMI powinien być wyłączony" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Zarządzanie zasilaniem kodeka audio włączone" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Bezprzewodowe oszczędzanie energii dla interfejsu %s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Pobutka/i" + +#: ../src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Status Wake-on-lan dla urządzenia %s" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Enable" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Status Wake-on-lan dla urządzenia %s" + +#~ msgid "Actual" +#~ msgstr "rzeczywisty" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Podsumowanie poboru mocy" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU ops/sekundę" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS ops/sec" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX wakes/sec i" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=NAZWAPLIKU]" diff --git a/po/powertop.pot b/po/powertop.pot new file mode 100644 index 0000000..a708e67 --- /dev/null +++ b/po/powertop.pot @@ -0,0 +1,949 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the powertop package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: powertop 2.15\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr "" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, c-format +msgid "package-%i" +msgstr "" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, c-format +msgid "Core %d" +msgstr "" + +#: src/cpu/cpu.cpp:579 +#, c-format +msgid "GPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:602 +msgid "CPU" +msgstr "" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, c-format +msgid "CPU %d" +msgstr "" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "" + +#: src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +msgid "Active" +msgstr "" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "" + +#: src/devices/devfreq.cpp:260 +msgid "Device Freq stats" +msgstr "" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "" + +#: src/devices/device.cpp:256 +msgid "The battery reports a discharge rate of: " +msgstr "" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +msgid "The system baseline power is estimated at: " +msgstr "" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "" + +#: src/devices/device.cpp:278 +msgid "Device Name" +msgstr "" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +msgid "Device" +msgstr "" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, c-format +msgid "PowerTOP version " +msgstr "" + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "" + +#: src/main.cpp:138 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "" + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, c-format +msgid "modprobe msr failed\n" +msgstr "" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, c-format +msgid "% usage" +msgstr "" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: src/report/report.cpp:122 +msgid "PowerTOP Version" +msgstr "" + +#: src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: src/report/report.cpp:195 +#, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: src/tuning/runtime.cpp:80 +#, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "" + +#: src/tuning/runtime.cpp:83 +#, c-format +msgid "Runtime PM for disk %s" +msgstr "" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: src/tuning/tuningsysfs.cpp:123 +#, c-format +msgid "Enable SATA link power management for %s" +msgstr "" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: src/wakeup/waketab.cpp:42 +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "" + +#: src/wakeup/waketab.cpp:170 +msgid "Wake status of the devices" +msgstr "" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Enabled" +msgstr "" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, c-format +msgid "Wake status for USB device %s" +msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 0000000..16a7425 --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,999 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Nelson A. de Oliveira <naoliv@debian.org>, 2013 +# Nelson A. de Oliveira <naoliv@gmail.com>, 2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/" +"PowerTOP/language/pt_BR/)\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Impossível criar arquivo temporário\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Calibrando: uso de CPU em %i threads\n" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Calibrando: consumo de energia de ativação da CPU\n" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Calibrando dispositivos USB\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... dispositivo %s \n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Calibrando dispositivos de rádio\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Calibrando luz de fundo\n" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Calibrando inatividade\n" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Calibrando: uso de disco \n" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Iniciando calibração de estimativa de consumo \n" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Finalizando calibração de estimativa de consumo \n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Parâmetros após calibração:\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "pacote cpu %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "pacote cpu" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Pacote %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Núcleo %i" + +#: ../src/cpu/cpu.cpp:573 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "evento cpu_idle não retornou estado?\n" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 ativo" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "C0 ativo" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "Link SATA: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "Disco SATA: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 ativo" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Coded de áudio %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Codec de áudio %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "Dispositivos" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "A bateria relata uma taxa de descarga de %sW\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Consumo básico do sistema estimado em %sW\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Consumo Uso Dispositivo\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Uso Dispositivo\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "A bateria relata uma taxa de descarga de %sW\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Consumo básico do sistema estimado em %sW\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Uso" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Dispositivos" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Interface de rede: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Dispositivo de rádio: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Dispositivos" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "Dispositivo PCI: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "Dispositivo USB: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "Dispositivo USB: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "Geral" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "Estados" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frequências" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "Dispositivos" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "Sair" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "Touchpad PS/2 / Teclado / Mouse" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "Controlador SATA" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Hub USB interno Intel" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP versão" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "Definir timeout de atualização" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "Uso: powertop [OPÇÕES]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "executa o powertop em modo de calibração" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "gera um relatório CSV" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "executar em modo \"debug\"" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=dispositivo]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "utiliza um analisador Extech para as medições" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "gera um relatório HTML" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "[=iterações] número de vezes para executar cada teste" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "suprime saída stderr" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=segundos]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "gera um relatório para 'x' segundos" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "[=carga]" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "arquivo a ser executado para a carga de trabalho" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "exibe informação da versão" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "exibe este menu de ajuda" + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Para obter mais ajuda consulte o README, por favor" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTOP está sem memória. PowerTOP está abortando" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Preparando para medições\n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "Obtendo %d medição(ões) com duração de %d segundo(s) cada.\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "Medindo carga %s.\n" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "saindo...\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Falha ao montar debugfs!\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "Saindo do PowerTOP" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Impossível salvar no arquivo" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Impossível carregar o arquivo" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Carregadas %i medições anteriores\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s necessita que o kernel suporte o subsistema 'perf'\n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "assim como suporte para 'tracepoints' no kernel:\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Energia estimada: %5.1f Energia medida: %5.1f Soma: %5.1f\n" +"\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "O tempo estimado restante é de %i horas, %i minutos\n" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Sumário" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "ativações/s" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "ops/s GPU" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "ops/s VFS e" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "de uso de CPU" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Est. energia" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Eventos/s" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Categoria" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Descrição" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Ativações/s" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU ops/s" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Disco ES/s" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "Ativações/s GFX" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Visão geral de software consumidores de energia" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Ativações/s" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Uso" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU ops/s" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Ativações/s" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Visão geral de software consumidores de energia" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP versão" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTOP versão" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "exibe informação da versão" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Impossível criar arquivo temporário\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Bom" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Ruim" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Desconhecido" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Status da interface do dispositivo bluetooth" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Status do wake-on-lan para o dispositivo %s" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "Gerenciamento de energia em tempo de execução para %s dispositivo %s" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" +"%s dispositivo %s não possui gerenciamento de energia em tempo de execução" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" +"Dispositivo PCI %s não possui gerenciamento de energia em tempo de execução" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" +"Gerenciamento de energia em tempo de execução para o dispositivo PCI %s" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Habilitar gerenciamento de energia do codec de áudio" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "O watchdog NMI deve ser desligado" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Escalonador de CPU voltado à economia de energia" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "Timeout de escrita da VM" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Ajustes" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "<ESC> Sair | <Enter> Alternar ajuste | <r> Atualizar janela" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "Gerenciamento de energia em tempo de execução para %s dispositivo %s" + +#: ../src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" +"%s dispositivo %s não possui gerenciamento de energia em tempo de execução" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Habilitar gerenciamento de energia da conexão SATA para %s" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Suspensão automática para dispositivo USB desconhecido %s (%s:%s)" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Suspensão automática para dispositivo USB %s [%s]" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Economia de energia para interface wireless %s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Ativações/s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "<ESC> Sair | <Enter> Alternar ajuste | <r> Atualizar janela" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Status do wake-on-lan para o dispositivo %s" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enable" +msgstr "Ajustes" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Status do wake-on-lan para o dispositivo %s" + +#~ msgid "Actual" +#~ msgstr "Atual" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Sumário de Consumo de Energia" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU ops/s" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS ops/s" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "ativações/s GFX e" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Usando o regulador de frequência 'ondemand'" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=ARQUIVO]" diff --git a/po/ru_RU.po b/po/ru_RU.po new file mode 100644 index 0000000..d19d464 --- /dev/null +++ b/po/ru_RU.po @@ -0,0 +1,996 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# JIghtuse <jightuse@gmail.com>, 2013 +# JIghtuse <jightuse@gmail.com>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/" +"PowerTOP/language/ru_RU/)\n" +"Language: ru_RU\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "Невозможно создать временный файл\\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "Калибровка: использование CPU на %i потоках\\n" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "Калибровка: потребление энергии пробуждения CPU\\n" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "Калибровка USB-устройств\\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... устройство %s\\n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "Калибровка радиоустройств\\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "Калибровка подсветки монитора\\n" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "Калибровка простоя\\n" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "Калибровка: использование диска\\n" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "Запущена калибровка оценочного потребления энергии PowerTOP\\n" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "Завершена калибровка оценочного потребления энергии PowerTOP\\n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "Параметры после калибровки:\\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(HW)" +msgstr "Ядро" + +#: ../src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(OS)" +msgstr "Ядро" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "Ядро" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "упаковка процессора %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "упаковка процессора" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "Упаковка %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "Упаковка" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, fuzzy, c-format +msgid "Core %d" +msgstr "Ядро %i" + +#: ../src/cpu/cpu.cpp:573 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU %i" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "событие cpu_idle не вернуло состояния?\\n" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "события power или cpu_frequency не вернули состояния?\\n" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "опрос C0" + +#: ../src/cpu/cpu_linux.cpp:242 +#, fuzzy, c-format +msgid " CPU(OS) %i" +msgstr "CPU %i" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "CPU %i" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "Упаковка" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "активно C0" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "Линк SATA: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "Диск SATA: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "активно C0" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Аудиокодек %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Аудиокодек %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "Статистика устройств" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "Аккумулятор сообщает о скорости разряда в %sВт\\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "Базовая мощность системы оценена в %sВ\\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Потребление\\t Использование\\t Название устройства\\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr "Использование\\t Название устройства\\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "Аккумулятор сообщает о скорости разряда в %sВт\\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "Базовая мощность системы оценена в %sВ\\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Использование" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Статистика устройств" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "Сетевой интерфейс: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "Радиоустройство: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Статистика устройств" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI-устройство: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB-устройство: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB-устройство: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "Обзор" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "Статистика простоя" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "Статистика частоты" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "Статистика устройств" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "Выход" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sВ" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "0 мВ" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Тачпад/Клавиатура/Мышь" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "Контроллер SATA" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Встроенный USB-хаб Intel" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "Версия PowerTOP" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "Задать время до обновления" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "Использование: powertop [OPTIONS]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "запуск powertop в режиме калибровки" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "генерация csv-отчёта" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "запуск в режиме \"debug\"" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=devnode]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "использует Extech Power Analyzer для измерений" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "генерация html-отчёта" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "[=iterations] число итераций запуска каждого теста" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "подавить вывод в stderr" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=seconds]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "генерация отчёта за 'x' секунд" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "[=workload]" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "файл для запуска нагрузки" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "печать информации о версии" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "вывести данное меню помощи" + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "Для более подробной информации обратитесь к файлу README" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "В процессе работы возникла неизвестная ошибка!\\n" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "Недостаточно памяти для PowerTOP. Прерывание PowerTOP" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "Подготовка к взятию измерений\\n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "Взятие %d измерение(-ий) длительностью %d секунд(а) каждое.\\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "Замер нагрузки %s.\\n" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "выход...\\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "Не удалось подмонтировать debugfs!\\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, fuzzy, c-format +msgid "Quiet mode failed!\n" +msgstr "Ошибка режима \"quite\"!\\n" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "Завершение PowerTOP" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "Невозможно сохранить в файл" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "Невозможно загрузить из файла" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "Загрузка %i предварительных замеров\\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s необходима поддержка подсистемы 'perf' ядра\\n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "а также поддержка trace points в ядре:\\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Оценочное потребление: %5.1f\\t Измеренное потребление: %5.1f\\t Суммарно: " +"%5.1f\\n \\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "Оценочное время работы %i часов, %i минут\\n" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Суммарно" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "пробуждений/секунду" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU операций/секунду" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS операций/с и" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "Использование CPU" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Оценка потребления" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "Событий/с" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Категория" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "Описание" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "Пробуждений/с" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU операций/с" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "Диск ввод-вывод/с" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX пробуждений/с" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "Обзор программных потребителей энергии" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "Пробуждений/с" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Использование" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU операций/с" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "Пробуждений/с" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "Обзор программных потребителей энергии" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "Версия PowerTOP" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "Версия PowerTOP" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "печать информации о версии" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "Невозможно создать временный файл\\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "Хорошо" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Плохо" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Неизвестно" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "Статус интерфейса bluetooth-устройства" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "Статус wake-on-lan для устройства %s" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "УП времени выполнения для %s устройства %s" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s устройство %s не имеет управления питанием времени выполнения" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI-устройство %s не имеет управления питанием времени выполнения" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "УП времени выполнения для PCI-устройства %s" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Активировать управление питанием аудиокодека" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI watchdog должен быть отключен" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "Энергосберегающий планировщик CPU" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "Таймаут обратной записи VM" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "Переключатели" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr "<ESC> Выход| <Enter> Переключить| <r> Обновить окно" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "УП времени выполнения для %s устройства %s" + +#: ../src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s устройство %s не имеет управления питанием времени выполнения" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Активировать управление питанием линка SATA для %s" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "Autosuspend для неизвестного USB-устройства %s (%s:%s)" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "Autosuspend для USB-устройства %s [%s]" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "Энергосбережение для беспроводного интерфейса %s" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "Пробуждений/с" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr "<ESC> Выход| <Enter> Переключить| <r> Обновить окно" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "Статус wake-on-lan для устройства %s" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enable" +msgstr "Переключатели" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "Статус wake-on-lan для устройства %s" + +#~ msgid "Actual" +#~ msgstr "Действительная" + +#~ msgid "Power Consumption Summary" +#~ msgstr "Суммарное потребление энергии" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU операций/секунду" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS операций/с" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX пробуждений/секунду и" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "Использование регулятора cpufreq 'ondemand'" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=FILENAME]" diff --git a/po/tr_TR.po b/po/tr_TR.po new file mode 100644 index 0000000..e3c05b5 --- /dev/null +++ b/po/tr_TR.po @@ -0,0 +1,961 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Caner BAŞARAN <basaran.caner@gmail.com>, 2012-2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Turkish (Turkey) (http://www.transifex.com/projects/p/" +"PowerTOP/language/tr_TR/)\n" +"Language: tr_TR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, c-format +msgid "package-%i" +msgstr "" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, c-format +msgid "Core %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:573 +#, c-format +msgid "GPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "CPU kullanımı" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU kullanımı" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +msgid "Active" +msgstr "" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "Ses kodlayıcı %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "Ses kodlayıcı %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "Aygıt İst" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "Pil saatte %sW boşalıyor \n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "Tahmini güç Kullanım Aygıt adı\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " Kullanım Aygıt adı\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "Pil saatte %sW boşalıyor \n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +msgid "The system baseline power is estimated at: " +msgstr "" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "Kullanım" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "Aygıt İst" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "Aygıt İst" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI Aygıt: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB Aygıt: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB Aygıt: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "Genel" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "Bekleme İst" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "Frekans İst" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "Aygıt İst" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "Çıkış" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "% 7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr "0 mW" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 Dokunmatik Ped / Klavye / Fare" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA denetleyicisi" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Yerleşik Intel USB hub" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, c-format +msgid "PowerTOP version " +msgstr "" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "" + +#: ../src/main.cpp:137 +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "" + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"Tahmini güç: %5.1f Ölçülen güç: %5.1f Toplam: %5.1f\n" +"\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "Özet" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "CPU kullanımı" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "Tahmini Güç" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "Kategori" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +msgid " wakeup/s" +msgstr "" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "Kullanım" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +msgid " ops/s" +msgstr "" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +msgid " wakeups/s" +msgstr "" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +msgid "Top 10 Power Consumers" +msgstr "" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "Tahmini Güç" + +#: ../src/report/report.cpp:131 +msgid "Kernel Version" +msgstr "" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +msgid "System Information" +msgstr "" + +#: ../src/report/report.cpp:195 +#, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "İyi" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "Kötü" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "Bilinmiyor" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "Etkin Ses kodlayıcı güç yönetimi" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr " <ESC> Çıkış | <Enter> Değer değiştirme | <r> Pencere yenileme" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:59 +#, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "Etkin Ses kodlayıcı güç yönetimi" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "%s arabirimi için Kablosuz Güç Tasarrufu" + +#: ../src/wakeup/waketab.cpp:42 +msgid "WakeUp" +msgstr "" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr " <ESC> Çıkış | <Enter> Değer değiştirme | <r> Pencere yenileme" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +msgid "Wake status of the devices" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Enable" +msgstr "" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "USB Aygıt: %s" diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..a9a2b47 --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,996 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Tommy He <lovenemesis@gmail.com>, 2012 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: powertop@lists.01.org\n" +"POT-Creation-Date: 2019-01-04 13:55-0800\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/PowerTOP/" +"language/zh_CN/)\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "无法创建临时文件\n" + +#: ../src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "校准:%i 线程中的 CPU 使用\n" + +#: ../src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "校准:CPU 唤醒电源消耗\n" + +#: ../src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "校准 USB 设备\n" + +#: ../src/calibrate/calibrate.cpp:292 ../src/calibrate/calibrate.cpp:309 +#: ../src/calibrate/calibrate.cpp:317 ../src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... 设别 %s \n" + +#: ../src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "校准无线电设备\n" + +#: ../src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "校准背光\n" + +#: ../src/calibrate/calibrate.cpp:355 ../src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "校准空闲耗电\n" + +#: ../src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "校准:磁盘使用\n" + +#: ../src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "开始 PowerTOP 电量预计校准\n" + +#: ../src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "结束 PowerTOP 电量预计校准\n" + +#: ../src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "校准后参数:\n" + +#: ../src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: ../src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(HW)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:37 +#, c-format +msgid " Core(OS)" +msgstr "" + +#: ../src/cpu/cpu_core.cpp:91 ../src/cpu/intel_cpus.cpp:324 +#, c-format +msgid " Core" +msgstr "" + +#: ../src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "CPU 代号 %i" + +#: ../src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "CPU 代号" + +#: ../src/cpu/cpu.cpp:89 ../src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "CPU 代号 %i" + +#: ../src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: ../src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:535 ../src/cpu/cpu.cpp:753 +msgid "Package" +msgstr "" + +#: ../src/cpu/cpu.cpp:566 ../src/cpu/cpu.cpp:775 +#, c-format +msgid "Core %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:573 +#, c-format +msgid "GPU %d" +msgstr "" + +#: ../src/cpu/cpu.cpp:594 +#, fuzzy +msgid "CPU" +msgstr "CPU 占用" + +#: ../src/cpu/cpu.cpp:676 +msgid "Processor Frequency Report" +msgstr "" + +#: ../src/cpu/cpu.cpp:796 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU 占用" + +#: ../src/cpu/cpu.cpp:997 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "CPU 空闲事件没有返回状态?\n" + +#: ../src/cpu/cpu.cpp:1012 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 轮巡" + +#: ../src/cpu/cpu_linux.cpp:242 +#, c-format +msgid " CPU(OS) %i" +msgstr "" + +#: ../src/cpu/cpu_linux.cpp:341 ../src/cpu/intel_cpus.cpp:651 +#, c-format +msgid " CPU %i" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: ../src/cpu/cpu_package.cpp:104 ../src/cpu/intel_cpus.cpp:412 +#, c-format +msgid " Package" +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:129 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: ../src/cpu/intel_cpus.cpp:574 +msgid "C0 active" +msgstr "C0 运行" + +#: ../src/cpu/intel_cpus.cpp:632 +#, c-format +msgid "Average" +msgstr "" + +#: ../src/cpu/intel_gpu.cpp:64 +#, c-format +msgid " GPU " +msgstr "" + +#: ../src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA 连线: %s" + +#: ../src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA 磁盘: %s" + +#: ../src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: ../src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: ../src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 运行" + +#: ../src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: ../src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: ../src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: ../src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: ../src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "音频设备 %s: %s (%s)" + +#: ../src/devices/alsa.cpp:79 ../src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "音频设备 %s: %s" + +#: ../src/devices/devfreq.cpp:261 +#, fuzzy +msgid "Device Freq stats" +msgstr "设备统计" + +#: ../src/devices/devfreq.cpp:279 +msgid " Devfreq is not enabled" +msgstr "" + +#: ../src/devices/devfreq.cpp:284 +msgid " No devfreq devices available" +msgstr "" + +#: ../src/devices/device.cpp:172 ../src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "电池报告放电速率为 %sW\n" + +#: ../src/devices/device.cpp:174 ../src/process/do_process.cpp:833 +#, c-format +msgid "The power consumed was %sJ\n" +msgstr "" + +#: ../src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "系统基线耗电量为 %sW\n" + +#: ../src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "预计电量 使用量 设备名\n" + +#: ../src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " 使用量 设备名\n" + +#: ../src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "电池报告放电速率为 %sW\n" + +#: ../src/devices/device.cpp:261 +msgid "The power consumed was : " +msgstr "" + +#: ../src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "系统基线耗电量为 %sW\n" + +#: ../src/devices/device.cpp:277 ../src/process/do_process.cpp:850 +#: ../src/process/do_process.cpp:852 ../src/process/do_process.cpp:926 +#: ../src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "用量" + +#: ../src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "设备统计" + +#: ../src/devices/device.cpp:280 ../src/process/do_process.cpp:935 +#: ../src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#. Report Output +#: ../src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: ../src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "网络接口: %s (%s)" + +#: ../src/devices/rfkill.cpp:65 ../src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "无线电设备: %s" + +#: ../src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/tuning/tuningi2c.cpp:57 +#: ../src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: ../src/devices/runtime_pm.cpp:216 ../src/devlist.cpp:331 +#: ../src/tuning/tuningi2c.cpp:57 ../src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "设备统计" + +#: ../src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI 设备: %s" + +#: ../src/devices/usb.cpp:51 ../src/devices/usb.cpp:96 +#: ../src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB 设备: %s" + +#: ../src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB 设备: %s (%s)" + +#: ../src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#. Report Output +#. No div attribute here inherits from device power report +#: ../src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: ../src/display.cpp:70 +msgid "Overview" +msgstr "概况" + +#: ../src/display.cpp:71 +msgid "Idle stats" +msgstr "空闲统计" + +#: ../src/display.cpp:72 +msgid "Frequency stats" +msgstr "频率统计" + +#: ../src/display.cpp:73 +msgid "Device stats" +msgstr "设备统计" + +#: ../src/display.cpp:131 +msgid "Exit" +msgstr "退出" + +#: ../src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: ../src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: ../src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: ../src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 触摸板 / 键盘 / 鼠标" + +#: ../src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA 控制器" + +#: ../src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel 内建 USB 集线器" + +#: ../src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: ../src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: ../src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: ../src/lib.cpp:513 ../src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: ../src/main.cpp:103 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTOP 版本" + +#: ../src/main.cpp:109 +msgid "Set refresh time out" +msgstr "设定刷新延迟" + +#: ../src/main.cpp:122 +msgid "Usage: powertop [OPTIONS]" +msgstr "用法:powertop [选项]" + +#: ../src/main.cpp:123 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: ../src/main.cpp:124 +msgid "runs powertop in calibration mode" +msgstr "以校准模式运行 PowerTOP" + +#: ../src/main.cpp:125 ../src/main.cpp:128 +msgid "[=filename]" +msgstr "" + +#: ../src/main.cpp:125 +msgid "generate a csv report" +msgstr "生成 CSV 报告" + +#: ../src/main.cpp:126 +msgid "run in \"debug\" mode" +msgstr "以“除错”模式运行" + +#: ../src/main.cpp:127 +msgid "[=devnode]" +msgstr "[=devnode]" + +#: ../src/main.cpp:127 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "使用 Extech 电源分析仪进行测量" + +#: ../src/main.cpp:128 +msgid "generate a html report" +msgstr "生成 HTML 报告" + +#: ../src/main.cpp:129 +msgid "[=iterations] number of times to run each test" +msgstr "[=重复数] 运行每项测试的次数" + +#: ../src/main.cpp:130 +msgid "suppress stderr output" +msgstr "" + +#: ../src/main.cpp:131 ../src/main.cpp:132 +msgid "[=seconds]" +msgstr "[=秒]" + +#: ../src/main.cpp:131 +msgid "interval for power consumption measurement" +msgstr "" + +#: ../src/main.cpp:132 +msgid "generate a report for 'x' seconds" +msgstr "生成指定 'x' 秒数的报告" + +#: ../src/main.cpp:133 +msgid "[=workload]" +msgstr "" + +#: ../src/main.cpp:133 +msgid "file to execute for workload" +msgstr "" + +#: ../src/main.cpp:134 +msgid "print version information" +msgstr "打印版本信息" + +#: ../src/main.cpp:135 +msgid "print this help menu" +msgstr "打印此帮助菜单" + +#: ../src/main.cpp:137 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "更多帮助请查阅 README" + +#: ../src/main.cpp:232 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "" + +#: ../src/main.cpp:289 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTOP 内存溢出。 PowerTOP 正在退出。" + +#. one to warm up everything +#: ../src/main.cpp:297 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "准备开始测量\n" + +#: ../src/main.cpp:302 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "执行 %d 次测量,每个持续 %d 秒。\n" + +#: ../src/main.cpp:304 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "" + +#: ../src/main.cpp:329 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: ../src/main.cpp:330 ../src/main.cpp:380 +#, c-format +msgid "exiting...\n" +msgstr "退出……\n" + +#: ../src/main.cpp:364 +#, c-format +msgid "modprobe cpufreq_stats failed" +msgstr "" + +#: ../src/main.cpp:367 +#, c-format +msgid "modprobe msr failed" +msgstr "" + +#: ../src/main.cpp:379 ../src/main.cpp:383 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "挂载 debugfs 失败!\n" + +#: ../src/main.cpp:384 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: ../src/main.cpp:466 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: ../src/main.cpp:482 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: ../src/main.cpp:491 +#, c-format +msgid "Quiet mode failed!\n" +msgstr "" + +#: ../src/main.cpp:559 +msgid "Leaving PowerTOP" +msgstr "离开 PowerTOP" + +#: ../src/parameters/persistent.cpp:46 ../src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "" + +#: ../src/parameters/persistent.cpp:89 ../src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "" + +#. '%i" is for count, do not translate +#: ../src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "载入之前 %i 的测量。\n" + +#: ../src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: ../src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: ../src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "" +"PowerTOP %s 需要内核支持 'perf' 子系统\n" +"\n" + +#: ../src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "以及支持内核中追溯点:\n" + +#: ../src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"预计耗电量: %5.1f 测量耗电量: %5.1f 总计: %5.1f\n" +"\n" + +#: ../src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "估计剩余时间 %i 小时, %i 分钟\n" + +#: ../src/process/do_process.cpp:846 +msgid "Summary" +msgstr "摘要" + +#: ../src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "每秒唤醒数" + +#: ../src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "每秒 GPU 操作数" + +#: ../src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "每秒 VFS 操作数和" + +#: ../src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "CPU 占用" + +#: ../src/process/do_process.cpp:850 +msgid "Power est." +msgstr "估计电量" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "每秒事件数" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:931 ../src/process/do_process.cpp:1079 +msgid "Category" +msgstr "分类" + +#: ../src/process/do_process.cpp:850 ../src/process/do_process.cpp:852 +#: ../src/process/do_process.cpp:932 ../src/process/do_process.cpp:1080 +#: ../src/tuning/tuning.cpp:242 ../src/tuning/tuning.cpp:270 +#: ../src/tuning/tuning.cpp:288 ../src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "描述" + +#: ../src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "每秒唤醒数" + +#: ../src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "每秒 GPU 操作数" + +#: ../src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "每秒磁盘 IO 数" + +#: ../src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "每秒 GFX 唤醒数" + +#: ../src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "软件电量消耗概览" + +#: ../src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: ../src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: ../src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: ../src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "每秒唤醒数" + +#: ../src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: ../src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "用量" + +#: ../src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: ../src/process/do_process.cpp:1067 ../src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "每秒 GPU 操作数" + +#: ../src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: ../src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "每秒唤醒数" + +#: ../src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: ../src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "软件电量消耗概览" + +#: ../src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTOP 版本" + +#: ../src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTOP 版本" + +#: ../src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: ../src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: ../src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: ../src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "打印版本信息" + +#: ../src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "无法创建临时文件\n" + +#: ../src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputing using base filename %s\n" +msgstr "" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:49 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "良好" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:50 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "糟糕" + +#: ../src/tuning/bluetooth.cpp:46 ../src/tuning/ethernet.cpp:50 +#: ../src/tuning/runtime.cpp:42 ../src/tuning/tunable.cpp:51 +#: ../src/tuning/tuningi2c.cpp:35 ../src/tuning/tuningsysfs.cpp:45 +#: ../src/tuning/tuningusb.cpp:39 ../src/tuning/wifi.cpp:45 +#: ../src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "未知" + +#: ../src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "蓝牙设备接口状态" + +#: ../src/tuning/ethernet.cpp:54 ../src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "设备 %s 的网络唤醒状态" + +#: ../src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "%s 设备 %s 的运行时电源管理" + +#: ../src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s 设备 %s 没有运行时电源管理" + +#: ../src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI 设备 %s 没有运行时电源管理" + +#: ../src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "PCI 设备 %s 的运行时电源管理" + +#: ../src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "启用音频设备电源管理" + +#: ../src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "需要关闭 NMI 监控" + +#: ../src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "支持节电的 CPU 调度器" + +#: ../src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "虚拟内存回写延时" + +#: ../src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "可调项" + +#: ../src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr " <ESC> 退出 | <Enter> 切换可调整项 | <r> 窗口刷新" + +#: ../src/tuning/tuning.cpp:243 ../src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#. Report Output +#: ../src/tuning/tuning.cpp:300 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: ../src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "%s 设备 %s 的运行时电源管理" + +#: ../src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s 设备 %s 没有运行时电源管理" + +#: ../src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "启用音频设备电源管理" + +#: ../src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "自动挂起未知 USB 设备 %s (%s:%s)" + +#: ../src/tuning/tuningusb.cpp:71 ../src/tuning/tuningusb.cpp:73 +#: ../src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "自动挂起 USB 设备 %s [%s]" + +#: ../src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "接口 %s 的无线节电设置" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "每秒唤醒数" + +#: ../src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr " <ESC> 退出 | <Enter> 切换可调整项 | <r> 窗口刷新" + +#. Report Output +#: ../src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "设备 %s 的网络唤醒状态" + +#: ../src/wakeup/wakeup.cpp:48 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enable" +msgstr "可调项" + +#: ../src/wakeup/wakeup.cpp:49 ../src/wakeup/wakeup_ethernet.cpp:47 +#: ../src/wakeup/wakeup_usb.cpp:47 +msgid "Disable" +msgstr "" + +#: ../src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "设备 %s 的网络唤醒状态" + +#~ msgid "Actual" +#~ msgstr "实际" + +#~ msgid "Power Consumption Summary" +#~ msgstr "电量消耗摘要" + +#~ msgid "GPU ops/second" +#~ msgstr "每秒 GPU 操作数" + +#~ msgid "VFS ops/sec" +#~ msgstr "每秒 VFS 操作数" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "每秒 GFX 唤醒数和" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "使用 '按需调整' CPU 频率控制器" + +#~ msgid "[=FILENAME]" +#~ msgstr "[=文件名]" diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100644 index 0000000..7e902fd --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,997 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Intel Corporation +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Yuan CHAO <yuanchao@gmail.com>, 2012-2013 +msgid "" +msgstr "" +"Project-Id-Version: PowerTOP\n" +"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n" +"POT-Creation-Date: 2022-09-29 04:45-0700\n" +"PO-Revision-Date: 2013-11-05 08:40+0000\n" +"Last-Translator: Margie Foster <margie@linux.intel.com>\n" +"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/" +"PowerTOP/language/zh_TW/)\n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/calibrate/calibrate.cpp:238 +#, c-format +msgid "Cannot create temp file\n" +msgstr "無法建立暫存檔案\n" + +#: src/calibrate/calibrate.cpp:258 +#, c-format +msgid "Calibrating: CPU usage on %i threads\n" +msgstr "校正: CPU 使用量於 %i 執行緒\n" + +#: src/calibrate/calibrate.cpp:273 +#, c-format +msgid "Calibrating: CPU wakeup power consumption\n" +msgstr "校正: CPU 喚醒電源使用量\n" + +#: src/calibrate/calibrate.cpp:290 +#, c-format +msgid "Calibrating USB devices\n" +msgstr "校正 USB 設備\n" + +#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309 +#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334 +#, c-format +msgid ".... device %s \n" +msgstr ".... 裝置 %s \n" + +#: src/calibrate/calibrate.cpp:307 +#, c-format +msgid "Calibrating radio devices\n" +msgstr "校正無線電設備\n" + +#: src/calibrate/calibrate.cpp:331 +#, c-format +msgid "Calibrating backlight\n" +msgstr "校正螢幕背光\n" + +#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365 +#, c-format +msgid "Calibrating idle\n" +msgstr "校正閒置\n" + +#: src/calibrate/calibrate.cpp:378 +#, c-format +msgid "Calibrating: disk usage \n" +msgstr "校正: 磁碟使用\n" + +#: src/calibrate/calibrate.cpp:403 +msgid "Starting PowerTOP power estimate calibration \n" +msgstr "開始 PowerTOP 電源估計校正 \n" + +#: src/calibrate/calibrate.cpp:426 +msgid "Finishing PowerTOP power estimate calibration \n" +msgstr "完成 PowerTOP 電源估計校正 \n" + +#: src/calibrate/calibrate.cpp:430 +#, c-format +msgid "Parameters after calibration:\n" +msgstr "校正取得參數:\n" + +#: src/cpu/abstract_cpu.cpp:74 +msgid "Idle" +msgstr "" + +#: src/cpu/abstract_cpu.cpp:76 +msgid "Turbo Mode" +msgstr "" + +#: src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(HW)" +msgstr " 核心" + +#: src/cpu/cpu_core.cpp:37 +#, fuzzy, c-format +msgid " Core(OS)" +msgstr " 核心" + +#: src/cpu/cpu_core.cpp:91 src/cpu/intel_cpus.cpp:367 +#, c-format +msgid " Core" +msgstr " 核心" + +#: src/cpu/cpu.cpp:85 +#, c-format +msgid "cpu package %i" +msgstr "cpu 代號 %i" + +#: src/cpu/cpu.cpp:86 +msgid "cpu package" +msgstr "cpu 代號" + +#: src/cpu/cpu.cpp:89 src/cpu/cpu.cpp:96 +#, fuzzy, c-format +msgid "package-%i" +msgstr "代號 %i" + +#: src/cpu/cpu.cpp:90 +msgid "cpu rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:97 +msgid "dram rapl package" +msgstr "" + +#: src/cpu/cpu.cpp:471 +msgid "Processor Idle State Report" +msgstr "" + +#: src/cpu/cpu.cpp:535 src/cpu/cpu.cpp:761 +msgid "Package" +msgstr "代號" + +#: src/cpu/cpu.cpp:572 src/cpu/cpu.cpp:783 +#, fuzzy, c-format +msgid "Core %d" +msgstr "核心 %i" + +#: src/cpu/cpu.cpp:579 +#, fuzzy, c-format +msgid "GPU %d" +msgstr "GPU %i" + +#: src/cpu/cpu.cpp:602 +#, fuzzy +msgid "CPU" +msgstr "CPU %i" + +#: src/cpu/cpu.cpp:684 +msgid "Processor Frequency Report" +msgstr "" + +#: src/cpu/cpu.cpp:804 +#, fuzzy, c-format +msgid "CPU %d" +msgstr "CPU %i" + +#: src/cpu/cpu.cpp:1005 +#, c-format +msgid "cpu_idle event returned no state?\n" +msgstr "cpu_idle 事件沒有傳回狀態?\n" + +#: src/cpu/cpu.cpp:1020 +#, c-format +msgid "power or cpu_frequency event returned no state?\n" +msgstr "power 或 cpu_frequecny 事件沒有傳回狀態?\n" + +#: src/cpu/cpu_linux.cpp:79 +msgid "C0 polling" +msgstr "C0 輪巡" + +#: src/cpu/cpu_linux.cpp:242 +#, fuzzy, c-format +msgid " CPU(OS) %i" +msgstr " CPU %i" + +#: src/cpu/cpu_linux.cpp:341 src/cpu/intel_cpus.cpp:733 +#, c-format +msgid " CPU %i" +msgstr " CPU %i" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(HW)" +msgstr "" + +#: src/cpu/cpu_package.cpp:47 +#, c-format +msgid " Pkg(OS)" +msgstr "" + +#: src/cpu/cpu_package.cpp:104 src/cpu/intel_cpus.cpp:498 +#, c-format +msgid " Package" +msgstr "代號" + +#: src/cpu/intel_cpus.cpp:152 +#, c-format +msgid "read_msr cpu%d 0x%llx : " +msgstr "" + +#: src/cpu/intel_cpus.cpp:656 +msgid "C0 active" +msgstr "C0 運作中" + +#: src/cpu/intel_cpus.cpp:714 +#, c-format +msgid "Average" +msgstr "" + +#: src/cpu/intel_gpu.cpp:64 +#, fuzzy, c-format +msgid " GPU " +msgstr "GPU %i" + +#: src/devices/ahci.cpp:154 +#, c-format +msgid "SATA link: %s" +msgstr "SATA 連線: %s" + +#: src/devices/ahci.cpp:156 +#, c-format +msgid "SATA disk: %s" +msgstr "SATA 磁碟: %s" + +#: src/devices/ahci.cpp:374 +msgid "AHCI ALPM Residency Statistics - Not supported on this macine" +msgstr "" + +#: src/devices/ahci.cpp:389 +msgid "Link" +msgstr "" + +#: src/devices/ahci.cpp:390 +#, fuzzy +msgid "Active" +msgstr "C0 運作中" + +#: src/devices/ahci.cpp:391 +msgid "Partial" +msgstr "" + +#: src/devices/ahci.cpp:392 +msgid "Slumber" +msgstr "" + +#: src/devices/ahci.cpp:393 +msgid "Devslp" +msgstr "" + +#: src/devices/ahci.cpp:399 +msgid "AHCI ALPM Residency Statistics" +msgstr "" + +#: src/devices/alsa.cpp:77 +#, c-format +msgid "Audio codec %s: %s (%s)" +msgstr "音效設備 %s: %s (%s)" + +#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81 +#, c-format +msgid "Audio codec %s: %s" +msgstr "音效設備 %s: %s" + +#: src/devices/devfreq.cpp:260 +#, fuzzy +msgid "Device Freq stats" +msgstr "設備統計" + +#: src/devices/devfreq.cpp:278 +msgid " Devfreq is not enabled" +msgstr "" + +#: src/devices/devfreq.cpp:283 +msgid " No devfreq devices available" +msgstr "" + +#: src/devices/device.cpp:172 src/process/do_process.cpp:831 +#, c-format +msgid "The battery reports a discharge rate of %sW\n" +msgstr "電池回報放電速率為 %sW\n" + +#: src/devices/device.cpp:174 src/process/do_process.cpp:833 +#, c-format +msgid "The energy consumed was %sJ\n" +msgstr "" + +#: src/devices/device.cpp:180 +#, c-format +msgid "System baseline power is estimated at %sW\n" +msgstr "預期系統基礎用電量為 %sW\n" + +#: src/devices/device.cpp:187 +msgid "Power est. Usage Device name\n" +msgstr "電源預估 使用量 設備名稱\n" + +#: src/devices/device.cpp:189 +msgid " Usage Device name\n" +msgstr " 使用量 設備名稱\n" + +#: src/devices/device.cpp:256 +#, fuzzy +msgid "The battery reports a discharge rate of: " +msgstr "電池回報放電速率為 %sW\n" + +#: src/devices/device.cpp:261 +msgid "The energy consumed was : " +msgstr "" + +#: src/devices/device.cpp:268 +#, fuzzy +msgid "The system baseline power is estimated at: " +msgstr "預期系統基礎用電量為 %sW\n" + +#: src/devices/device.cpp:277 src/process/do_process.cpp:850 +#: src/process/do_process.cpp:852 src/process/do_process.cpp:926 +#: src/process/do_process.cpp:1077 +msgid "Usage" +msgstr "用法" + +#: src/devices/device.cpp:278 +#, fuzzy +msgid "Device Name" +msgstr "設備統計" + +#: src/devices/device.cpp:280 src/process/do_process.cpp:935 +#: src/process/do_process.cpp:1082 +msgid "PW Estimate" +msgstr "" + +#: src/devices/device.cpp:317 +msgid "Device Power Report" +msgstr "" + +#: src/devices/network.cpp:177 +#, c-format +msgid "Network interface: %s (%s)" +msgstr "網路介面卡: %s (%s)" + +#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69 +#, c-format +msgid "Radio device: %s" +msgstr "無線電設備: %s" + +#: src/devices/runtime_pm.cpp:216 +#, c-format +msgid "I2C %s (%s): %s" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57 +#: src/tuning/tuningi2c.cpp:59 +msgid "Adapter" +msgstr "" + +#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331 +#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59 +#, fuzzy +msgid "Device" +msgstr "設備統計" + +#: src/devices/runtime_pm.cpp:241 +#, c-format +msgid "PCI Device: %s" +msgstr "PCI 設備: %s" + +#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98 +#, c-format +msgid "USB device: %s" +msgstr "USB 設備: %s" + +#: src/devices/usb.cpp:94 +#, c-format +msgid "USB device: %s (%s)" +msgstr "USB 設備: %s (%s)" + +#: src/devlist.cpp:330 +msgid "Process" +msgstr "" + +#: src/devlist.cpp:347 +msgid "Process Device Activity" +msgstr "" + +#: src/display.cpp:70 +msgid "Overview" +msgstr "總覽" + +#: src/display.cpp:71 +msgid "Idle stats" +msgstr "閒置統計" + +#: src/display.cpp:72 +msgid "Frequency stats" +msgstr "頻率統計" + +#: src/display.cpp:73 +msgid "Device stats" +msgstr "設備統計" + +#: src/display.cpp:131 +msgid "Exit" +msgstr "離開" + +#: src/display.cpp:132 +msgid "Navigate" +msgstr "" + +#: src/lib.cpp:288 +#, c-format +msgid "%7sW" +msgstr "%7sW" + +#: src/lib.cpp:291 +#, c-format +msgid " 0 mW" +msgstr " 0 mW" + +#: src/lib.cpp:410 +msgid "PS/2 Touchpad / Keyboard / Mouse" +msgstr "PS/2 觸控板 / 鍵盤 / 滑鼠" + +#: src/lib.cpp:411 +msgid "SATA controller" +msgstr "SATA 控制器" + +#: src/lib.cpp:412 +msgid "Intel built in USB hub" +msgstr "Intel 內建 USB 集線器" + +#: src/lib.cpp:467 +#, c-format +msgid "glob returned GLOB_NOSPACE\n" +msgstr "" + +#: src/lib.cpp:471 +#, c-format +msgid "glob returned GLOB_ABORTED\n" +msgstr "" + +#: src/lib.cpp:475 +#, c-format +msgid "glob returned GLOB_NOMATCH\n" +msgstr "" + +#: src/lib.cpp:513 src/lib.cpp:549 +#, c-format +msgid "" +"Model-specific registers (MSR)\t\t\t not found (try enabling " +"CONFIG_X86_MSR).\n" +msgstr "" + +#: src/main.cpp:104 +#, fuzzy, c-format +msgid "PowerTOP version " +msgstr "PowerTop 版本" + +#: src/main.cpp:110 +msgid "Set refresh time out" +msgstr "設定更新週期" + +#: src/main.cpp:123 +msgid "Usage: powertop [OPTIONS]" +msgstr "用法: powertop [選項]" + +#: src/main.cpp:124 +msgid "sets all tunable options to their GOOD setting" +msgstr "" + +#: src/main.cpp:125 +msgid "runs powertop in calibration mode" +msgstr "以校正模式執行 powertop" + +#: src/main.cpp:126 src/main.cpp:129 +msgid "[=filename]" +msgstr "" + +#: src/main.cpp:126 +msgid "generate a csv report" +msgstr "產生 csv 報告" + +#: src/main.cpp:127 +msgid "run in \"debug\" mode" +msgstr "以 \"debug\" 模式執行" + +#: src/main.cpp:128 +msgid "[=devnode]" +msgstr "[= 設備節點]" + +#: src/main.cpp:128 +msgid "uses an Extech Power Analyzer for measurements" +msgstr "使用 Extech 電源分析儀進行量測" + +#: src/main.cpp:129 +msgid "generate a html report" +msgstr "產生 html 報告" + +#: src/main.cpp:130 +msgid "[=iterations] number of times to run each test" +msgstr "[=iterations] 每次檢驗進行量測次數" + +#: src/main.cpp:131 +msgid "suppress stderr output" +msgstr "關閉標準錯誤輸出" + +#: src/main.cpp:132 src/main.cpp:133 +msgid "[=seconds]" +msgstr "[= 秒]" + +#: src/main.cpp:132 +msgid "interval for power consumption measurement" +msgstr "" + +#: src/main.cpp:133 +msgid "generate a report for 'x' seconds" +msgstr "產生蒐集資料 'x' 秒鐘的報告" + +#: src/main.cpp:134 +msgid "[=workload]" +msgstr "[=工作負載]" + +#: src/main.cpp:134 +msgid "file to execute for workload" +msgstr "工作負載要執行的檔案" + +#: src/main.cpp:135 +msgid "print version information" +msgstr "顯示版本資訊" + +#: src/main.cpp:136 +msgid "print this help menu" +msgstr "顯示此輔助說明選單" + +#: src/main.cpp:138 +#, fuzzy +msgid "For more help please refer to the 'man 8 powertop'" +msgstr "更多的輔助說明請參閱 README" + +#: src/main.cpp:233 +#, c-format +msgid "Unknown issue running workload!\n" +msgstr "執行工作負載發生未知問題!\n" + +#: src/main.cpp:290 +msgid "PowerTOP is out of memory. PowerTOP is Aborting" +msgstr "PowerTOP 已耗盡記憶體,退出中。" + +#: src/main.cpp:298 +#, c-format +msgid "Preparing to take measurements\n" +msgstr "量測準備中\n" + +#: src/main.cpp:303 +#, c-format +msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n" +msgstr "測量 %d 次於每 %d 秒。\n" + +#: src/main.cpp:305 +#, c-format +msgid "Measuring workload %s.\n" +msgstr "量測工作負載 %s 。\n" + +#: src/main.cpp:330 +#, c-format +msgid "PowerTOP " +msgstr "PowerTOP " + +#: src/main.cpp:331 src/main.cpp:381 +#, c-format +msgid "exiting...\n" +msgstr "離開中...\n" + +#: src/main.cpp:365 +#, c-format +msgid "modprobe cpufreq_stats failed\n" +msgstr "" + +#: src/main.cpp:368 +#, fuzzy, c-format +msgid "modprobe msr failed\n" +msgstr "進入安靜模式失敗!\n" + +#: src/main.cpp:380 src/main.cpp:384 +#, c-format +msgid "Failed to mount debugfs!\n" +msgstr "debugfs 掛載失敗!\n" + +#: src/main.cpp:385 +#, c-format +msgid "Should still be able to auto tune...\n" +msgstr "" + +#: src/main.cpp:467 +#, c-format +msgid "Invalid CSV filename\n" +msgstr "" + +#: src/main.cpp:483 +#, c-format +msgid "Invalid HTML filename\n" +msgstr "" + +#: src/main.cpp:492 +#, fuzzy, c-format +msgid "Quiet mode failed!\n" +msgstr "進入安靜模式失敗!\n" + +#: src/main.cpp:560 +msgid "Leaving PowerTOP" +msgstr "離開 PowerTOP" + +#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155 +msgid "Cannot save to file" +msgstr "無法儲存檔案" + +#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180 +msgid "Cannot load from file" +msgstr "無法讀取檔案" + +#: src/parameters/persistent.cpp:138 +#, c-format +msgid "Loaded %i prior measurements\n" +msgstr "已載入 %i 筆先前量測數據\n" + +#: src/parameters/persistent.cpp:181 +msgid "" +"File will be loaded after taking minimum number of measurement(s) with " +"battery only \n" +msgstr "" + +#: src/perf/perf.cpp:115 +#, c-format +msgid "" +"Too many open files, please increase the limit of open file descriptors.\n" +msgstr "" + +#: src/perf/perf.cpp:117 +#, c-format +msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n" +msgstr "PowerTOP %s 需要 Linux 核心 'perf' 子系統支援\n" + +#: src/perf/perf.cpp:118 +#, c-format +msgid "as well as support for trace points in the kernel:\n" +msgstr "以及 Linux 核心中斷點 (trace point) 支援:\n" + +#: src/process/do_process.cpp:819 +#, c-format +msgid "" +"Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n" +"\n" +msgstr "" +"預估用電量: %5.1f 實測用電量: %5.1f 總計: %5.1f\n" +"\n" + +#: src/process/do_process.cpp:838 +#, c-format +msgid "The estimated remaining time is %i hours, %i minutes\n" +msgstr "估計剩餘時間為 %i 小時 %i 分鐘\n" + +#: src/process/do_process.cpp:846 +msgid "Summary" +msgstr "總覽" + +#: src/process/do_process.cpp:846 +msgid "wakeups/second" +msgstr "喚醒 / 秒" + +#: src/process/do_process.cpp:846 +msgid "GPU ops/seconds" +msgstr "GPU 指令 / 秒" + +#: src/process/do_process.cpp:846 +msgid "VFS ops/sec and" +msgstr "VFS 指令 / 秒 以及" + +#: src/process/do_process.cpp:846 +msgid "CPU use" +msgstr "CPU 用量" + +#: src/process/do_process.cpp:850 +msgid "Power est." +msgstr "電源預計" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:1078 +msgid "Events/s" +msgstr "事件 / 秒" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079 +msgid "Category" +msgstr "分類" + +#: src/process/do_process.cpp:850 src/process/do_process.cpp:852 +#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080 +#: src/tuning/tuning.cpp:242 src/tuning/tuning.cpp:270 +#: src/tuning/tuning.cpp:295 src/wakeup/waketab.cpp:155 +msgid "Description" +msgstr "描述" + +#: src/process/do_process.cpp:927 +msgid "Wakeups/s" +msgstr "喚醒 / 秒" + +#: src/process/do_process.cpp:928 +msgid "GPU ops/s" +msgstr "GPU 指令 / 秒" + +#: src/process/do_process.cpp:929 +msgid "Disk IO/s" +msgstr "磁碟 IO / 秒" + +#: src/process/do_process.cpp:930 +msgid "GFX Wakeups/s" +msgstr "GFX 喚醒 / 秒" + +#: src/process/do_process.cpp:1017 +msgid "Overview of Software Power Consumers" +msgstr "軟體耗電量大戶總覽" + +#: src/process/do_process.cpp:1057 +msgid "Target:" +msgstr "" + +#: src/process/do_process.cpp:1058 +msgid "1 units/s" +msgstr "" + +#: src/process/do_process.cpp:1059 +msgid "System: " +msgstr "" + +#: src/process/do_process.cpp:1061 +#, fuzzy +msgid " wakeup/s" +msgstr "喚醒 / 秒" + +#: src/process/do_process.cpp:1062 +msgid "CPU: " +msgstr "" + +#: src/process/do_process.cpp:1064 +#, fuzzy, c-format +msgid "% usage" +msgstr "用法" + +#: src/process/do_process.cpp:1065 +msgid "GPU:" +msgstr "" + +#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073 +#, fuzzy +msgid " ops/s" +msgstr "GPU 指令 / 秒" + +#: src/process/do_process.cpp:1068 +msgid "GFX:" +msgstr "" + +#: src/process/do_process.cpp:1070 +#, fuzzy +msgid " wakeups/s" +msgstr "喚醒 / 秒" + +#: src/process/do_process.cpp:1071 +msgid "VFS:" +msgstr "" + +#: src/process/do_process.cpp:1139 +#, fuzzy +msgid "Top 10 Power Consumers" +msgstr "軟體耗電量大戶總覽" + +#: src/report/report.cpp:122 +#, fuzzy +msgid "PowerTOP Version" +msgstr "PowerTop 版本" + +#: src/report/report.cpp:131 +#, fuzzy +msgid "Kernel Version" +msgstr "PowerTop 版本" + +#: src/report/report.cpp:135 +msgid "System Name" +msgstr "" + +#: src/report/report.cpp:142 +msgid "CPU Information" +msgstr "" + +#: src/report/report.cpp:154 +msgid "OS Information" +msgstr "" + +#: src/report/report.cpp:161 +#, fuzzy +msgid "System Information" +msgstr "顯示版本資訊" + +#: src/report/report.cpp:195 +#, fuzzy, c-format +msgid "Cannot open output file %s (%s)\n" +msgstr "無法建立暫存檔案\n" + +#: src/report/report.cpp:211 +#, c-format +msgid "PowerTOP outputting using base filename %s\n" +msgstr "" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Good" +msgstr "好" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 +msgid "Bad" +msgstr "壞" + +#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50 +#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51 +#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45 +#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45 src/wakeup/wakeup.cpp:50 +msgid "Unknown" +msgstr "未知" + +#: src/tuning/bluetooth.cpp:48 +#, c-format +msgid "Bluetooth device interface status" +msgstr "藍牙設備介面狀態" + +#: src/tuning/ethernet.cpp:54 src/wakeup/wakeup_ethernet.cpp:51 +#, c-format +msgid "Wake-on-lan status for device %s" +msgstr "網路喚醒啟用狀態於設備 %s" + +#: src/tuning/runtime.cpp:48 +#, c-format +msgid "Runtime PM for %s device %s" +msgstr "執行時期省電 %s 設備 %s" + +#: src/tuning/runtime.cpp:50 +#, c-format +msgid "%s device %s has no runtime power management" +msgstr "%s 設備 %s 沒有執行時期電源管理功能" + +#: src/tuning/runtime.cpp:74 +#, c-format +msgid "PCI Device %s has no runtime power management" +msgstr "PCI 設備 %s 沒有執行時期電源管理功能" + +#: src/tuning/runtime.cpp:76 +#, c-format +msgid "Runtime PM for PCI Device %s" +msgstr "PCI 設備 %s 電源管理" + +#: src/tuning/runtime.cpp:80 +#, fuzzy, c-format +msgid "Runtime PM for port %s of PCI device: %s" +msgstr "執行時期省電 %s 設備 %s" + +#: src/tuning/runtime.cpp:83 +#, fuzzy, c-format +msgid "Runtime PM for disk %s" +msgstr "執行時期省電 %s 設備 %s" + +#: src/tuning/tuning.cpp:62 +msgid "Enable Audio codec power management" +msgstr "啟用音效設備電源管理功能" + +#: src/tuning/tuning.cpp:63 +msgid "NMI watchdog should be turned off" +msgstr "NMI watchdog 監控應該關閉" + +#: src/tuning/tuning.cpp:64 +msgid "Power Aware CPU scheduler" +msgstr "省電型 CPU 排程器 " + +#: src/tuning/tuning.cpp:65 +msgid "VM writeback timeout" +msgstr "VM 回寫延時" + +#: src/tuning/tuning.cpp:81 +msgid "Tunables" +msgstr "可調選項" + +#: src/tuning/tuning.cpp:81 +msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh" +msgstr " <ESC> 離開 | <Enter> 切換選項開關 | <r> 更新視窗內容" + +#: src/tuning/tuning.cpp:243 src/wakeup/waketab.cpp:156 +msgid "Script" +msgstr "" + +#: src/tuning/tuning.cpp:257 +msgid "Software Settings in Need of Tuning" +msgstr "" + +#: src/tuning/tuning.cpp:276 +msgid "Untunable Software Issues" +msgstr "" + +#: src/tuning/tuning.cpp:307 +msgid "Optimal Tuned Software Settings" +msgstr "" + +#: src/tuning/tuningi2c.cpp:57 +#, fuzzy, c-format +msgid "Runtime PM for I2C %s %s (%s)" +msgstr "執行時期省電 %s 設備 %s" + +#: src/tuning/tuningi2c.cpp:59 +#, fuzzy, c-format +msgid "I2C %s %s has no runtime power management" +msgstr "%s 設備 %s 沒有執行時期電源管理功能" + +#: src/tuning/tuningsysfs.cpp:123 +#, fuzzy, c-format +msgid "Enable SATA link power management for %s" +msgstr "啟用 %s 的 SATA 連線電源管理" + +#: src/tuning/tuningusb.cpp:54 +#, c-format +msgid "Autosuspend for unknown USB device %s (%s:%s)" +msgstr "自動閒置於未知的 USB 設備 %s (%s:%s)" + +#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73 +#: src/tuning/tuningusb.cpp:75 +#, c-format +msgid "Autosuspend for USB device %s [%s]" +msgstr "自動閒置於 USB 設備 %s [%s]" + +#: src/tuning/wifi.cpp:48 +#, c-format +msgid "Wireless Power Saving for interface %s" +msgstr "無線網路省電狀態於設備 %s" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid "WakeUp" +msgstr "喚醒 / 秒" + +#: src/wakeup/waketab.cpp:42 +#, fuzzy +msgid " <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh" +msgstr " <ESC> 離開 | <Enter> 切換選項開關 | <r> 更新視窗內容" + +#: src/wakeup/waketab.cpp:170 +#, fuzzy +msgid "Wake status of the devices" +msgstr "網路喚醒啟用狀態於設備 %s" + +#: src/wakeup/wakeup.cpp:48 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +#, fuzzy +msgid "Enabled" +msgstr "可調選項" + +#: src/wakeup/wakeup.cpp:49 src/wakeup/wakeup_ethernet.cpp:47 +#: src/wakeup/wakeup_usb.cpp:47 +msgid "Disabled" +msgstr "" + +#: src/wakeup/wakeup_usb.cpp:51 +#, fuzzy, c-format +msgid "Wake status for USB device %s" +msgstr "網路喚醒啟用狀態於設備 %s" + +#~ msgid "Actual" +#~ msgstr "實際" + +#, fuzzy +#~ msgid "I2C Device: %s" +#~ msgstr "PCI 設備: %s" + +#~ msgid "[=FILENAME]" +#~ msgstr "[= 檔案名稱]" + +#~ msgid "Using 'ondemand' cpufreq governor" +#~ msgstr "使用 'ondemand' cpu 排程器" + +#~ msgid "Power Consumption Summary" +#~ msgstr "電源使用量總覽" + +#~ msgid "GPU ops/second" +#~ msgstr "GPU 指令 / 秒" + +#~ msgid "VFS ops/sec" +#~ msgstr "VFS 指令 / 秒" + +#~ msgid "GFX wakes/sec and" +#~ msgstr "GFX 喚醒 / 秒 以及" diff --git a/powertop.service b/powertop.service new file mode 100644 index 0000000..5a44ca2 --- /dev/null +++ b/powertop.service @@ -0,0 +1,9 @@ +[Unit] +Description=Extend the battery life of laptop + +[Service] +Type=oneshot +ExecStart=/usr/sbin/powertop --auto-tune + +[Install] +WantedBy=multi-user.target sleep.target diff --git a/scripts/bash-completion/Makefile.am b/scripts/bash-completion/Makefile.am new file mode 100644 index 0000000..45073bd --- /dev/null +++ b/scripts/bash-completion/Makefile.am @@ -0,0 +1,2 @@ +bashcompletiondir = @bashcompletiondir@ +dist_bashcompletion_DATA = powertop diff --git a/scripts/bash-completion/powertop b/scripts/bash-completion/powertop new file mode 100644 index 0000000..03d238e --- /dev/null +++ b/scripts/bash-completion/powertop @@ -0,0 +1,43 @@ +#!/bin/bash +# +# Powertop tab completion for bash. +# +# This is part of PowerTOP +# +# This program file 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; version 2 of the License. +# +# 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 in a file named COPYING; if not, write to the +# Free Software Foundation, Inc, +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# or just google for it. + +_powertop() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + '-C'|'--csv'|'--extech'|'-r'|'--html'|'-w'|'--workload') + _filedir + return 0 + ;; + esac + + local all_long_options=$( _parse_help "$1" ) + + COMPREPLY=( $( compgen -W "${all_long_options}" -- "$cur" ) ) + + return 0 +} + +# load the completion +complete -F _powertop powertop diff --git a/scripts/regenerate-potfiles-in b/scripts/regenerate-potfiles-in new file mode 100644 index 0000000..a178fa0 --- /dev/null +++ b/scripts/regenerate-potfiles-in @@ -0,0 +1,15 @@ +#!/bin/sh + +echo "INFO: checking for git ..." +git --version > /dev/null 2>&1 || exit 1 + +echo "INFO: priming ./POTFILES.in.new ..." +touch POTFILES.in.new || exit 2 +echo "# List of source files which contain translatable strings." > POTFILES.in.new || exit 3 +echo "" >> POTFILES.in.new || exit 4 + +echo "INFO: populating ./POTFILES.in.new ..." +git grep -l -e "__(" -e "_(" | sort >> POTFILES.in.new || exit 5 + +echo "INFO: contents of ./POTFILES.in.new ..." +cat POTFILES.in.new diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..6b523f6 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,176 @@ +AUTOMAKE_OPTIONS = subdir-objects + +sbin_PROGRAMS = powertop +nodist_powertop_SOURCES = css.h + +powertop_SOURCES = \ + css.h \ + devlist.cpp \ + devlist.h \ + display.cpp \ + display.h \ + lib.cpp \ + lib.h \ + main.cpp \ + powertop.css \ + \ + calibrate/calibrate.cpp \ + calibrate/calibrate.h \ + cpu/abstract_cpu.cpp \ + cpu/cpu.cpp \ + cpu/cpu.h \ + cpu/cpu_core.cpp \ + cpu/cpu_linux.cpp \ + cpu/cpu_package.cpp \ + cpu/cpu_rapl_device.cpp \ + cpu/cpu_rapl_device.h \ + cpu/cpudevice.cpp \ + cpu/cpudevice.h \ + cpu/dram_rapl_device.cpp \ + cpu/dram_rapl_device.h \ + cpu/intel_cpus.cpp \ + cpu/intel_cpus.h \ + cpu/intel_gpu.cpp \ + cpu/rapl/rapl_interface.cpp \ + cpu/rapl/rapl_interface.h \ + devices/ahci.cpp \ + devices/ahci.h \ + devices/alsa.cpp \ + devices/alsa.h \ + devices/backlight.cpp \ + devices/backlight.h \ + devices/devfreq.cpp \ + devices/devfreq.h \ + devices/device.cpp \ + devices/device.h \ + devices/gpu_rapl_device.cpp \ + devices/gpu_rapl_device.h \ + devices/i915-gpu.cpp \ + devices/i915-gpu.h \ + devices/network.cpp \ + devices/network.h \ + devices/rfkill.cpp \ + devices/rfkill.h \ + devices/runtime_pm.cpp \ + devices/runtime_pm.h \ + devices/thinkpad-fan.cpp \ + devices/thinkpad-fan.h \ + devices/thinkpad-light.cpp \ + devices/thinkpad-light.h \ + devices/usb.cpp \ + devices/usb.h \ + measurement/acpi.cpp \ + measurement/acpi.h \ + measurement/extech.cpp \ + measurement/extech.h \ + measurement/measurement.cpp \ + measurement/measurement.h \ + measurement/sysfs.cpp \ + measurement/sysfs.h \ + measurement/opal-sensors.cpp \ + measurement/opal-sensors.h \ + parameters/learn.cpp \ + parameters/parameters.cpp \ + parameters/parameters.h \ + parameters/persistent.cpp \ + perf/perf.cpp \ + perf/perf.h \ + perf/perf_bundle.cpp \ + perf/perf_bundle.h \ + perf/perf_event.h \ + process/do_process.cpp \ + process/interrupt.cpp \ + process/interrupt.h \ + process/powerconsumer.cpp \ + process/powerconsumer.h \ + process/process.cpp \ + process/process.h \ + process/processdevice.cpp \ + process/processdevice.h \ + process/timer.cpp \ + process/timer.h \ + process/work.cpp \ + process/work.h \ + report/report-data-html.cpp \ + report/report-data-html.h \ + report/report-formatter-base.cpp \ + report/report-formatter-base.h \ + report/report-formatter-csv.cpp \ + report/report-formatter-csv.h \ + report/report-formatter-html.cpp \ + report/report-formatter-html.h \ + report/report-formatter.h \ + report/report-maker.cpp \ + report/report-maker.h \ + report/report.cpp \ + report/report.h \ + tuning/bluetooth.cpp \ + tuning/bluetooth.h \ + tuning/ethernet.cpp \ + tuning/ethernet.h \ + tuning/iw.c \ + tuning/iw.h \ + tuning/nl80211.h \ + tuning/runtime.cpp \ + tuning/runtime.h \ + tuning/tunable.cpp \ + tuning/tunable.h \ + tuning/tuning.cpp \ + tuning/tuning.h \ + tuning/tuningsysfs.cpp \ + tuning/tuningsysfs.h \ + tuning/tuningusb.cpp \ + tuning/tuningusb.h \ + tuning/tuningi2c.cpp \ + tuning/tuningi2c.h \ + tuning/wifi.cpp \ + tuning/wifi.h \ + wakeup/wakeup.cpp \ + wakeup/waketab.cpp \ + wakeup/wakeup_ethernet.cpp \ + wakeup/wakeup_usb.cpp \ + wakeup/wakeup_usb.h \ + wakeup/wakeup.h \ + wakeup/wakeup_ethernet.h + +powertop_CXXFLAGS = \ + -Wall \ + -Wformat \ + -Wshadow \ + -fno-omit-frame-pointer \ + -fstack-protector \ + $(GLIB2_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(NCURSES_CFLAGS) \ + $(PCIUTILS_CFLAGS) \ + $(PTHREAD_CFLAGS) + + +powertop_CPPFLAGS = \ + -DLOCALEDIR=\"$(localedir)\" \ + $(GLIB2_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(LIBZ_CFLAGS) \ + $(NCURSES_CFLAGS) \ + $(PCIUTILS_CFLAGS) \ + $(PTHREAD_CFLAGS) + +powertop_LDADD = \ + ../traceevent/libtraceevnet.la + +AM_LDFLAGS = \ + $(LIBNL_LIBS) \ + $(LIBS) \ + $(LIBZ_LIBS) \ + $(NCURSES_LIBS) \ + $(PCIUTILS_LIBS) \ + $(PTHREAD_LIBS) \ + $(RESOLV_LIBS) + +BUILT_SOURCES = css.h +CLEANFILES = css.h + +css.h: powertop.css + $(SHELL) ${srcdir}/csstoh.sh ${srcdir}/powertop.css css.h + +EXTRA_DIST = ${srcdir}/csstoh.sh diff --git a/src/calibrate/calibrate.cpp b/src/calibrate/calibrate.cpp new file mode 100644 index 0000000..745d544 --- /dev/null +++ b/src/calibrate/calibrate.cpp @@ -0,0 +1,435 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> +#include <algorithm> + +#include "calibrate.h" +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <math.h> +#include <sys/types.h> +#include <errno.h> +#include <limits.h> + +#include "../parameters/parameters.h" +extern "C" { +#include "../tuning/iw.h" +} + +#include <map> +#include <vector> +#include <string> + +using namespace std; + + +static vector<string> usb_devices; +static vector<string> rfkill_devices; +static vector<string> backlight_devices; +static vector<string> scsi_link_devices; +static int blmax; + +static map<string, string> saved_sysfs; + + +static volatile int stop_measurement; + +static int wireless_PS; + + +static void save_sysfs(const char *filename) +{ + char line[4096]; + ifstream file; + + file.open(filename, ios::in); + if (!file) + return; + file.getline(line, 4096); + file.close(); + + saved_sysfs[filename] = line; +} + +static void restore_all_sysfs(void) +{ + map<string, string>::iterator it; + + for (it = saved_sysfs.begin(); it != saved_sysfs.end(); it++) + write_sysfs(it->first, it->second); + + set_wifi_power_saving("wlan0", wireless_PS); +} + +static void find_all_usb_callback(const char *d_name) +{ + char filename[PATH_MAX]; + ifstream file; + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s/power/active_duration", d_name); + if (access(filename, R_OK) != 0) + return; + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s/power/idVendor", d_name); + file.open(filename, ios::in); + if (file) { + file.getline(filename, sizeof(filename)); + file.close(); + if (strcmp(filename, "1d6b") == 0) + return; + } + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s/power/control", d_name); + save_sysfs(filename); + usb_devices.push_back(filename); +} + +static void find_all_usb(void) +{ + process_directory("/sys/bus/usb/devices/", find_all_usb_callback); +} + +static void suspend_all_usb_devices(void) +{ + unsigned int i; + + for (i = 0; i < usb_devices.size(); i++) + write_sysfs(usb_devices[i], "auto\n"); +} + +static void find_all_rfkill_callback(const char *d_name) +{ + char filename[PATH_MAX]; + snprintf(filename, sizeof(filename), "/sys/class/rfkill/%s/soft", d_name); + if (access(filename, R_OK) != 0) + return; + save_sysfs(filename); + rfkill_devices.push_back(filename); +} + +static void find_all_rfkill(void) +{ + process_directory("/sys/class/rfkill/", find_all_rfkill_callback); +} + +static void rfkill_all_radios(void) +{ + unsigned int i; + + for (i = 0; i < rfkill_devices.size(); i++) + write_sysfs(rfkill_devices[i], "1\n"); +} +static void unrfkill_all_radios(void) +{ + unsigned int i; + + for (i = 0; i < rfkill_devices.size(); i++) + write_sysfs(rfkill_devices[i], "0\n"); +} + +static void find_backlight_callback(const char *d_name) +{ + char filename[PATH_MAX]; + snprintf(filename, sizeof(filename), "/sys/class/backlight/%s/brightness", d_name); + if (access(filename, R_OK) != 0) + return; + + save_sysfs(filename); + backlight_devices.push_back(filename); + snprintf(filename, sizeof(filename), "/sys/class/backlight/%s/max_brightness", d_name); + blmax = read_sysfs(filename); +} + +static void find_backlight(void) +{ + process_directory("/sys/class/backlight/", find_backlight_callback); +} + +static void lower_backlight(void) +{ + unsigned int i; + + for (i = 0; i < backlight_devices.size(); i++) + write_sysfs(backlight_devices[i], "0\n"); +} + +static void find_scsi_link_callback(const char *d_name) +{ + char filename[PATH_MAX]; + snprintf(filename, sizeof(filename), "/sys/class/scsi_host/%s/link_power_management_policy", d_name); + if (access(filename, R_OK)!=0) + return; + + save_sysfs(filename); + scsi_link_devices.push_back(filename); +} + +static void find_scsi_link(void) +{ + process_directory("/sys/class/scsi_host/", find_scsi_link_callback); +} + +static void set_scsi_link(const char *state) +{ + unsigned int i; + + for (i = 0; i < scsi_link_devices.size(); i++) + write_sysfs(scsi_link_devices[i], state); +} + + +static void *burn_cpu(void *dummy) +{ + volatile double d = 1.1; + + while (!stop_measurement) { + d = pow(d, 1.0001); + } + return NULL; +} + +static void *burn_cpu_wakeups(void *dummy) +{ + struct timespec tm; + + while (!stop_measurement) { + tm.tv_sec = 0; + tm.tv_nsec = (unsigned long)dummy; + nanosleep(&tm, NULL); + } + return NULL; +} + +static void *burn_disk(void *dummy) +{ + int fd; + char buffer[64*1024]; + char filename[256]; + + strcpy(filename ,"/tmp/powertop.XXXXXX"); + fd = mkstemp(filename); + + if (fd < 0) { + printf(_("Cannot create temp file\n")); + return NULL; + } + + while (!stop_measurement) { + lseek(fd, 0, SEEK_SET); + if(write(fd, buffer, 64*1024) == -1) + printf("Error: %s\n", strerror(errno)); + fdatasync(fd); + } + unlink(filename); + return NULL; +} + + +static void cpu_calibration(int threads) +{ + int i; + pthread_t thr; + + printf(_("Calibrating: CPU usage on %i threads\n"), threads); + + stop_measurement = 0; + for (i = 0; i < threads; i++) + pthread_create(&thr, NULL, burn_cpu, NULL); + + one_measurement(15, 15, NULL); + stop_measurement = 1; + sleep(1); +} + +static void wakeup_calibration(unsigned long interval) +{ + pthread_t thr; + + printf(_("Calibrating: CPU wakeup power consumption\n")); + + stop_measurement = 0; + + pthread_create(&thr, NULL, burn_cpu_wakeups, (void *)interval); + + one_measurement(15, 15, NULL); + stop_measurement = 1; + sleep(1); +} + +static void usb_calibration(void) +{ + unsigned int i; + + /* chances are one of the USB devices is bluetooth; unrfkill first */ + unrfkill_all_radios(); + printf(_("Calibrating USB devices\n")); + for (i = 0; i < usb_devices.size(); i++) { + printf(_(".... device %s \n"), usb_devices[i].c_str()); + suspend_all_usb_devices(); + write_sysfs(usb_devices[i], "on\n"); + one_measurement(15, 15, NULL); + suspend_all_usb_devices(); + sleep(3); + } + rfkill_all_radios(); + sleep(4); +} + +static void rfkill_calibration(void) +{ + unsigned int i; + + printf(_("Calibrating radio devices\n")); + for (i = 0; i < rfkill_devices.size(); i++) { + printf(_(".... device %s \n"), rfkill_devices[i].c_str()); + rfkill_all_radios(); + write_sysfs(rfkill_devices[i], "0\n"); + one_measurement(15, 15, NULL); + rfkill_all_radios(); + sleep(3); + } + for (i = 0; i < rfkill_devices.size(); i++) { + printf(_(".... device %s \n"), rfkill_devices[i].c_str()); + unrfkill_all_radios(); + write_sysfs(rfkill_devices[i], "1\n"); + one_measurement(15, 15, NULL); + unrfkill_all_radios(); + sleep(3); + } + rfkill_all_radios(); +} + +static void backlight_calibration(void) +{ + unsigned int i; + + printf(_("Calibrating backlight\n")); + for (i = 0; i < backlight_devices.size(); i++) { + char str[4096]; + printf(_(".... device %s \n"), backlight_devices[i].c_str()); + lower_backlight(); + one_measurement(15, 15, NULL); + sprintf(str, "%i\n", blmax / 4); + write_sysfs(backlight_devices[i], str); + one_measurement(15, 15, NULL); + + sprintf(str, "%i\n", blmax / 2); + write_sysfs(backlight_devices[i], str); + one_measurement(15, 15, NULL); + + sprintf(str, "%i\n", 3 * blmax / 4 ); + write_sysfs(backlight_devices[i], str); + one_measurement(15, 15, NULL); + + sprintf(str, "%i\n", blmax); + write_sysfs(backlight_devices[i], str); + one_measurement(15, 15, NULL); + lower_backlight(); + sleep(1); + } + printf(_("Calibrating idle\n")); + if(!system("DISPLAY=:0 /usr/bin/xset dpms force off")) + printf("System is not available\n"); + one_measurement(15, 15, NULL); + if(!system("DISPLAY=:0 /usr/bin/xset dpms force on")) + printf("System is not available\n"); +} + +static void idle_calibration(void) +{ + printf(_("Calibrating idle\n")); + if(!system("DISPLAY=:0 /usr/bin/xset dpms force off")) + printf("System is not available\n"); + one_measurement(15, 15, NULL); + if(!system("DISPLAY=:0 /usr/bin/xset dpms force on")) + printf("System is not available\n"); +} + + +static void disk_calibration(void) +{ + pthread_t thr; + + printf(_("Calibrating: disk usage \n")); + + set_scsi_link("min_power"); + + stop_measurement = 0; + pthread_create(&thr, NULL, burn_disk, NULL); + + one_measurement(15, 15, NULL); + stop_measurement = 1; + sleep(1); + + +} + + +void calibrate(void) +{ + find_all_usb(); + find_all_rfkill(); + find_backlight(); + find_scsi_link(); + wireless_PS = get_wifi_power_saving("wlan0"); + + save_sysfs("/sys/module/snd_hda_intel/parameters/power_save"); + + cout << _("Starting PowerTOP power estimate calibration \n"); + suspend_all_usb_devices(); + rfkill_all_radios(); + lower_backlight(); + set_wifi_power_saving("wlan0", 1); + + sleep(4); + + + idle_calibration(); + disk_calibration(); + backlight_calibration(); + + write_sysfs("/sys/module/snd_hda_intel/parameters/power_save", "1\n"); + cpu_calibration(1); + cpu_calibration(4); + wakeup_calibration(10000); + wakeup_calibration(100000); + wakeup_calibration(1000000); + set_wifi_power_saving("wlan0", 0); + usb_calibration(); + rfkill_calibration(); + + cout << _("Finishing PowerTOP power estimate calibration \n"); + + restore_all_sysfs(); + learn_parameters(300, 1); + printf(_("Parameters after calibration:\n")); + dump_parameter_bundle(); + save_parameters("saved_parameters.powertop"); + save_all_results("saved_results.powertop"); + +} diff --git a/src/calibrate/calibrate.h b/src/calibrate/calibrate.h new file mode 100644 index 0000000..de71938 --- /dev/null +++ b/src/calibrate/calibrate.h @@ -0,0 +1,32 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_CALIBRATE_H +#define __INCLUDE_GUARD_CALIBRATE_H + +extern void one_measurement(int seconds, int sample_interval, char *workload); +extern void calibrate(void); + + +#endif diff --git a/src/cpu/abstract_cpu.cpp b/src/cpu/abstract_cpu.cpp new file mode 100644 index 0000000..066891d --- /dev/null +++ b/src/cpu/abstract_cpu.cpp @@ -0,0 +1,535 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include "cpu.h" +#include "../lib.h" + +abstract_cpu::~abstract_cpu() +{ + unsigned int i=0; + for (i=0; i < cstates.size(); i++){ + delete cstates[i]; + } + cstates.clear(); + + for (i=0; i < pstates.size(); i++){ + delete pstates[i]; + } + pstates.clear(); +} + +void abstract_cpu::account_freq(uint64_t freq, uint64_t duration) +{ + struct frequency *state = NULL; + unsigned int i; + + for (i = 0; i < pstates.size(); i++) { + if (freq == pstates[i]->freq) { + state = pstates[i]; + break; + } + } + + + if (!state) { + state = new(std::nothrow) struct frequency; + + if (!state) + return; + + memset(state, 0, sizeof(*state)); + + pstates.push_back(state); + + state->freq = freq; + hz_to_human(freq, state->human_name); + if (freq == 0) + pt_strcpy(state->human_name, _("Idle")); + if (is_turbo(freq, max_frequency, max_minus_one_frequency)) + pt_strcpy(state->human_name, _("Turbo Mode")); + + state->after_count = 1; + } + + + state->time_after += duration; + + +} + +void abstract_cpu::freq_updated(uint64_t time) +{ + if(parent) + parent->calculate_freq(time); + old_idle = idle; +} + +void abstract_cpu::measurement_start(void) +{ + unsigned int i; + ifstream file; + char filename[4096]; + + last_stamp = 0; + + for (i = 0; i < cstates.size(); i++) + delete cstates[i]; + cstates.resize(0); + + for (i = 0; i < pstates.size(); i++) + delete pstates[i]; + pstates.resize(0); + + current_frequency = 0; + idle = false; + old_idle = true; + + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_available_frequencies", number); + file.open(filename, ios::in); + if (file) { + file >> max_frequency; + file >> max_minus_one_frequency; + file.close(); + } + + for (i = 0; i < children.size(); i++) + if (children[i]) + children[i]->measurement_start(); + + gettimeofday(&stamp_before, NULL); + + last_stamp = 0; + + for (i = 0; i < children.size(); i++) + if (children[i]) + children[i]->wiggle(); + +} + +void abstract_cpu::measurement_end(void) +{ + unsigned int i, j; + + total_stamp = 0; + gettimeofday(&stamp_after, NULL); + for (i = 0; i < children.size(); i++) + if (children[i]) + children[i]->wiggle(); + + time_factor = 1000000.0 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; + + + for (i = 0; i < children.size(); i++) + if (children[i]) + children[i]->measurement_end(); + + for (i = 0; i < children.size(); i++) + if (children[i]) { + for (j = 0; j < children[i]->cstates.size(); j++) { + struct idle_state *state; + state = children[i]->cstates[j]; + if (!state) + continue; + + update_cstate( state->linux_name, state->human_name, state->usage_before, state->duration_before, state->before_count); + finalize_cstate(state->linux_name, state->usage_after, state->duration_after, state->after_count); + } + for (j = 0; j < children[i]->pstates.size(); j++) { + struct frequency *state; + state = children[i]->pstates[j]; + if (!state) + continue; + + update_pstate( state->freq, state->human_name, state->time_before, state->before_count); + finalize_pstate(state->freq, state->time_after, state->after_count); + } + } + + for (i = 0; i < cstates.size(); i++) { + struct idle_state *state = cstates[i]; + + if (state->after_count == 0) + continue; + + if (state->after_count != state->before_count) + continue; + + state->usage_delta = (state->usage_after - state->usage_before) / state->after_count; + state->duration_delta = (state->duration_after - state->duration_before) / state->after_count; + } +} + +void abstract_cpu::insert_cstate(const char *linux_name, const char *human_name, uint64_t usage, uint64_t duration, int count, int level) +{ + struct idle_state *state; + const char *c; + + state = new(std::nothrow) struct idle_state; + + if (!state) + return; + + memset(state, 0, sizeof(*state)); + + cstates.push_back(state); + + pt_strcpy(state->linux_name, linux_name); + pt_strcpy(state->human_name, human_name); + + state->line_level = -1; + + c = human_name; + while (*c) { + if (strcmp(linux_name, "active")==0) { + state->line_level = LEVEL_C0; + break; + } + if (*c >= '0' && *c <='9') { + state->line_level = strtoull(c, NULL, 10); + if(*(c+1) != '-'){ + int greater_line_level = strtoull(c, NULL, 10); + for(unsigned int pos = 0; pos < cstates.size(); pos++){ + if(*c == cstates[pos]->human_name[1]){ + if(*(c+1) != cstates[pos]->human_name[2]){ + greater_line_level = max(greater_line_level, cstates[pos]->line_level); + state->line_level = greater_line_level + 1; + } + } + } + } + break; + } + c++; + } + + /* some architectures (ARM) don't have good numbers in their human name.. fall back to the linux name for those */ + c = linux_name; + while (*c && state->line_level < 0) { + if (*c >= '0' && *c <='9') { + state->line_level = strtoull(c, NULL, 10); + break; + } + c++; + } + + if (level >= 0) + state->line_level = level; + + state->usage_before = usage; + state->duration_before = duration; + state->before_count = count; +} + +void abstract_cpu::finalize_cstate(const char *linux_name, uint64_t usage, uint64_t duration, int count) +{ + unsigned int i; + struct idle_state *state = NULL; + + for (i = 0; i < cstates.size(); i++) { + if (strcmp(linux_name, cstates[i]->linux_name) == 0) { + state = cstates[i]; + break; + } + } + + if (!state) { + cout << "Invalid C state finalize " << linux_name << " \n"; + return; + } + + state->usage_after += usage; + state->duration_after += duration; + state->after_count += count; +} + +void abstract_cpu::update_cstate(const char *linux_name, const char *human_name, uint64_t usage, uint64_t duration, int count, int level) +{ + unsigned int i; + struct idle_state *state = NULL; + + for (i = 0; i < cstates.size(); i++) { + if (strcmp(linux_name, cstates[i]->linux_name) == 0) { + state = cstates[i]; + break; + } + } + + if (!state) { + insert_cstate(linux_name, human_name, usage, duration, count, level); + return; + } + + state->usage_before += usage; + state->duration_before += duration; + state->before_count += count; + +} + +int abstract_cpu::has_cstate_level(int level) +{ + unsigned int i; + + if (level == LEVEL_HEADER) + return 1; + + for (i = 0; i < cstates.size(); i++) + if (cstates[i]->line_level == level) + return 1; + + for (i = 0; i < children.size(); i++) + if (children[i]) + if (children[i]->has_cstate_level(level)) + return 1; + return 0; +} + +int abstract_cpu::has_pstate_level(int level) +{ + unsigned int i; + + if (level == LEVEL_HEADER) + return 1; + + if (level >= 0 && level < (int)pstates.size()) + return 1; + + for (i = 0; i < children.size(); i++) + if (children[i]) + if (children[i]->has_pstate_level(level)) + return 1; + return 0; +} + + + +void abstract_cpu::insert_pstate(uint64_t freq, const char *human_name, uint64_t duration, int count) +{ + struct frequency *state; + + state = new(std::nothrow) struct frequency; + + if (!state) + return; + + memset(state, 0, sizeof(*state)); + + pstates.push_back(state); + + state->freq = freq; + pt_strcpy(state->human_name, human_name); + + + state->time_before = duration; + state->before_count = count; +} + +void abstract_cpu::finalize_pstate(uint64_t freq, uint64_t duration, int count) +{ + unsigned int i; + struct frequency *state = NULL; + + for (i = 0; i < pstates.size(); i++) { + if (freq == pstates[i]->freq) { + state = pstates[i]; + break; + } + } + + if (!state) { + cout << "Invalid P state finalize " << freq << " \n"; + return; + } + state->time_after += duration; + state->after_count += count; + +} + +void abstract_cpu::update_pstate(uint64_t freq, const char *human_name, uint64_t duration, int count) +{ + unsigned int i; + struct frequency *state = NULL; + + for (i = 0; i < pstates.size(); i++) { + if (freq == pstates[i]->freq) { + state = pstates[i]; + break; + } + } + + if (!state) { + insert_pstate(freq, human_name, duration, count); + return; + } + + state->time_before += duration; + state->before_count += count; +} + + +void abstract_cpu::calculate_freq(uint64_t time) +{ + uint64_t freq = 0; + bool is_idle = true; + unsigned int i; + + /* calculate the maximum frequency of all children */ + for (i = 0; i < children.size(); i++) + if (children[i] && children[i]->has_pstates()) { + uint64_t f = 0; + if (!children[i]->idle) { + f = children[i]->current_frequency; + is_idle = false; + } + if (f > freq) + freq = f; + } + + current_frequency = freq; + idle = is_idle; + freq_updated(time); +} + +void abstract_cpu::change_effective_frequency(uint64_t time, uint64_t frequency) +{ + unsigned int i; + uint64_t time_delta, fr; + + if (last_stamp) + time_delta = time - last_stamp; + else + time_delta = 1; + + fr = effective_frequency; + if (old_idle) + fr = 0; + + account_freq(fr, time_delta); + + effective_frequency = frequency; + last_stamp = time; + + /* propagate to all children */ + for (i = 0; i < children.size(); i++) + if (children[i]) { + children[i]->change_effective_frequency(time, frequency); + } +} + + +void abstract_cpu::wiggle(void) +{ + char filename[PATH_MAX]; + ifstream ifile; + ofstream ofile; + uint64_t minf,maxf; + uint64_t setspeed = 0; + + /* wiggle a CPU so that we have a record of it at the start and end of the perf trace */ + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_max_freq", first_cpu); + ifile.open(filename, ios::in); + ifile >> maxf; + ifile.close(); + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_min_freq", first_cpu); + ifile.open(filename, ios::in); + ifile >> minf; + ifile.close(); + + /* In case of the userspace governor, remember the old setspeed setting, it will be affected by wiggle */ + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_setspeed", first_cpu); + ifile.open(filename, ios::in); + /* Note that non-userspace governors report "<unsupported>". In that case ifile will fail and setspeed remains 0 */ + ifile >> setspeed; + ifile.close(); + + ofile.open(filename, ios::out); + ofile << maxf; + ofile.close(); + ofile.open(filename, ios::out); + ofile << minf; + ofile.close(); + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_max_freq", first_cpu); + ofile.open(filename, ios::out); + ofile << minf; + ofile.close(); + ofile.open(filename, ios::out); + ofile << maxf; + ofile.close(); + + if (setspeed != 0) { + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_setspeed", first_cpu); + ofile.open(filename, ios::out); + ofile << setspeed; + ofile.close(); + } +} +uint64_t abstract_cpu::total_pstate_time(void) +{ + unsigned int i; + uint64_t stamp = 0; + + for (i = 0; i < pstates.size(); i++) + stamp += pstates[i]->time_after; + + return stamp; +} + + +void abstract_cpu::validate(void) +{ + unsigned int i; + + for (i = 0; i < children.size(); i++) { + if (children[i]) + children[i]->validate(); + } +} + +void abstract_cpu::reset_pstate_data(void) +{ + unsigned int i; + + for (i = 0; i < pstates.size(); i++) { + pstates[i]->time_before = 0; + pstates[i]->time_after = 0; + } + for (i = 0; i < cstates.size(); i++) { + cstates[i]->duration_before = 0; + cstates[i]->duration_after = 0; + cstates[i]->before_count = 0; + cstates[i]->after_count = 0; + } + + for (i = 0; i < children.size(); i++) + if (children[i]) + children[i]->reset_pstate_data(); +} diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp new file mode 100644 index 0000000..1c12765 --- /dev/null +++ b/src/cpu/cpu.cpp @@ -0,0 +1,1075 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> +#include <vector> +#include <string.h> +#include <stdlib.h> +#include <ncurses.h> +#include <unistd.h> +#include "cpu.h" +#include "cpudevice.h" +#include "cpu_rapl_device.h" +#include "dram_rapl_device.h" +#include "intel_cpus.h" +#include "../parameters/parameters.h" + +#include "../perf/perf_bundle.h" +#include "../lib.h" +#include "../display.h" +#include "../report/report.h" +#include "../report/report-maker.h" +#include "../report/report-data-html.h" + +static class abstract_cpu system_level; + +vector<class abstract_cpu *> all_cpus; + +static class perf_bundle * perf_events; + + + +class perf_power_bundle: public perf_bundle +{ + virtual void handle_trace_point(void *trace, int cpu, uint64_t time); + +}; + + +static class abstract_cpu * new_package(int package, int cpu, char * vendor, int family, int model) +{ + class abstract_cpu *ret = NULL; + class cpudevice *cpudev; + class cpu_rapl_device *cpu_rapl_dev; + class dram_rapl_device *dram_rapl_dev; + + char packagename[128]; + if (strcmp(vendor, "GenuineIntel") == 0) + if (family == 6) + if (is_supported_intel_cpu(model, cpu)) { + ret = new class nhm_package(model); + ret->set_intel_MSR(true); + } + + if (!ret) { + ret = new class cpu_package; + ret->set_intel_MSR(false); + } + + ret->set_number(package, cpu); + ret->set_type("Package"); + ret->childcount = 0; + + snprintf(packagename, sizeof(packagename), _("cpu package %i"), cpu); + cpudev = new class cpudevice(_("cpu package"), packagename, ret); + all_devices.push_back(cpudev); + + snprintf(packagename, sizeof(packagename), _("package-%i"), cpu); + cpu_rapl_dev = new class cpu_rapl_device(cpudev, _("cpu rapl package"), packagename, ret); + if (cpu_rapl_dev->device_present()) + all_devices.push_back(cpu_rapl_dev); + else + delete cpu_rapl_dev; + + snprintf(packagename, sizeof(packagename), _("package-%i"), cpu); + dram_rapl_dev = new class dram_rapl_device(cpudev, _("dram rapl package"), packagename, ret); + if (dram_rapl_dev->device_present()) + all_devices.push_back(dram_rapl_dev); + else + delete dram_rapl_dev; + + return ret; +} + +static class abstract_cpu * new_core(int core, int cpu, char * vendor, int family, int model) +{ + class abstract_cpu *ret = NULL; + + if (strcmp(vendor, "GenuineIntel") == 0) + if (family == 6) + if (is_supported_intel_cpu(model, cpu)) { + ret = new class nhm_core(model); + ret->set_intel_MSR(true); + } + + if (!ret) { + ret = new class cpu_core; + ret->set_intel_MSR(false); + } + + ret->set_number(core, cpu); + ret->childcount = 0; + ret->set_type("Core"); + + return ret; +} + +static class abstract_cpu * new_i965_gpu(void) +{ + class abstract_cpu *ret = NULL; + + ret = new class i965_core; + ret->childcount = 0; + ret->set_type("GPU"); + + return ret; +} + +static class abstract_cpu * new_cpu(int number, char * vendor, int family, int model) +{ + class abstract_cpu * ret = NULL; + + if (strcmp(vendor, "GenuineIntel") == 0) + if (family == 6) + if (is_supported_intel_cpu(model, number)) { + ret = new class nhm_cpu; + ret->set_intel_MSR(true); + } + + if (!ret) { + ret = new class cpu_linux; + ret->set_intel_MSR(false); + } + ret->set_number(number, number); + ret->set_type("CPU"); + ret->childcount = 0; + + return ret; +} + + + + +static void handle_one_cpu(unsigned int number, char *vendor, int family, int model) +{ + char filename[PATH_MAX]; + ifstream file; + unsigned int package_number = 0; + unsigned int core_number = 0; + class abstract_cpu *package, *core, *cpu; + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/topology/core_id", number); + file.open(filename, ios::in); + if (file) { + file >> core_number; + file.close(); + } + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/topology/physical_package_id", number); + file.open(filename, ios::in); + if (file) { + file >> package_number; + if (package_number == (unsigned int) -1) + package_number = 0; + file.close(); + } + + + if (system_level.children.size() <= package_number) + system_level.children.resize(package_number + 1, NULL); + + if (!system_level.children[package_number]) { + system_level.children[package_number] = new_package(package_number, number, vendor, family, model); + system_level.childcount++; + } + + package = system_level.children[package_number]; + package->parent = &system_level; + + if (package->children.size() <= core_number) + package->children.resize(core_number + 1, NULL); + + if (!package->children[core_number]) { + package->children[core_number] = new_core(core_number, number, vendor, family, model); + package->childcount++; + } + + core = package->children[core_number]; + core->parent = package; + + if (core->children.size() <= number) + core->children.resize(number + 1, NULL); + if (!core->children[number]) { + core->children[number] = new_cpu(number, vendor, family, model); + core->childcount++; + } + + cpu = core->children[number]; + cpu->parent = core; + + if (number >= all_cpus.size()) + all_cpus.resize(number + 1, NULL); + all_cpus[number] = cpu; +} + +static void handle_i965_gpu(void) +{ + unsigned int core_number = 0; + class abstract_cpu *package; + + + package = system_level.children[0]; + + core_number = package->children.size(); + + if (package->children.size() <= core_number) + package->children.resize(core_number + 1, NULL); + + if (!package->children[core_number]) { + package->children[core_number] = new_i965_gpu(); + package->childcount++; + } +} + + +void enumerate_cpus(void) +{ + ifstream file; + char line[4096]; + + int number = -1; + char vendor[128]; + int family = 0; + int model = 0; + + file.open("/proc/cpuinfo", ios::in); + + if (!file) + return; + /* Not all /proc/cpuinfo include "vendor_id\t". */ + vendor[0] = '\0'; + + while (file) { + + file.getline(line, sizeof(line)); + if (strncmp(line, "vendor_id\t",10) == 0) { + char *c; + c = strchr(line, ':'); + if (c) { + c++; + if (*c == ' ') + c++; + pt_strcpy(vendor, c); + } + } + if (strncmp(line, "processor\t",10) == 0) { + char *c; + c = strchr(line, ':'); + if (c) { + c++; + number = strtoull(c, NULL, 10); + } + } + if (strncmp(line, "cpu family\t",11) == 0) { + char *c; + c = strchr(line, ':'); + if (c) { + c++; + family = strtoull(c, NULL, 10); + } + } + if (strncmp(line, "model\t",6) == 0) { + char *c; + c = strchr(line, ':'); + if (c) { + c++; + model = strtoull(c, NULL, 10); + } + } + /* on x86 and others 'bogomips' is last + * on ARM it *can* be bogomips, or 'CPU revision' + * on POWER, it's revision + */ + if (strncasecmp(line, "bogomips\t", 9) == 0 + || strncasecmp(line, "CPU revision\t", 13) == 0 + || strncmp(line, "revision", 8) == 0) { + if (number == -1) { + /* Not all /proc/cpuinfo include "processor\t". */ + number = 0; + } + if (number >= 0) { + handle_one_cpu(number, vendor, family, model); + set_max_cpu(number); + number = -2; + } + } + } + + + file.close(); + + if (access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK) == 0) + handle_i965_gpu(); + + perf_events = new perf_power_bundle(); + + if (!perf_events->add_event("power:cpu_idle")){ + perf_events->add_event("power:power_start"); + perf_events->add_event("power:power_end"); + } + if (!perf_events->add_event("power:cpu_frequency")) + perf_events->add_event("power:power_frequency"); + +} + +void start_cpu_measurement(void) +{ + perf_events->start(); + system_level.measurement_start(); +} + +void end_cpu_measurement(void) +{ + system_level.measurement_end(); + perf_events->stop(); +} + +static void expand_string(char *string, unsigned int newlen) +{ + while (strlen(string) < newlen) + strcat(string, " "); +} + +static int has_state_level(class abstract_cpu *acpu, int state, int line) +{ + switch (state) { + case PSTATE: + return acpu->has_pstate_level(line); + break; + case CSTATE: + return acpu->has_cstate_level(line); + break; + } + return 0; +} + +static const char * fill_state_name(class abstract_cpu *acpu, int state, int line, char *buf) +{ + switch (state) { + case PSTATE: + return acpu->fill_pstate_name(line, buf); + break; + case CSTATE: + return acpu->fill_cstate_name(line, buf); + break; + } + return "-EINVAL"; +} + +static const char * fill_state_line(class abstract_cpu *acpu, int state, int line, + char *buf, const char *sep = "") +{ + switch (state) { + case PSTATE: + return acpu->fill_pstate_line(line, buf); + break; + case CSTATE: + return acpu->fill_cstate_line(line, buf, sep); + break; + } + return "-EINVAL"; +} + +static int get_cstates_num(void) +{ + unsigned int package, core, cpu; + class abstract_cpu *_package, * _core, * _cpu; + unsigned int i; + int cstates_num; + + for (package = 0, cstates_num = 0; + package < system_level.children.size(); package++) { + _package = system_level.children[package]; + if (_package == NULL) + continue; + + /* walk package cstates and get largest cstates number */ + for (i = 0; i < _package->cstates.size(); i++) + cstates_num = std::max(cstates_num, + (_package->cstates[i])->line_level); + + /* + * for each core in this package, walk core cstates and get + * largest cstates number + */ + for (core = 0; core < _package->children.size(); core++) { + _core = _package->children[core]; + if (_core == NULL) + continue; + + for (i = 0; i < _core->cstates.size(); i++) + cstates_num = std::max(cstates_num, + (_core->cstates[i])->line_level); + + /* + * for each core, walk the logical cpus in case + * there is are more linux cstates than hw cstates + */ + for (cpu = 0; cpu < _core->children.size(); cpu++) { + _cpu = _core->children[cpu]; + if (_cpu == NULL) + continue; + + for (i = 0; i < _cpu->cstates.size(); i++) + cstates_num = std::max(cstates_num, + (_cpu->cstates[i])->line_level); + } + } + } + + return cstates_num; +} + +void report_display_cpu_cstates(void) +{ + char buffer[512], buffer2[512], tmp_num[50]; + unsigned int package, core, cpu; + int line, cstates_num, title=0, core_num=0; + class abstract_cpu *_package, *_core = NULL, * _cpu; + const char* core_type = NULL; + + cstates_num = get_cstates_num(); + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "clear_block", "cpuidle"); + + /* Set Table attributes, rows, and cols */ + table_attributes std_table_css; + table_size pkg_tbl_size; + table_size core_tbl_size; + table_size cpu_tbl_size; + + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Report add section */ + report.add_div(&div_attr); + report.add_title(&title_attr, __("Processor Idle State Report")); + + /* Set array of data in row Major order */ + int idx1, idx2, idx3; + string tmp_str; + + for (package = 0; package < system_level.children.size(); package++) { + bool first_core = true; + idx1=0; + idx2=0; + idx3=0; + + _package = system_level.children[package]; + if (!_package) + continue; + /* Tables for PKG, CORE, CPU */ + pkg_tbl_size.cols=2; + pkg_tbl_size.rows= ((cstates_num+1)-LEVEL_HEADER)+1; + string *pkg_data = new string[pkg_tbl_size.cols * pkg_tbl_size.rows]; + + core_tbl_size.cols=2; + core_tbl_size.rows=(cstates_num *_package->children.size()) + + _package->children.size(); + string *core_data = new string[core_tbl_size.cols * core_tbl_size.rows]; + int num_cpus=0, num_cores=0; + + for (core = 0; core < _package->children.size(); core++) { + _core = _package->children[core]; + if (!_core) + continue; + core_type = _core->get_type(); + if (core_type != NULL) + if (strcmp(core_type, "Core") == 0 ) + num_cores+=1; + + for (cpu = 0; cpu < _core->children.size(); cpu++) { + _cpu = _core->children[cpu]; + if (!_cpu) + continue; + num_cpus+=1; + } + } + cpu_tbl_size.cols=(2 * (num_cpus / num_cores)) + 1; + cpu_tbl_size.rows = ((cstates_num+1-LEVEL_HEADER) * _package->children.size()) + + _package->children.size(); + string *cpu_data = new string[cpu_tbl_size.cols * cpu_tbl_size.rows]; + + for (core = 0; core < _package->children.size(); core++) { + cpu_data[idx3]=" "; + idx3+=1; + _core = _package->children[core]; + + if (!_core) + continue; + + /* *** PKG STARTS *** */ + for (line = LEVEL_HEADER; line <= cstates_num; line++) { + bool first_cpu = true; + if (!_package->has_cstate_level(line)) + continue; + buffer[0] = 0; + buffer2[0] = 0; + if (line == LEVEL_HEADER) { + if (first_core) { + pkg_data[idx1]=__("Package"); + idx1+=1; + sprintf(tmp_num,"%d", _package->get_number()); + pkg_data[idx1]= string(tmp_num); + idx1+=1; + } + } else if (first_core) { + tmp_str=string(_package->fill_cstate_name(line, buffer)); + pkg_data[idx1]=(tmp_str=="" ? " " : tmp_str); + idx1+=1; + tmp_str=string(_package->fill_cstate_line(line, buffer2)); + pkg_data[idx1]=(tmp_str=="" ? " " : tmp_str); + idx1+=1; + } + + /* *** CORE STARTS *** */ + if (!_core->can_collapse()) { + buffer[0] = 0; + buffer2[0] = 0; + + /* + * Patch for compatibility with Ryzen processors + * See https://github.com/fenrus75/powertop/issues/64 + */ + if(idx2 >= core_tbl_size.cols * core_tbl_size.rows) break; + + if (line == LEVEL_HEADER) { + /* Here we need to check for which core type we + * are using. Do not use the core type for the + * report.addf as it breaks an important macro use + * for translation decision making for the reports. + * */ + core_type = _core->get_type(); + if (core_type != NULL) { + if (strcmp(core_type, "Core") == 0 ) { + core_data[idx2]=""; + idx2+=1; + snprintf(tmp_num, sizeof(tmp_num), __("Core %d"), _core->get_number()); + core_data[idx2]=string(tmp_num); + idx2+=1; + core_num+=1; + } else { + core_data[idx2]=""; + idx2+=1; + snprintf(tmp_num, sizeof(tmp_num), __("GPU %d"), _core->get_number()); + core_data[idx2]=string(tmp_num); + idx2+=1; + } + } + } else { + + + tmp_str=string(_core->fill_cstate_name(line, buffer)); + core_data[idx2]=(tmp_str=="" ? " " : tmp_str); + idx2+=1; + tmp_str=string(_core->fill_cstate_line(line, buffer2)); + core_data[idx2]=(tmp_str=="" ? " " : tmp_str); + idx2+=1; + } + } + // *** CPU STARTS *** + for (cpu = 0; cpu < _core->children.size(); cpu++) { + _cpu = _core->children[cpu]; + + if (!_cpu) + continue; + if (line == LEVEL_HEADER) { + cpu_data[idx3] = __("CPU"); + idx3+=1; + sprintf(tmp_num,"%d",_cpu->get_number()); + cpu_data[idx3]=string(tmp_num); + idx3+=1; + continue; + } + + if (first_cpu) { + title+=1; + cpu_data[idx3]=(string(_cpu->fill_cstate_name(line, buffer))); + idx3+=1; + first_cpu = false; + } + + buffer[0] = 0; + tmp_str=string(_cpu->fill_cstate_percentage(line, buffer)); + cpu_data[idx3]=(tmp_str=="" ? " " : tmp_str); + idx3+=1; + + if (line != LEVEL_C0){ + tmp_str=string(_cpu->fill_cstate_time(line, buffer)); + cpu_data[idx3]=(tmp_str=="" ? " " : tmp_str); + idx3+=1; + } else { + cpu_data[idx3]=" "; + idx3+=1; + } + } + } + first_core = false; + } + + /* Report Output */ + if(core_num > 0) + title=title/core_num; + else if(_core && _core->children.size() > 0) + title=title/_core->children.size(); + + init_pkg_table_attr(&std_table_css, pkg_tbl_size.rows, pkg_tbl_size.cols); + report.add_table(pkg_data, &std_table_css); + if (!_core->can_collapse()){ + init_core_table_attr(&std_table_css, title+1, core_tbl_size.rows, + core_tbl_size.cols); + report.add_table(core_data, &std_table_css); + } + init_cpu_table_attr(&std_table_css, title+1, cpu_tbl_size.rows, + cpu_tbl_size.cols); + report.add_table(cpu_data, &std_table_css); + delete [] pkg_data; + delete [] core_data; + delete [] cpu_data; + } + report.end_div(); +} + +void report_display_cpu_pstates(void) +{ + char buffer[512], buffer2[512], tmp_num[50]; + unsigned int package, core, cpu; + int line, title=0; + class abstract_cpu *_package, *_core = NULL, * _cpu; + unsigned int i, pstates_num; + const char* core_type = NULL; + + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "clear_block", "cpufreq"); + + /* Set Table attributes, rows, and cols */ + table_attributes std_table_css; + table_size pkg_tbl_size; + table_size core_tbl_size; + table_size cpu_tbl_size; + + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Report add section */ + report.add_div(&div_attr); + report.add_title(&title_attr, __("Processor Frequency Report")); + + /* Set array of data in row Major order */ + int idx1, idx2, idx3, num_cpus=0, num_cores=0; + string tmp_str; + + for (i = 0, pstates_num = 0; i < all_cpus.size(); i++) { + if (all_cpus[i]) + pstates_num = std::max<unsigned int>(pstates_num, + all_cpus[i]->pstates.size()); + } + + for (package = 0; package < system_level.children.size(); package++) { + bool first_core = true; + idx1=0; + idx2=0; + idx3=0; + + _package = system_level.children[package]; + if (!_package) + continue; + + /* Tables for PKG, CORE, CPU */ + pkg_tbl_size.cols=2; + pkg_tbl_size.rows=((pstates_num+1)-LEVEL_HEADER)+2; + string *pkg_data = new string[pkg_tbl_size.cols * pkg_tbl_size.rows]; + + core_tbl_size.cols=2; + core_tbl_size.rows=((pstates_num+2) *_package->children.size()); + string *core_data = new string[core_tbl_size.cols * core_tbl_size.rows]; + + /* PKG */ + num_cpus=0; + num_cores=0; + for (core = 0; core < _package->children.size(); core++) { + _core = _package->children[core]; + if (!_core) + continue; + + core_type = _core->get_type(); + if (core_type != NULL) + if (strcmp(core_type, "Core") == 0 ) + num_cores+=1; + + for (cpu = 0; cpu < _core->children.size(); cpu++) { + _cpu = _core->children[cpu]; + if (!_cpu) + continue; + num_cpus+=1; + } + } + cpu_tbl_size.cols= (num_cpus/ num_cores) + 1; + cpu_tbl_size.rows= (pstates_num+2) * _package->children.size() + + _package->children.size(); + string *cpu_data = new string[cpu_tbl_size.cols * cpu_tbl_size.rows]; + + /* Core */ + for (core = 0; core < _package->children.size(); core++) { + cpu_data[idx3]=" "; + idx3+=1; + _core = _package->children[core]; + if (!_core) + continue; + + if (!_core->has_pstates()) + continue; + + for (line = LEVEL_HEADER; line < (int)pstates_num; line++) { + bool first_cpu = true; + + if (!_package->has_pstate_level(line)) + continue; + + buffer[0] = 0; + buffer2[0] = 0; + if (first_core) { + if (line == LEVEL_HEADER) { + pkg_data[idx1]=__("Package"); + idx1+=1; + sprintf(tmp_num,"%d", _package->get_number()); + pkg_data[idx1]= string(tmp_num); + idx1+=1; + } else { + tmp_str=string(_package->fill_pstate_name(line, buffer)); + pkg_data[idx1]=(tmp_str=="" ? " " : tmp_str); + idx1+=1; + tmp_str=string(_package->fill_pstate_line(line, buffer2)); + pkg_data[idx1]=(tmp_str=="" ? " " : tmp_str); + idx1+=1; + } + } + + + if (!_core->can_collapse()) { + buffer[0] = 0; + buffer2[0] = 0; + if (line == LEVEL_HEADER) { + core_data[idx2]=""; + idx2+=1; + snprintf(tmp_num, sizeof(tmp_num), __("Core %d"), _core->get_number()); + core_data[idx2]=string(tmp_num); + idx2+=1; + } else { + tmp_str=string(_core->fill_pstate_name(line, buffer)); + core_data[idx2]= (tmp_str=="" ? " " : tmp_str); + idx2+=1; + tmp_str=string(_core->fill_pstate_line(line, buffer2)); + core_data[idx2]= (tmp_str=="" ? " " : tmp_str); + idx2+=1; + } + } + + /* CPU */ + for (cpu = 0; cpu < _core->children.size(); cpu++) { + buffer[0] = 0; + _cpu = _core->children[cpu]; + if (!_cpu) + continue; + + if (line == LEVEL_HEADER) { + snprintf(tmp_num, sizeof(tmp_num), __("CPU %d"), _cpu->get_number()); + cpu_data[idx3] = string(tmp_num); + idx3+=1; + continue; + } + + if (first_cpu) { + tmp_str=string(_cpu->fill_pstate_name(line, buffer)); + cpu_data[idx3]=(tmp_str=="" ? " " : tmp_str); + idx3+=1; + first_cpu = false; + } + + buffer[0] = 0; + tmp_str=string(_cpu->fill_pstate_line(line, buffer)); + cpu_data[idx3]=(tmp_str=="" ? " " : tmp_str); + idx3+=1; + } + } + first_core = false; + } + init_pkg_table_attr(&std_table_css, pkg_tbl_size.rows, pkg_tbl_size.cols); + report.add_table(pkg_data, &std_table_css); + if(_core && !_core->can_collapse()){ + title=pstates_num+2; + init_core_table_attr(&std_table_css, title, + core_tbl_size.rows, core_tbl_size.cols); + report.add_table(core_data, &std_table_css); + } else { + title=pstates_num+1; + } + + init_cpu_table_attr(&std_table_css, title, + cpu_tbl_size.rows, cpu_tbl_size.cols); + report.add_table(cpu_data, &std_table_css); + delete [] pkg_data; + delete [] core_data; + delete [] cpu_data; + } + report.end_div(); +} + +void impl_w_display_cpu_states(int state) +{ + WINDOW *win; + char buffer[128]; + char linebuf[1024]; + unsigned int package, core, cpu; + int line, loop, cstates_num, pstates_num; + class abstract_cpu *_package, * _core, * _cpu; + int ctr = 0; + unsigned int i; + + cstates_num = get_cstates_num(); + + for (i = 0, pstates_num = 0; i < all_cpus.size(); i++) { + if (!all_cpus[i]) + continue; + + pstates_num = std::max<int>(pstates_num, all_cpus[i]->pstates.size()); + } + + if (state == PSTATE) { + win = get_ncurses_win("Frequency stats"); + loop = pstates_num; + } else { + win = get_ncurses_win("Idle stats"); + loop = cstates_num; + } + + if (!win) + return; + + wclear(win); + wmove(win, 2,0); + + for (package = 0; package < system_level.children.size(); package++) { + int first_pkg = 0; + _package = system_level.children[package]; + if (!_package) + continue; + + for (core = 0; core < _package->children.size(); core++) { + _core = _package->children[core]; + if (!_core) + continue; + if (!_core->has_pstates() && state == PSTATE) + continue; + + for (line = LEVEL_HEADER; line <= loop; line++) { + int first = 1; + ctr = 0; + linebuf[0] = 0; + + if (!has_state_level(_package, state, line)) + continue; + + buffer[0] = 0; + if (first_pkg == 0) { + strcat(linebuf, fill_state_name(_package, state, line, buffer)); + expand_string(linebuf, ctr + 10); + strcat(linebuf, fill_state_line(_package, state, line, buffer)); + } + ctr += 20; + expand_string(linebuf, ctr); + + strcat(linebuf, "| "); + ctr += strlen("| "); + + if (!_core->can_collapse()) { + buffer[0] = 0; + strcat(linebuf, fill_state_name(_core, state, line, buffer)); + expand_string(linebuf, ctr + 10); + strcat(linebuf, fill_state_line(_core, state, line, buffer)); + ctr += 20; + expand_string(linebuf, ctr); + + strcat(linebuf, "| "); + ctr += strlen("| "); + } + + for (cpu = 0; cpu < _core->children.size(); cpu++) { + _cpu = _core->children[cpu]; + if (!_cpu) + continue; + + if (first == 1) { + strcat(linebuf, fill_state_name(_cpu, state, line, buffer)); + expand_string(linebuf, ctr + 10); + first = 0; + ctr += 12; + } + buffer[0] = 0; + strcat(linebuf, fill_state_line(_cpu, state, line, buffer)); + ctr += 10; + expand_string(linebuf, ctr); + + } + strcat(linebuf, "\n"); + wprintw(win, "%s", linebuf); + } + wprintw(win, "\n"); + first_pkg++; + } + } +} + +void w_display_cpu_pstates(void) +{ + impl_w_display_cpu_states(PSTATE); +} + +void w_display_cpu_cstates(void) +{ + impl_w_display_cpu_states(CSTATE); +} + +struct power_entry { +#ifndef __i386__ + int dummy; +#endif + int64_t type; + int64_t value; +} __attribute__((packed)); + + +void perf_power_bundle::handle_trace_point(void *trace, int cpunr, uint64_t time) +{ + struct event_format *event; + struct pevent_record rec; /* holder */ + class abstract_cpu *cpu; + int type; + + rec.data = trace; + + type = pevent_data_type(perf_event::pevent, &rec); + event = pevent_find_event(perf_event::pevent, type); + + if (!event) + return; + + if (cpunr >= (int)all_cpus.size()) { + cout << "INVALID cpu nr in handle_trace_point\n"; + return; + } + + cpu = all_cpus[cpunr]; + +#if 0 + unsigned int i; + printf("Time is %llu \n", time); + for (i = 0; i < system_level.children.size(); i++) + if (system_level.children[i]) + system_level.children[i]->validate(); +#endif + unsigned long long val; + int ret; + if (strcmp(event->name, "cpu_idle")==0) { + + ret = pevent_get_field_val(NULL, event, "state", &rec, &val, 0); + if (ret < 0) { + fprintf(stderr, _("cpu_idle event returned no state?\n")); + exit(-1); + } + + if (val == (unsigned int)-1) + cpu->go_unidle(time); + else + cpu->go_idle(time); + } + + if (strcmp(event->name, "power_frequency") == 0 + || strcmp(event->name, "cpu_frequency") == 0){ + + ret = pevent_get_field_val(NULL, event, "state", &rec, &val, 0); + if (ret < 0) { + fprintf(stderr, _("power or cpu_frequency event returned no state?\n")); + exit(-1); + } + + cpu->change_freq(time, val); + } + + if (strcmp(event->name, "power_start")==0) + cpu->go_idle(time); + if (strcmp(event->name, "power_end")==0) + cpu->go_unidle(time); + +#if 0 + unsigned int i; + for (i = 0; i < system_level.children.size(); i++) + if (system_level.children[i]) + system_level.children[i]->validate(); +#endif +} + +void process_cpu_data(void) +{ + unsigned int i; + system_level.reset_pstate_data(); + + perf_events->process(); + + for (i = 0; i < system_level.children.size(); i++) + if (system_level.children[i]) + system_level.children[i]->validate(); + +} + +void end_cpu_data(void) +{ + system_level.reset_pstate_data(); + + perf_events->clear(); +} + +void clear_cpu_data(void) +{ + if (perf_events) + perf_events->release(); + delete perf_events; +} + + +void clear_all_cpus(void) +{ + unsigned int i; + for (i = 0; i < all_cpus.size(); i++) { + delete all_cpus[i]; + } + all_cpus.clear(); +} diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h new file mode 100644 index 0000000..9114764 --- /dev/null +++ b/src/cpu/cpu.h @@ -0,0 +1,234 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#ifndef __INCLUDE_GUARD_CPUDEV_H +#define __INCLUDE_GUARD_CPUDEV_H + +#include <iostream> +#include <vector> +#include <string> +#include <stdint.h> +#include <sys/time.h> + +using namespace std; + +class abstract_cpu; + +#define LEVEL_C0 -1 +#define LEVEL_HEADER -2 + +#define PSTATE 1 +#define CSTATE 2 + +struct idle_state { + char linux_name[16]; /* state0 etc.. cpuidle name */ + char human_name[32]; + + uint64_t usage_before; + uint64_t usage_after; + uint64_t usage_delta; + + uint64_t duration_before; + uint64_t duration_after; + uint64_t duration_delta; + + int before_count; + int after_count; + + int line_level; +}; + +struct frequency { + char human_name[32]; + int line_level; + + uint64_t freq; + + uint64_t time_after; + uint64_t time_before; + + int before_count; + int after_count; + + double display_value; +}; + +class abstract_cpu +{ +protected: + int first_cpu; + struct timeval stamp_before, stamp_after; + double time_factor; + uint64_t max_frequency = 0; + uint64_t max_minus_one_frequency = 0; + + virtual void account_freq(uint64_t frequency, uint64_t duration); + virtual void freq_updated(uint64_t time); + +public: + uint64_t last_stamp; + uint64_t total_stamp; + int number; + int childcount; + const char* name; + bool idle, old_idle, has_intel_MSR; + uint64_t current_frequency; + uint64_t effective_frequency; + + vector<class abstract_cpu *> children; + vector<struct idle_state *> cstates; + vector<struct frequency *> pstates; + + virtual ~abstract_cpu(); + + class abstract_cpu *parent; + + + int get_first_cpu() { return first_cpu; } + void set_number(int _number, int cpu) {this->number = _number; this->first_cpu = cpu;}; + void set_intel_MSR(bool _bool_value) {this->has_intel_MSR = _bool_value;}; + void set_type(const char* _name) {this->name = _name;}; + int get_number(void) { return number; }; + const char* get_type(void) { return name; }; + + virtual void measurement_start(void); + virtual void measurement_end(void); + + virtual int can_collapse(void) { return 0;}; + + + /* C state related methods */ + + void insert_cstate(const char *linux_name, const char *human_name, uint64_t usage, uint64_t duration, int count, int level = -1); + void update_cstate(const char *linux_name, const char *human_name, uint64_t usage, uint64_t duration, int count, int level = -1); + void finalize_cstate(const char *linux_name, uint64_t usage, uint64_t duration, int count); + + virtual int has_cstate_level(int level); + + virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator="") { return buffer;}; + virtual char * fill_cstate_percentage(int line_nr, char *buffer) { return buffer; }; + virtual char * fill_cstate_time(int line_nr, char *buffer) { return buffer; }; + virtual char * fill_cstate_name(int line_nr, char *buffer) { return buffer;}; + + + /* P state related methods */ + void insert_pstate(uint64_t freq, const char *human_name, uint64_t duration, int count); + void update_pstate(uint64_t freq, const char *human_name, uint64_t duration, int count); + void finalize_pstate(uint64_t freq, uint64_t duration, int count); + + + virtual char * fill_pstate_line(int line_nr, char *buffer) { return buffer;}; + virtual char * fill_pstate_name(int line_nr, char *buffer) { return buffer;}; + virtual int has_pstate_level(int level); + virtual int has_pstates(void) { return 1; }; + + /* Frequency micro accounting methods */ + virtual void calculate_freq(uint64_t time); + virtual void go_idle(uint64_t time) { idle = true; freq_updated(time); } + virtual void go_unidle(uint64_t time) { idle = false; freq_updated(time); } + virtual void change_freq(uint64_t time, int freq) { current_frequency = freq; freq_updated(time); } + + virtual void change_effective_frequency(uint64_t time, uint64_t freq); + + virtual void wiggle(void); + + virtual uint64_t total_pstate_time(void); + + virtual void validate(void); + virtual void reset_pstate_data(void); +}; + +extern vector<class abstract_cpu *> all_cpus; + +class cpu_linux: public abstract_cpu +{ + void parse_pstates_start(void); + void parse_cstates_start(void); + void parse_pstates_end(void); + void parse_cstates_end(void); + +public: + virtual void measurement_start(void); + virtual void measurement_end(void); + + virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator=""); + virtual char * fill_cstate_name(int line_nr, char *buffer); + virtual char * fill_cstate_percentage(int line_nr, char *buffer); + virtual char * fill_cstate_time(int line_nr, char *buffer); + + virtual char * fill_pstate_line(int line_nr, char *buffer); + virtual char * fill_pstate_name(int line_nr, char *buffer); +}; + +class cpu_core: public abstract_cpu +{ +public: + virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator=""); + virtual char * fill_cstate_name(int line_nr, char *buffer); + + virtual char * fill_pstate_line(int line_nr, char *buffer); + virtual char * fill_pstate_name(int line_nr, char *buffer); + + virtual int can_collapse(void) { return childcount == 1;}; +}; + +class cpu_package: public abstract_cpu +{ +protected: + virtual void freq_updated(uint64_t time); +public: + virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator=""); + virtual char * fill_cstate_name(int line_nr, char *buffer); + + virtual char * fill_pstate_line(int line_nr, char *buffer); + virtual char * fill_pstate_name(int line_nr, char *buffer); + virtual int can_collapse(void) { return childcount == 1;}; +}; + +extern void enumerate_cpus(void); + +extern void report_display_cpu_pstates(void); +extern void report_display_cpu_cstates(void); + + + +extern void display_cpu_cstates(const char *start= "", + const char *end = "", + const char *linestart = "", + const char *separator = "| ", + const char *lineend = "\n"); + +extern void w_display_cpu_cstates(void); +extern void w_display_cpu_pstates(void); + + +extern void start_cpu_measurement(void); +extern void end_cpu_measurement(void); +extern void process_cpu_data(void); +extern void end_cpu_data(void); +extern void clear_cpu_data(void); +extern void clear_all_cpus(void); + +#endif diff --git a/src/cpu/cpu_core.cpp b/src/cpu/cpu_core.cpp new file mode 100644 index 0000000..e1372f7 --- /dev/null +++ b/src/cpu/cpu_core.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <stdio.h> +#include "cpu.h" +#include "../lib.h" + +#include "../parameters/parameters.h" + +char * cpu_core::fill_cstate_line(int line_nr, char *buffer, const char *separator) +{ + unsigned int i; + buffer[0] = 0; + + if (line_nr == LEVEL_HEADER) + sprintf(buffer, this->has_intel_MSR ? _(" Core(HW)"): _(" Core(OS)")); + + for (i = 0; i < cstates.size(); i++) { + if (cstates[i]->line_level != line_nr) + continue; + sprintf(buffer,"%5.1f%%", percentage(cstates[i]->duration_delta / time_factor)); + } + + return buffer; +} + + +char * cpu_core::fill_cstate_name(int line_nr, char *buffer) +{ + unsigned int i; + buffer[0] = 0; + + for (i = 0; i < cstates.size(); i++) { + if (cstates[i]->line_level != line_nr) + continue; + + sprintf(buffer,"%s", cstates[i]->human_name); + } + + return buffer; +} + + + +char * cpu_core::fill_pstate_name(int line_nr, char *buffer) +{ + buffer[0] = 0; + + if (line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer,"%s", pstates[line_nr]->human_name); + + return buffer; +} + +char * cpu_core::fill_pstate_line(int line_nr, char *buffer) +{ + buffer[0] = 0; + unsigned int i; + + if (total_stamp ==0) { + for (i = 0; i < pstates.size(); i++) + total_stamp += pstates[i]->time_after; + if (total_stamp == 0) + total_stamp = 1; + } + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer,_(" Core")); + return buffer; + } + + if (line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer," %5.1f%% ", percentage(1.0* (pstates[line_nr]->time_after) / total_stamp)); + return buffer; +} diff --git a/src/cpu/cpu_linux.cpp b/src/cpu/cpu_linux.cpp new file mode 100644 index 0000000..d7ce93d --- /dev/null +++ b/src/cpu/cpu_linux.cpp @@ -0,0 +1,350 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> + +#include "cpu.h" +#include "../lib.h" + +#include <stdlib.h> + +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> + +void cpu_linux::parse_cstates_start(void) +{ + ifstream file; + DIR *dir; + struct dirent *entry; + char filename[256]; + int len; + + len = snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpuidle", number); + + dir = opendir(filename); + if (!dir) + return; + + /* For each C-state, there is a stateX directory which + * contains a 'usage' and a 'time' (duration) file */ + while ((entry = readdir(dir))) { + char linux_name[64]; + char human_name[64]; + uint64_t usage = 0; + uint64_t duration = 0; + + + if (strlen(entry->d_name) < 3) + continue; + + pt_strcpy(linux_name, entry->d_name); + pt_strcpy(human_name, linux_name); + + snprintf(filename + len, sizeof(filename) - len, "/%s/name", entry->d_name); + + file.open(filename, ios::in); + if (file) { + file.getline(human_name, sizeof(human_name)); + file.close(); + } + + if (strcmp(human_name, "C0")==0) + pt_strcpy(human_name, _("C0 polling")); + + snprintf(filename + len, sizeof(filename) - len, "/%s/usage", entry->d_name); + file.open(filename, ios::in); + if (file) { + file >> usage; + file.close(); + } else + continue; + + snprintf(filename + len, sizeof(filename) - len, "/%s/time", entry->d_name); + + file.open(filename, ios::in); + if (file) { + file >> duration; + file.close(); + } + + + update_cstate(linux_name, human_name, usage, duration, 1); + + } + closedir(dir); +} + + +void cpu_linux::parse_pstates_start(void) +{ + ifstream file; + char filename[256]; + unsigned int i; + + last_stamp = 0; + for (i = 0; i < children.size(); i++) + if (children[i]) + children[i]->wiggle(); + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/stats/time_in_state", first_cpu); + + file.open(filename, ios::in); + + if (file) { + char line[1024]; + + while (file) { + uint64_t f; + file.getline(line, sizeof(line)); + f = strtoull(line, NULL, 10); + account_freq(f, 0); + } + file.close(); + } + account_freq(0, 0); +} + +void cpu_linux::measurement_start(void) +{ + abstract_cpu::measurement_start(); + parse_cstates_start(); + parse_pstates_start(); +} + +void cpu_linux::parse_cstates_end(void) +{ + DIR *dir; + struct dirent *entry; + char filename[256]; + ifstream file; + int len; + + len = snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpuidle", number); + + dir = opendir(filename); + if (!dir) + return; + + /* For each C-state, there is a stateX directory which + * contains a 'usage' and a 'time' (duration) file */ + while ((entry = readdir(dir))) { + char linux_name[64]; + char human_name[64]; + uint64_t usage = 0; + uint64_t duration = 0; + + + if (strlen(entry->d_name) < 3) + continue; + + pt_strcpy(linux_name, entry->d_name); + pt_strcpy(human_name, linux_name); + + + snprintf(filename + len, sizeof(filename) - len, "/%s/usage", entry->d_name); + file.open(filename, ios::in); + if (file) { + file >> usage; + file.close(); + } else + continue; + + snprintf(filename + len, sizeof(filename) - len, "/%s/time", entry->d_name); + + file.open(filename, ios::in); + if (file) { + file >> duration; + file.close(); + } + + + finalize_cstate(linux_name, usage, duration, 1); + + } + closedir(dir); +} + +void cpu_linux::parse_pstates_end(void) +{ + char filename[256]; + ifstream file; + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/stats/time_in_state", number); + + file.open(filename, ios::in); + + if (file) { + char line[1024]; + + while (file) { + uint64_t f,count; + char *c; + + memset(line, 0, sizeof(line)); + + file.getline(line, sizeof(line)); + + f = strtoull(line, &c, 10); + if (!c) + break; + + count = strtoull(c, NULL, 10); + + if (f > 0) + finalize_pstate(f, count, 1); + + + } + file.close(); + } +} + +void cpu_linux::measurement_end(void) +{ + parse_cstates_end(); + parse_pstates_end(); + abstract_cpu::measurement_end(); +} + +char * cpu_linux::fill_cstate_line(int line_nr, char *buffer, const char *separator) +{ + unsigned int i; + buffer[0] = 0; + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer,_(" CPU(OS) %i"), number); + return buffer; + } + + for (i = 0; i < cstates.size(); i++) { + if (cstates[i]->line_level != line_nr) + continue; + + if (line_nr == LEVEL_C0) + sprintf(buffer,"%5.1f%%", percentage(cstates[i]->duration_delta / time_factor)); + else + sprintf(buffer,"%5.1f%%%s %6.1f ms", + percentage(cstates[i]->duration_delta / time_factor), + separator, + 1.0 * cstates[i]->duration_delta / (1 + cstates[i]->usage_delta) / 1000); + } + + return buffer; +} + +char * cpu_linux::fill_cstate_percentage(int line_nr, char *buffer) +{ + unsigned int i; + buffer[0] = 0; + + for (i = 0; i < cstates.size(); i++) { + if (cstates[i]->line_level != line_nr) + continue; + + sprintf(buffer,"%5.1f%%", + percentage(cstates[i]->duration_delta / time_factor)); + break; + } + + return buffer; +} + +char * cpu_linux::fill_cstate_time(int line_nr, char *buffer) +{ + unsigned int i; + buffer[0] = 0; + + if (line_nr == LEVEL_C0) + return buffer; + + for (i = 0; i < cstates.size(); i++) { + if (cstates[i]->line_level != line_nr) + continue; + + sprintf(buffer,"%6.1f ms", + 1.0 * cstates[i]->duration_delta / + (1 + cstates[i]->usage_delta) / 1000); + break; + } + + return buffer; +} + +char * cpu_linux::fill_cstate_name(int line_nr, char *buffer) +{ + unsigned int i; + buffer[0] = 0; + + for (i = 0; i < cstates.size(); i++) { + if (cstates[i]->line_level != line_nr) + continue; + + sprintf(buffer,"%s", cstates[i]->human_name); + } + + return buffer; +} + + +char * cpu_linux::fill_pstate_name(int line_nr, char *buffer) +{ + buffer[0] = 0; + + if (line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer,"%s", pstates[line_nr]->human_name); + + return buffer; +} + +char * cpu_linux::fill_pstate_line(int line_nr, char *buffer) +{ + buffer[0] = 0; + + if (total_stamp ==0) { + unsigned int i; + for (i = 0; i < pstates.size(); i++) + total_stamp += pstates[i]->time_after; + if (total_stamp == 0) + total_stamp = 1; + } + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer,_(" CPU %i"), number); + return buffer; + } + + if (line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer," %5.1f%% ", percentage(1.0* (pstates[line_nr]->time_after) / total_stamp)); + return buffer; +} diff --git a/src/cpu/cpu_package.cpp b/src/cpu/cpu_package.cpp new file mode 100644 index 0000000..926a484 --- /dev/null +++ b/src/cpu/cpu_package.cpp @@ -0,0 +1,113 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <stdio.h> +#include "cpu.h" +#include "../lib.h" +#include "../parameters/parameters.h" + +void cpu_package::freq_updated(uint64_t time) +{ + if (parent) + parent->calculate_freq(time); + /* + * Make the frequency changes to propagate to all cores in a package. + */ + change_effective_frequency(time, current_frequency); + old_idle = idle; +} + +char * cpu_package::fill_cstate_line(int line_nr, char *buffer, const char *separator) +{ + unsigned int i; + buffer[0] = 0; + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer, this->has_intel_MSR ? _(" Pkg(HW)"): _(" Pkg(OS)")); + } + + for (i = 0; i < cstates.size(); i++) { + if (cstates[i]->line_level != line_nr) + continue; + + sprintf(buffer,"%5.1f%%", percentage(cstates[i]->duration_delta / time_factor)); + } + + return buffer; +} + + +char * cpu_package::fill_cstate_name(int line_nr, char *buffer) +{ + unsigned int i; + buffer[0] = 0; + + for (i = 0; i < cstates.size(); i++) { + if (cstates[i]->line_level != line_nr) + continue; + + sprintf(buffer,"%s", cstates[i]->human_name); + } + + return buffer; +} + + + +char * cpu_package::fill_pstate_name(int line_nr, char *buffer) +{ + buffer[0] = 0; + + if (line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer,"%s", pstates[line_nr]->human_name); + + return buffer; +} + +char * cpu_package::fill_pstate_line(int line_nr, char *buffer) +{ + buffer[0] = 0; + unsigned int i; + + if (total_stamp ==0) { + for (i = 0; i < pstates.size(); i++) + total_stamp += pstates[i]->time_after; + if (total_stamp == 0) + total_stamp = 1; + } + + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer,_(" Package")); + return buffer; + } + + if (line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer," %5.1f%% ", percentage(1.0* (pstates[line_nr]->time_after) / total_stamp)); + return buffer; +} diff --git a/src/cpu/cpu_rapl_device.cpp b/src/cpu/cpu_rapl_device.cpp new file mode 100644 index 0000000..357a1c8 --- /dev/null +++ b/src/cpu/cpu_rapl_device.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Srinivas Pandruvada<Srinivas.Pandruvada@linux.intel.com> + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "../parameters/parameters.h" +#include "cpu_rapl_device.h" + +cpu_rapl_device::cpu_rapl_device(cpudevice *parent, const char *classname, const char *dev_name, class abstract_cpu *_cpu) + : cpudevice(classname, dev_name, _cpu), + device_valid(false) +{ + if (_cpu) + rapl = new c_rapl_interface(dev_name, cpu->get_first_cpu()); + else + rapl = new c_rapl_interface(); + last_time = time(NULL); + if (rapl->pp0_domain_present()) { + device_valid = true; + parent->add_child(this); + rapl->get_pp0_energy_status(&last_energy); + } +} + +void cpu_rapl_device::start_measurement(void) +{ + last_time = time(NULL); + + rapl->get_pp0_energy_status(&last_energy); +} + +void cpu_rapl_device::end_measurement(void) +{ + time_t curr_time = time(NULL); + double energy; + + consumed_power = 0.0; + if ((curr_time - last_time) > 0) { + rapl->get_pp0_energy_status(&energy); + consumed_power = (energy-last_energy)/(curr_time-last_time); + last_energy = energy; + last_time = curr_time; + } +} + +double cpu_rapl_device::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + if (rapl->pp0_domain_present()) + return consumed_power; + else + return 0.0; +} diff --git a/src/cpu/cpu_rapl_device.h b/src/cpu/cpu_rapl_device.h new file mode 100644 index 0000000..407f2da --- /dev/null +++ b/src/cpu/cpu_rapl_device.h @@ -0,0 +1,57 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Srinivas Pandruvada <Srinivas.Pandruvada@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_CPU_RAPL_DEVICE_H +#define _INCLUDE_GUARD_CPU_RAPL_DEVICE_H + +#include <vector> +#include <string> + +using namespace std; + +#include <sys/time.h> +#include "cpudevice.h" +#include "rapl/rapl_interface.h" + +class cpu_rapl_device: public cpudevice { + + c_rapl_interface *rapl; + time_t last_time; + double last_energy; + double consumed_power; + bool device_valid; + +public: + cpu_rapl_device(cpudevice *parent, const char *classname = "cpu_core", const char *device_name = "cpu_core", class abstract_cpu *_cpu = NULL); + ~cpu_rapl_device() { delete rapl; } + virtual const char * device_name(void) {return "CPU core";}; + bool device_present() { return device_valid;} + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual void start_measurement(void); + virtual void end_measurement(void); + +}; + + +#endif diff --git a/src/cpu/cpudevice.cpp b/src/cpu/cpudevice.cpp new file mode 100644 index 0000000..4c7ca7b --- /dev/null +++ b/src/cpu/cpudevice.cpp @@ -0,0 +1,86 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "cpudevice.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "../lib.h" +#include "../parameters/parameters.h" + + +cpudevice::cpudevice(const char *classname, const char *dev_name, class abstract_cpu *_cpu) +{ + pt_strcpy(_class, classname); + pt_strcpy(_cpuname, dev_name); + cpu = _cpu; + wake_index = get_param_index("cpu-wakeups");; + consumption_index = get_param_index("cpu-consumption");; + r_wake_index = get_result_index("cpu-wakeups");; + r_consumption_index = get_result_index("cpu-consumption");; +} + +const char * cpudevice::device_name(void) +{ + if (child_devices.size()) + return "CPU misc"; + else + return "CPU use"; +} + +double cpudevice::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double _utilization; + double child_power; + + power = 0; + factor = get_parameter_value(wake_index, bundle); + _utilization = get_result_value(r_wake_index, result); + + power += _utilization * factor / 10000.0; + + factor = get_parameter_value(consumption_index, bundle); + _utilization = get_result_value(r_consumption_index, result); + + power += _utilization * factor; + + for (unsigned int i = 0; i < child_devices.size(); ++i) { + child_power = child_devices[i]->power_usage(result, bundle); + if ((power - child_power) > 0.0) + power -= child_power; + } + + return power; +} + +double cpudevice::utilization(void) +{ + double _utilization; + _utilization = get_result_value(r_consumption_index); + + return _utilization * 100; + +} diff --git a/src/cpu/cpudevice.h b/src/cpu/cpudevice.h new file mode 100644 index 0000000..841a101 --- /dev/null +++ b/src/cpu/cpudevice.h @@ -0,0 +1,63 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_CPUDEVICE_H +#define _INCLUDE_GUARD_CPUDEVICE_H + +#include <vector> +#include <string> + +using namespace std; + +#include "../devices/device.h" +#include "cpu.h" + +class cpudevice: public device { +protected: + char _class[128]; + char _cpuname[128]; + + vector<string> params; + class abstract_cpu *cpu; + int wake_index; + int consumption_index; + int r_wake_index; + int r_consumption_index; + + vector<device *>child_devices; + +public: + cpudevice(const char *classname = "cpu", const char *device_name = "cpu0", class abstract_cpu *_cpu = NULL); + virtual const char * class_name(void) { return _class;}; + + virtual const char * device_name(void); + + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual bool show_in_list(void) {return false;}; + virtual double utilization(void); /* percentage */ + void add_child(device *dev_ptr) { child_devices.push_back(dev_ptr);} +}; + + +#endif
\ No newline at end of file diff --git a/src/cpu/dram_rapl_device.cpp b/src/cpu/dram_rapl_device.cpp new file mode 100644 index 0000000..36d47a2 --- /dev/null +++ b/src/cpu/dram_rapl_device.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Srinivas Pandruvada <Srinivas.Pandruvada@linux.intel.com> + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "../parameters/parameters.h" +#include "dram_rapl_device.h" + + +dram_rapl_device::dram_rapl_device(cpudevice *parent, const char *classname, const char *dev_name, class abstract_cpu *_cpu) + : cpudevice(classname, dev_name, _cpu), + device_valid(false) +{ + if (_cpu) + rapl = new c_rapl_interface(dev_name, cpu->get_first_cpu()); + else + rapl = new c_rapl_interface(); + last_time = time(NULL); + if (rapl->dram_domain_present()) { + device_valid = true; + parent->add_child(this); + rapl->get_dram_energy_status(&last_energy); + } +} + +void dram_rapl_device::start_measurement(void) +{ + last_time = time(NULL); + + rapl->get_dram_energy_status(&last_energy); +} + +void dram_rapl_device::end_measurement(void) +{ + time_t curr_time = time(NULL); + double energy; + + consumed_power = 0.0; + if ((curr_time - last_time) > 0) { + rapl->get_dram_energy_status(&energy); + consumed_power = (energy-last_energy)/(curr_time-last_time); + last_energy = energy; + last_time = curr_time; + } +} + +double dram_rapl_device::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + if (rapl->dram_domain_present()) + return consumed_power; + else + return 0.0; +} diff --git a/src/cpu/dram_rapl_device.h b/src/cpu/dram_rapl_device.h new file mode 100644 index 0000000..dc53094 --- /dev/null +++ b/src/cpu/dram_rapl_device.h @@ -0,0 +1,57 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Srinivas Pandruvada <Srinivas.Pandruvada@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_DRAM_RAPL_DEVICE_H +#define _INCLUDE_GUARD_DRAM_RAPL_DEVICE_H + +#include <vector> +#include <string> + +using namespace std; + +#include <sys/time.h> +#include "cpudevice.h" +#include "rapl/rapl_interface.h" + +class dram_rapl_device: public cpudevice { + + c_rapl_interface *rapl; + time_t last_time; + double last_energy; + double consumed_power; + bool device_valid; + +public: + dram_rapl_device(cpudevice *parent, const char *classname = "dram_core", const char *device_name = "dram_core", class abstract_cpu *_cpu = NULL); + ~dram_rapl_device() { delete rapl; } + virtual const char * device_name(void) {return "DRAM";}; + bool device_present() { return device_valid;} + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + void start_measurement(void); + void end_measurement(void); + +}; + + +#endif diff --git a/src/cpu/intel_cpus.cpp b/src/cpu/intel_cpus.cpp new file mode 100644 index 0000000..a7145d7 --- /dev/null +++ b/src/cpu/intel_cpus.cpp @@ -0,0 +1,757 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "intel_cpus.h" +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <stdint.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/time.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <limits.h> + +#include "../lib.h" +#include "../parameters/parameters.h" +#include "../display.h" + +static int intel_cpu_models[] = { + 0x1A, /* Core i7, Xeon 5500 series */ + 0x1E, /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ + 0x1F, /* Core i7 and i5 Processor - Nehalem */ + 0x25, /* Westmere */ + 0x27, /* Medfield Atom */ + 0x2A, /* SNB */ + 0x2C, /* Westmere */ + 0x2D, /* SNB Xeon */ + 0x2E, /* Nehalem-EX Xeon */ + 0x2F, /* Westmere-EX Xeon */ + 0x37, /* BYT-M */ + 0x3A, /* IVB */ + 0x3C, /* HSW */ + 0x3D, /* BDW */ + 0x3E, /* IVB Xeon */ + 0x3F, /* HSX */ + 0x45, /* HSW-ULT */ + 0x46, /* HSW-G */ + 0x47, /* BDW-H */ + 0x4C, /* BSW */ + 0x4D, /* AVN */ + 0x4F, /* BDX */ + 0x4E, /* SKY */ + 0x55, /* SKY-X */ + 0x56, /* BDX-DE */ + 0x5C, /* BXT-P */ + 0x5E, /* SKY */ + 0x5F, /* DNV */ + 0x66, /* CNL-U/Y */ + 0x6A, /* ICL_X*/ + 0x7A, /* GLK */ + 0x7D, /* ICL_DESKTOP */ + 0x7E, /* ICL_MOBILE */ + 0x8A, /* LKF */ + 0x8C, /* TGL_MOBILE */ + 0x8D, /* TGL_DESKTOP */ + 0x8E, /* KBL_MOBILE */ + 0X8F, /* SAPPHIRERAPIDS_X */ + 0x96, /* EHL */ + 0x97, /* ADL_DESKTOP */ + 0x9A, /* ADL_MOBILE */ + 0x9C, /* JSL */ + 0x9D, /* ICL_NNPI */ + 0x9E, /* KBL_DESKTOP */ + 0xA5, /* CML_DESKTOP */ + 0xA6, /* CML_MOBILE */ + 0xA7, /* RKL_DESKTOP */ + 0xAA, /* MTL_MOBILE */ + 0xAC, /* MTL_DESKTOP */ + 0xB7, /* RPL_DESKTOP */ + 0xBA, /* RPL_P */ + 0xBE, /* ADL_N */ + 0xBF, /* RPL_S */ + 0 /* last entry must be zero */ +}; + +static int intel_pstate_driver_loaded = -1; + +int is_supported_intel_cpu(int model, int cpu) +{ + int i; + uint64_t msr; + + for (i = 0; intel_cpu_models[i] != 0; i++) + if (model == intel_cpu_models[i]) + if (cpu < 0 || read_msr(cpu, MSR_APERF, &msr) >= 0) + return 1; + + return 0; +} + +int is_intel_pstate_driver_loaded() +{ + const char *filename = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver"; + const string intel_pstate("intel_pstate"); + char line[32] = { '\0' }; + ifstream file; + + if (intel_pstate_driver_loaded > -1) + return intel_pstate_driver_loaded; + + file.open(filename, ios::in); + + if (!file) + return -1; + + file.getline(line, sizeof(line)-1); + file.close(); + + const string scaling_driver(line); + if (scaling_driver == intel_pstate) { + intel_pstate_driver_loaded = 1; + } else { + intel_pstate_driver_loaded = 0; + } + + return intel_pstate_driver_loaded; +} + +static uint64_t get_msr(int cpu, uint64_t offset) +{ + ssize_t retval; + uint64_t msr; + + retval = read_msr(cpu, offset, &msr); + if (retval < 0) { + reset_display(); + fprintf(stderr, _("read_msr cpu%d 0x%llx : "), cpu, (unsigned long long)offset); + fprintf(stderr, "%s\n", strerror(errno)); + exit(-2); + } + + return msr; +} + +intel_util::intel_util() +{ + byt_ahci_support=0; +} + +void intel_util::byt_has_ahci() +{ + dir = opendir("/sys/bus/pci/devices/0000:00:13.0"); + if (!dir) + byt_ahci_support=0; + else { + byt_ahci_support=1; + closedir(dir); + } +} + +int intel_util::get_byt_ahci_support() +{ + return byt_ahci_support; +} + +nhm_core::nhm_core(int model) +{ + has_c7_res = 0; + + switch(model) { + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + case 0x3A: /* IVB */ + case 0x3C: /* HSW */ + case 0x3D: /* BDW */ + case 0x3E: /* IVB Xeon */ + case 0x45: /* HSW-ULT */ + case 0x4E: /* SKY */ + case 0x55: /* SKY-X */ + case 0x5E: /* SKY */ + case 0x5F: /* DNV */ + case 0x5C: /* BXT-P */ + case 0x66: /* CNL-U/Y */ + case 0x6A: /* ICL_X*/ + case 0x7A: /* GLK */ + case 0x7D: /* ICL_DESKTOP */ + case 0x7E: /* ICL_MOBILE */ + case 0x8A: /* LKF */ + case 0x8C: /* TGL_MOBILE */ + case 0x8D: /* TGL_DESKTOP */ + case 0x8E: /* KBL_MOBILE */ + case 0x8F: /* SAPPHIRERAPIDS_X */ + case 0x96: /* EHL */ + case 0x97: /* ADL_DESKTOP */ + case 0x9A: /* ADL_MOBILE */ + case 0x9C: /* JSL */ + case 0x9D: /* ICL_NNPI */ + case 0x9E: /* KBL_DESKTOP */ + case 0xA5: /* CML_DESKTOP */ + case 0xA6: /* CML_MOBILE */ + case 0xA7: /* RKL_DESKTOP */ + case 0xAA: /* MTL_MOBILE */ + case 0xAC: /* MTL_DESKTOP */ + case 0xB7: /* RPL_DESKTOP */ + case 0xBA: /* RPL_P */ + case 0xBE: /* ADL_N */ + case 0xBF: /* RPL_S */ + has_c7_res = 1; + } + + has_c3_res = 1; + has_c1_res = 0; + + switch (model) { + case 0x37: /* BYT-M does not support C3/C4 */ + case 0x4C: /* BSW does not support C3 */ + has_c3_res = 0; + has_c1_res = 1; + } + +} + +void nhm_core::measurement_start(void) +{ + ifstream file; + char filename[PATH_MAX]; + + /* the abstract function needs to be first since it clears all state */ + abstract_cpu::measurement_start(); + + last_stamp = 0; + + if (this->has_c1_res) + c1_before = get_msr(first_cpu, MSR_CORE_C1_RESIDENCY); + if (this->has_c3_res) + c3_before = get_msr(first_cpu, MSR_CORE_C3_RESIDENCY); + c6_before = get_msr(first_cpu, MSR_CORE_C6_RESIDENCY); + if (this->has_c7_res) + c7_before = get_msr(first_cpu, MSR_CORE_C7_RESIDENCY); + tsc_before = get_msr(first_cpu, MSR_TSC); + + if (this->has_c1_res) + insert_cstate("core c1", "C1 (cc1)", 0, c1_before, 1); + if (this->has_c3_res) + insert_cstate("core c3", "C3 (cc3)", 0, c3_before, 1); + insert_cstate("core c6", "C6 (cc6)", 0, c6_before, 1); + if (this->has_c7_res) { + insert_cstate("core c7", "C7 (cc7)", 0, c7_before, 1); + } + + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/stats/time_in_state", first_cpu); + + file.open(filename, ios::in); + + if (file) { + char line[1024]; + + while (file) { + uint64_t f; + file.getline(line, 1024); + f = strtoull(line, NULL, 10); + account_freq(f, 0); + } + file.close(); + } + account_freq(0, 0); + +} + +void nhm_core::measurement_end(void) +{ + unsigned int i; + uint64_t time_delta; + double ratio; + + if (this->has_c1_res) + c1_after = get_msr(first_cpu, MSR_CORE_C1_RESIDENCY); + if (this->has_c3_res) + c3_after = get_msr(first_cpu, MSR_CORE_C3_RESIDENCY); + c6_after = get_msr(first_cpu, MSR_CORE_C6_RESIDENCY); + if (this->has_c7_res) + c7_after = get_msr(first_cpu, MSR_CORE_C7_RESIDENCY); + tsc_after = get_msr(first_cpu, MSR_TSC); + + if (this->has_c1_res) + finalize_cstate("core c1", 0, c1_after, 1); + if (this->has_c3_res) + finalize_cstate("core c3", 0, c3_after, 1); + finalize_cstate("core c6", 0, c6_after, 1); + if (this->has_c7_res) + finalize_cstate("core c7", 0, c7_after, 1); + + gettimeofday(&stamp_after, NULL); + + time_factor = 1000000.0 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; + + for (i = 0; i < children.size(); i++) + if (children[i]) { + children[i]->measurement_end(); + children[i]->wiggle(); + } + + time_delta = 1000000 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; + + ratio = 1.0 * time_delta / (tsc_after - tsc_before); + + for (i = 0; i < cstates.size(); i++) { + struct idle_state *state = cstates[i]; + + if (state->after_count == 0) + continue; + + if (state->after_count != state->before_count) + continue; + + state->usage_delta = ratio * (state->usage_after - state->usage_before) / state->after_count; + state->duration_delta = ratio * (state->duration_after - state->duration_before) / state->after_count; + } + +#if 0 + for (i = 0; i < children.size(); i++) + if (children[i]) { + for (j = 0; j < children[i]->pstates.size(); j++) { + struct frequency *state; + state = children[i]->pstates[j]; + if (!state) + continue; + + update_pstate( state->freq, state->human_name, state->time_before, state->before_count); + finalize_pstate(state->freq, state->time_after, state->after_count); + } + } +#endif + total_stamp = 0; +} + +char * nhm_core::fill_pstate_line(int line_nr, char *buffer) +{ + const int intel_pstate = is_intel_pstate_driver_loaded(); + buffer[0] = 0; + unsigned int i; + + if (!intel_pstate && total_stamp ==0) { + for (i = 0; i < pstates.size(); i++) + total_stamp += pstates[i]->time_after; + if (total_stamp == 0) + total_stamp = 1; + } + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer,_(" Core")); + return buffer; + } + + if (intel_pstate > 0 || line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer," %5.1f%% ", percentage(1.0* (pstates[line_nr]->time_after) / total_stamp)); + + return buffer; +} + +nhm_package::nhm_package(int model) +{ + has_c8c9c10_res = 0; + has_c2c6_res = 0; + has_c7_res = 0; + has_c6c_res = 0; + + switch(model) { + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + case 0x3A: /* IVB */ + case 0x3C: /* HSW */ + case 0x3D: /* BDW */ + case 0x3E: /* IVB Xeon */ + case 0x45: /* HSW-ULT */ + case 0x4E: /* SKY */ + case 0x55: /* SKY-X */ + case 0x5C: /* BXT-P */ + case 0x5E: /* SKY */ + case 0x5F: /* DNV */ + case 0x66: /* CNL-U/Y */ + case 0x6A: /* ICL_X*/ + case 0x7A: /* GLK */ + case 0x7D: /* ICL_DESKTOP */ + case 0x7E: /* ICL_MOBILE */ + case 0x8A: /* LKF */ + case 0x8C: /* TGL_MOBILE */ + case 0x8D: /* TGL_DESKTOP */ + case 0x8E: /* KBL_MOBILE */ + case 0x8F: /* SAPPHIRERAPIDS_X */ + case 0x96: /* EHL */ + case 0x97: /* ADL_DESKTOP */ + case 0X9A: /* ADL_MOBILE */ + case 0x9C: /* JSL */ + case 0x9D: /* ICL_NNPI */ + case 0x9E: /* KBL_DESKTOP */ + case 0xA5: /* CML_DESKTOP */ + case 0xA6: /* CML_MOBILE */ + case 0xA7: /* RKL_DESKTOP */ + case 0xAA: /* MTL_MOBILE */ + case 0xAC: /* MTL_DESKTOP */ + case 0xB7: /* RPL_DESKTOP */ + case 0xBA: /* RPL_P */ + case 0xBE: /* ADL_N */ + case 0xBF: /* RPL_S */ + has_c2c6_res=1; + has_c7_res = 1; + } + + has_c3_res = 1; + + switch(model) { + /* BYT-M doesn't have C3 or C7 */ + /* BYT-T doesn't have C3 but it has C7 */ + case 0x37: + has_c2c6_res=1; + this->byt_has_ahci(); + if ((this->get_byt_ahci_support()) == 0) + has_c7_res = 1;/*BYT-T PC7 <- S0iX*/ + else + has_c7_res = 0; + break; + case 0x4C: /* BSW doesn't have C3 */ + has_c3_res = 0; + has_c6c_res = 1; /* BSW only exposes package C6 */ + break; + } + + /*Has C8/9/10*/ + switch(model) { + case 0x3D: /* BDW */ + case 0x45: /* HSW */ + case 0x4E: /* SKY */ + case 0x5C: /* BXT-P */ + case 0x5E: /* SKY */ + case 0x5F: /* DNV */ + case 0x66: /* CNL-U/Y */ + case 0x7A: /* GLK */ + case 0x7D: /* ICL_DESKTOP */ + case 0x7E: /* ICL_MOBILE */ + case 0x8A: /* LKF */ + case 0x8C: /* TGL_MOBILE */ + case 0x8D: /* TGL_DESKTOP */ + case 0x8E: /* KBL_MOBILE */ + case 0x96: /* EHL */ + case 0x97: /* ADL_DESKTOP */ + case 0x9A: /* ADL_MOBILE */ + case 0x9C: /* JSL */ + case 0x9D: /* ICL_NNPI */ + case 0x9E: /* KBL_DESKTOP */ + case 0xA5: /* CML_DESKTOP */ + case 0xA6: /* CML_MOBILE */ + case 0xA7: /* RKL_DESKTOP */ + case 0xAA: /* MTL_MOBILE */ + case 0xAC: /* MTL_DESKTOP */ + case 0xB7: /* RPL_DESKTOP */ + case 0xBA: /* RPL_P */ + case 0xBE: /* ADL_N */ + case 0xBF: /* RPL_S */ + has_c8c9c10_res = 1; + break; + } +} + +char * nhm_package::fill_pstate_line(int line_nr, char *buffer) +{ + const int intel_pstate = is_intel_pstate_driver_loaded(); + buffer[0] = 0; + unsigned int i; + + if (!intel_pstate && total_stamp ==0) { + for (i = 0; i < pstates.size(); i++) + total_stamp += pstates[i]->time_after; + if (total_stamp == 0) + total_stamp = 1; + } + + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer,_(" Package")); + return buffer; + } + + if (intel_pstate > 0 || line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer," %5.1f%% ", percentage(1.0* (pstates[line_nr]->time_after) / total_stamp)); + + return buffer; +} + + + +void nhm_package::measurement_start(void) +{ + abstract_cpu::measurement_start(); + + last_stamp = 0; + + if (this->has_c2c6_res) + c2_before = get_msr(number, MSR_PKG_C2_RESIDENCY); + + if (this->has_c3_res) + c3_before = get_msr(number, MSR_PKG_C3_RESIDENCY); + + /* + * Hack for Braswell where C7 MSR is actually BSW C6 + */ + if (this->has_c6c_res) + c6_before = get_msr(number, MSR_PKG_C7_RESIDENCY); + else + c6_before = get_msr(number, MSR_PKG_C6_RESIDENCY); + + if (this->has_c7_res) + c7_before = get_msr(number, MSR_PKG_C7_RESIDENCY); + if (this->has_c8c9c10_res) { + c8_before = get_msr(number, MSR_PKG_C8_RESIDENCY); + c9_before = get_msr(number, MSR_PKG_C9_RESIDENCY); + c10_before = get_msr(number, MSR_PKG_C10_RESIDENCY); + } + tsc_before = get_msr(first_cpu, MSR_TSC); + + if (this->has_c2c6_res) + insert_cstate("pkg c2", "C2 (pc2)", 0, c2_before, 1); + + if (this->has_c3_res) + insert_cstate("pkg c3", "C3 (pc3)", 0, c3_before, 1); + insert_cstate("pkg c6", "C6 (pc6)", 0, c6_before, 1); + if (this->has_c7_res) + insert_cstate("pkg c7", "C7 (pc7)", 0, c7_before, 1); + if (this->has_c8c9c10_res) { + insert_cstate("pkg c8", "C8 (pc8)", 0, c8_before, 1); + insert_cstate("pkg c9", "C9 (pc9)", 0, c9_before, 1); + insert_cstate("pkg c10", "C10 (pc10)", 0, c10_before, 1); + } +} + +void nhm_package::measurement_end(void) +{ + uint64_t time_delta; + double ratio; + unsigned int i, j; + + for (i = 0; i < children.size(); i++) + if (children[i]) + children[i]->wiggle(); + + + if (this->has_c2c6_res) + c2_after = get_msr(number, MSR_PKG_C2_RESIDENCY); + + if (this->has_c3_res) + c3_after = get_msr(number, MSR_PKG_C3_RESIDENCY); + + if (this->has_c6c_res) + c6_after = get_msr(number, MSR_PKG_C7_RESIDENCY); + else + c6_after = get_msr(number, MSR_PKG_C6_RESIDENCY); + + if (this->has_c7_res) + c7_after = get_msr(number, MSR_PKG_C7_RESIDENCY); + if (has_c8c9c10_res) { + c8_after = get_msr(number, MSR_PKG_C8_RESIDENCY); + c9_after = get_msr(number, MSR_PKG_C9_RESIDENCY); + c10_after = get_msr(number, MSR_PKG_C10_RESIDENCY); + } + tsc_after = get_msr(first_cpu, MSR_TSC); + + gettimeofday(&stamp_after, NULL); + + time_factor = 1000000.0 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; + + + if (this->has_c2c6_res) + finalize_cstate("pkg c2", 0, c2_after, 1); + + if (this->has_c3_res) + finalize_cstate("pkg c3", 0, c3_after, 1); + finalize_cstate("pkg c6", 0, c6_after, 1); + if (this->has_c7_res) + finalize_cstate("pkg c7", 0, c7_after, 1); + if (has_c8c9c10_res) { + finalize_cstate("pkg c8", 0, c8_after, 1); + finalize_cstate("pkg c9", 0, c9_after, 1); + finalize_cstate("pkg c10", 0, c10_after, 1); + } + + for (i = 0; i < children.size(); i++) + if (children[i]) + children[i]->measurement_end(); + + time_delta = 1000000 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; + + ratio = 1.0 * time_delta / (tsc_after - tsc_before); + + + for (i = 0; i < cstates.size(); i++) { + struct idle_state *state = cstates[i]; + + if (state->after_count == 0) + continue; + + if (state->after_count != state->before_count) + continue; + + state->usage_delta = ratio * (state->usage_after - state->usage_before) / state->after_count; + state->duration_delta = ratio * (state->duration_after - state->duration_before) / state->after_count; + } + for (i = 0; i < children.size(); i++) + if (children[i]) { + for (j = 0; j < children[i]->pstates.size(); j++) { + struct frequency *state; + state = children[i]->pstates[j]; + if (!state) + continue; + + update_pstate( state->freq, state->human_name, state->time_before, state->before_count); + finalize_pstate(state->freq, state->time_after, state->after_count); + } + } + total_stamp = 0; + +} + +void nhm_cpu::measurement_start(void) +{ + ifstream file; + char filename[PATH_MAX]; + + cpu_linux::measurement_start(); + + last_stamp = 0; + + aperf_before = get_msr(number, MSR_APERF); + mperf_before = get_msr(number, MSR_MPERF); + tsc_before = get_msr(number, MSR_TSC); + + insert_cstate("active", _("C0 active"), 0, aperf_before, 1); + + snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/stats/time_in_state", first_cpu); + + file.open(filename, ios::in); + + if (file) { + char line[1024]; + + while (file) { + uint64_t f; + file.getline(line, sizeof(line)); + f = strtoull(line, NULL, 10); + account_freq(f, 0); + } + file.close(); + } + account_freq(0, 0); +} + +void nhm_cpu::measurement_end(void) +{ + uint64_t time_delta; + double ratio; + unsigned int i; + + aperf_after = get_msr(number, MSR_APERF); + mperf_after = get_msr(number, MSR_MPERF); + tsc_after = get_msr(number, MSR_TSC); + + + + finalize_cstate("active", 0, aperf_after, 1); + + + cpu_linux::measurement_end(); + + time_delta = 1000000 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; + + ratio = 1.0 * time_delta / (tsc_after - tsc_before); + + + for (i = 0; i < cstates.size(); i++) { + struct idle_state *state = cstates[i]; + if (state->line_level != LEVEL_C0) + continue; + + state->usage_delta = ratio * (state->usage_after - state->usage_before) / state->after_count; + state->duration_delta = ratio * (state->duration_after - state->duration_before) / state->after_count; + } + + total_stamp = 0; + +} + +char * nhm_cpu::fill_pstate_name(int line_nr, char *buffer) +{ + if (line_nr == LEVEL_C0) { + sprintf(buffer, _("Average")); + return buffer; + } + return cpu_linux::fill_pstate_name(line_nr, buffer); +} + +char * nhm_cpu::fill_pstate_line(int line_nr, char *buffer) +{ + const int intel_pstate = is_intel_pstate_driver_loaded(); + + if (!intel_pstate && total_stamp ==0) { + unsigned int i; + for (i = 0; i < pstates.size(); i++) + total_stamp += pstates[i]->time_after; + if (total_stamp == 0) + total_stamp = 1; + } + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer,_(" CPU %i"), number); + return buffer; + } + + if (line_nr == LEVEL_C0) { + double F; + F = 1.0 * (tsc_after - tsc_before) * (aperf_after - aperf_before) / (mperf_after - mperf_before) / time_factor * 1000; + hz_to_human(F, buffer, 1); + return buffer; + } + if (intel_pstate > 0 || line_nr >= (int)pstates.size() || line_nr < 0) + return buffer; + + sprintf(buffer," %5.1f%% ", percentage(1.0* (pstates[line_nr]->time_after) / total_stamp)); + + return buffer; +} + + +int nhm_cpu::has_pstate_level(int level) +{ + if (level == LEVEL_C0) + return 1; + return cpu_linux::has_pstate_level(level); +} diff --git a/src/cpu/intel_cpus.h b/src/cpu/intel_cpus.h new file mode 100644 index 0000000..79afb98 --- /dev/null +++ b/src/cpu/intel_cpus.h @@ -0,0 +1,180 @@ +#ifndef PowerTop_INTEL_CPUS_H_84F09FB4F519470FA914AA9B02453221 +#define PowerTop_INTEL_CPUS_H_84F09FB4F519470FA914AA9B02453221 +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <stdint.h> +#include <sys/time.h> +#include <dirent.h> + +#include "cpu.h" + + +#define MSR_TSC 0x10 +#define MSR_NEHALEM_PLATFORM_INFO 0xCE +#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD +#define MSR_APERF 0xE8 +#define MSR_MPERF 0xE7 +#define MSR_PKG_C2_RESIDENCY 0x60D +#define MSR_PKG_C3_RESIDENCY 0x3F8 +#define MSR_PKG_C6_RESIDENCY 0x3F9 +#define MSR_PKG_C7_RESIDENCY 0x3FA +#define MSR_PKG_C8_RESIDENCY 0x630 +#define MSR_PKG_C9_RESIDENCY 0x631 +#define MSR_PKG_C10_RESIDENCY 0x632 +#define MSR_CORE_C1_RESIDENCY 0x660 +#define MSR_CORE_C3_RESIDENCY 0x3FC +#define MSR_CORE_C6_RESIDENCY 0x3FD +#define MSR_CORE_C7_RESIDENCY 0x3FE + +class intel_util +{ +protected: + int byt_ahci_support; + DIR *dir; +public: + intel_util(); + virtual void byt_has_ahci(); + virtual int get_byt_ahci_support(); +}; + +class nhm_package: public cpu_package, public intel_util +{ +private: + uint64_t c2_before, c2_after; + uint64_t c3_before, c3_after; + uint64_t c6_before, c6_after; + uint64_t c7_before, c7_after; + uint64_t c8_before, c8_after; + uint64_t c9_before, c9_after; + uint64_t c10_before, c10_after; + uint64_t tsc_before, tsc_after; + + uint64_t last_stamp; + uint64_t total_stamp; +public: + int has_c7_res; + int has_c2c6_res; + int has_c3_res; + int has_c6c_res; /* BSW */ + int has_c8c9c10_res; + nhm_package(int model); + virtual void measurement_start(void); + virtual void measurement_end(void); + virtual int can_collapse(void) { return 0;}; + + virtual char * fill_pstate_line(int line_nr, char *buffer); +}; + +class nhm_core: public cpu_core, public intel_util +{ +private: + uint64_t c1_before, c1_after; + uint64_t c3_before, c3_after; + uint64_t c6_before, c6_after; + uint64_t c7_before, c7_after; + uint64_t tsc_before, tsc_after; + + uint64_t last_stamp; + uint64_t total_stamp; +public: + int has_c1_res; + int has_c7_res; + int has_c3_res; + nhm_core(int model); + virtual void measurement_start(void); + virtual void measurement_end(void); + virtual int can_collapse(void) { return 0;}; + + virtual char * fill_pstate_line(int line_nr, char *buffer); +}; + +class nhm_cpu: public cpu_linux, public intel_util +{ +private: + uint64_t aperf_before; + uint64_t aperf_after; + uint64_t mperf_before; + uint64_t mperf_after; + uint64_t tsc_before, tsc_after; + + uint64_t last_stamp; + uint64_t total_stamp; +public: + virtual void measurement_start(void); + virtual void measurement_end(void); + virtual int can_collapse(void) { return 0;}; + + virtual char * fill_pstate_name(int line_nr, char *buffer); + virtual char * fill_pstate_line(int line_nr, char *buffer); + virtual int has_pstate_level(int level); +}; + +class atom_package: public cpu_package +{ +public: + virtual void measurement_start(void); + virtual void measurement_end(void); + +}; + +class atom_core: public cpu_core +{ +public: + virtual void measurement_start(void); + virtual void measurement_end(void); + +}; + + +class i965_core: public cpu_core +{ +private: + uint64_t rc6_before, rc6_after; + uint64_t rc6p_before, rc6p_after; + uint64_t rc6pp_before, rc6pp_after; + + struct timeval before; + struct timeval after; + +public: + virtual void measurement_start(void); + virtual void measurement_end(void); + virtual int can_collapse(void) { return 0;}; + + virtual char * fill_pstate_line(int line_nr, char *buffer); + virtual char * fill_pstate_name(int line_nr, char *buffer); + virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator); + virtual int has_pstate_level(int level) { return 0; }; + virtual int has_pstates(void) { return 0; }; + virtual void wiggle(void) { }; + +}; + +int is_supported_intel_cpu(int model, int cpu); +int byt_has_ahci(); + +int is_intel_pstate_driver_loaded(); + +#endif diff --git a/src/cpu/intel_gpu.cpp b/src/cpu/intel_gpu.cpp new file mode 100644 index 0000000..e0f4ac2 --- /dev/null +++ b/src/cpu/intel_gpu.cpp @@ -0,0 +1,122 @@ +/* + * Copyright 2012, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "intel_cpus.h" +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <stdint.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/time.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> + +#include "../lib.h" +#include "../parameters/parameters.h" +#include "../display.h" + +void i965_core::measurement_start(void) +{ + ifstream file; + + gettimeofday(&before, NULL); + rc6_before = read_sysfs("/sys/class/drm/card0/power/rc6_residency_ms", NULL); + rc6p_before = read_sysfs("/sys/class/drm/card0/power/rc6p_residency_ms", NULL); + rc6pp_before = read_sysfs("/sys/class/drm/card0/power/rc6pp_residency_ms", NULL); + + update_cstate("gpu c0", "Powered On", 0, 0, 1, 0); + update_cstate("gpu rc6", "RC6", 0, rc6_before, 1, 1); + update_cstate("gpu rc6p", "RC6p", 0, rc6p_before, 1, 2); + update_cstate("gpu rc6pp", "RC6pp", 0, rc6pp_before, 1, 3); +} + +char * i965_core::fill_cstate_line(int line_nr, char *buffer, const char *separator) +{ + buffer[0] = 0; + double ratio, d = -1.0, time_delta; + + if (line_nr == LEVEL_HEADER) { + sprintf(buffer,_(" GPU ")); + return buffer; + } + + buffer[0] = 0; + + time_delta = 1000000 * (after.tv_sec - before.tv_sec) + after.tv_usec - before.tv_usec; + ratio = 100000.0/time_delta; + + switch (line_nr) { + case 0: + d = 100.0 - ratio * (rc6_after + rc6p_after + rc6pp_after - rc6_before - rc6p_before - rc6pp_before); + break; + case 1: + d = ratio * (rc6_after - rc6_before); + break; + case 2: + d = ratio * (rc6p_after - rc6p_before); + break; + case 3: + d = ratio * (rc6pp_after - rc6pp_before); + break; + default: + return buffer; + } + + /* cope with rounding errors due to the measurement interval */ + if (d < 0.0) + d = 0.0; + if (d > 100.0) + d = 100.0; + + sprintf(buffer,"%5.1f%%", d); + + return buffer; +} + + +void i965_core::measurement_end(void) +{ + gettimeofday(&after, NULL); + + rc6_after = read_sysfs("/sys/class/drm/card0/power/rc6_residency_ms", NULL); + rc6p_after = read_sysfs("/sys/class/drm/card0/power/rc6p_residency_ms", NULL); + rc6pp_after = read_sysfs("/sys/class/drm/card0/power/rc6pp_residency_ms", NULL); +} + +char * i965_core::fill_pstate_line(int line_nr, char *buffer) +{ + buffer[0] = 0; + return buffer; +} + +char * i965_core::fill_pstate_name(int line_nr, char *buffer) +{ + buffer[0] = 0; + return buffer; +} + diff --git a/src/cpu/rapl/rapl_interface.cpp b/src/cpu/rapl/rapl_interface.cpp new file mode 100644 index 0000000..d6bd4c8 --- /dev/null +++ b/src/cpu/rapl/rapl_interface.cpp @@ -0,0 +1,699 @@ +/* rapl_interface.cpp: rapl interface for power top implementation + * + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * Author Name <Srinivas.Pandruvada@linux.intel.com> + * + */ +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <math.h> +#include <stdlib.h> +#include <dirent.h> +#include "lib.h" +#include "rapl_interface.h" + +#ifdef DEBUG +#define RAPL_DBG_PRINT printf +#define RAPL_ERROR_PRINT printf +#else +#define RAPL_DBG_PRINT(...) ((void) 0) +#define RAPL_ERROR_PRINT(...) ((void) 0) +#endif +#define RAPL_INFO_PRINT(format, m) fprintf(stderr, format, m) + +#define MAX_TEMP_STR_SIZE 20 + +// RAPL interface +#define MSR_RAPL_POWER_UNIT 0x606 +#define MSR_PKG_POWER_LIMIT 0x610 + +#define MSR_PKG_ENERY_STATUS 0x611 +#define MSR_PKG_POWER_INFO 0x614 +#define MSR_PKG_PERF_STATUS 0x613 + +#define MSR_DRAM_POWER_LIMIT 0x618 +#define MSR_DRAM_ENERY_STATUS 0x619 +#define MSR_DRAM_PERF_STATUS 0x61B +#define MSR_DRAM_POWER_INFO 0x61c + +#define MSR_PP0_POWER_LIMIT 0x638 +#define MSR_PP0_ENERY_STATUS 0x639 +#define MSR_PP0_POLICY 0x63A +#define MSR_PP0_PERF_STATUS 0x63B + +#define MSR_PP1_POWER_LIMIT 0x640 +#define MSR_PP1_ENERY_STATUS 0x641 +#define MSR_PP1_POLICY 0x642 + +#define PKG_DOMAIN_PRESENT 0x01 +#define DRAM_DOMAIN_PRESENT 0x02 +#define PP0_DOMAIN_PRESENT 0x04 +#define PP1_DOMAIN_PRESENT 0x08 + +c_rapl_interface::c_rapl_interface(const char *dev_name, int cpu) : + powercap_sysfs_present(false), + powercap_core_path(), + powercap_uncore_path(), + powercap_dram_path(), + first_cpu(cpu), + measurment_interval(def_sampling_interval), + last_pkg_energy_status(0.0), + last_dram_energy_status(0.0), + last_pp0_energy_status(0.0), + last_pp1_energy_status(0.0) +{ + uint64_t value; + int ret; + string package_path; + DIR *dir; + struct dirent *entry; + + RAPL_INFO_PRINT("RAPL device for cpu %d\n", cpu); + + rapl_domains = 0; + + if (dev_name) { + string base_path = "/sys/class/powercap/intel-rapl/"; + if ((dir = opendir(base_path.c_str())) != NULL) { + while ((entry = readdir(dir)) != NULL) { + string path = base_path + entry->d_name + "/name"; + string str = read_sysfs_string(path); + if (str.length() > 0) { + if (str == dev_name) { + package_path = base_path + entry->d_name + "/"; + powercap_sysfs_present = true; + rapl_domains |= PKG_DOMAIN_PRESENT; + break; + } + } + } + closedir(dir); + } + } + + if (powercap_sysfs_present) { + if ((dir = opendir(package_path.c_str())) != NULL) { + while ((entry = readdir(dir)) != NULL) { + string path = package_path + entry->d_name; + string str = read_sysfs_string(path + "/name"); + if (str.length() > 0) { + if (str == "core") { + rapl_domains |= PP0_DOMAIN_PRESENT; + powercap_core_path = path + "/"; + } + else if (str == "dram") { + rapl_domains |= DRAM_DOMAIN_PRESENT; + powercap_dram_path = path + "/"; + } + else if (str == "uncore") { + rapl_domains |= PP1_DOMAIN_PRESENT; + powercap_uncore_path = path + "/"; + } + } + } + closedir(dir); + } + + RAPL_INFO_PRINT("RAPL Using PowerCap Sysfs : Domain Mask %x\n", rapl_domains); + return; + } + + // Fallback to using MSRs + + // presence of each domain + // Check presence of PKG domain + ret = read_msr(first_cpu, MSR_PKG_ENERY_STATUS, &value); + if (ret > 0) { + rapl_domains |= PKG_DOMAIN_PRESENT; + RAPL_DBG_PRINT("Domain : PKG present\n"); + } else { + RAPL_DBG_PRINT("Domain : PKG Not present\n"); + } + + // Check presence of DRAM domain + ret = read_msr(first_cpu, MSR_DRAM_ENERY_STATUS, &value); + if (ret > 0) { + rapl_domains |= DRAM_DOMAIN_PRESENT; + RAPL_DBG_PRINT("Domain : DRAM present\n"); + } else { + RAPL_DBG_PRINT("Domain : DRAM Not present\n"); + } + + // Check presence of PP0 domain + ret = read_msr(first_cpu, MSR_PP0_ENERY_STATUS, &value); + if (ret > 0) { + rapl_domains |= PP0_DOMAIN_PRESENT; + RAPL_DBG_PRINT("Domain : PP0 present\n"); + } else { + RAPL_DBG_PRINT("Domain : PP0 Not present\n"); + } + + // Check presence of PP1 domain + ret = read_msr(first_cpu, MSR_PP1_ENERY_STATUS, &value); + if (ret > 0) { + rapl_domains |= PP1_DOMAIN_PRESENT; + RAPL_DBG_PRINT("Domain : PP1 present\n"); + } else { + RAPL_DBG_PRINT("Domain : PP1 Not present\n"); + } + + power_units = get_power_unit(); + energy_status_units = get_energy_status_unit(); + time_units = get_time_unit(); + + RAPL_DBG_PRINT("RAPL Domain mask: %x\n", rapl_domains); +} + +bool c_rapl_interface::pkg_domain_present() +{ + if ((rapl_domains & PKG_DOMAIN_PRESENT)) { + return true; + } + + return false; +} + +bool c_rapl_interface::dram_domain_present() +{ + if ((rapl_domains & DRAM_DOMAIN_PRESENT)) { + return true; + } + + return false; +} + +bool c_rapl_interface::pp0_domain_present() +{ + if ((rapl_domains & PP0_DOMAIN_PRESENT)) { + return true; + } + + return false; +} + +bool c_rapl_interface::pp1_domain_present() +{ + if ((rapl_domains & PP1_DOMAIN_PRESENT)) { + return true; + } + + return false; +} + +int c_rapl_interface::read_msr(int cpu, unsigned int idx, uint64_t *val) +{ + return ::read_msr(cpu, idx, val); +} + +int c_rapl_interface::write_msr(int cpu, unsigned int idx, uint64_t val) +{ + return ::write_msr(cpu, idx, val); +} + +int c_rapl_interface::get_rapl_power_unit(uint64_t *value) +{ + int ret; + + ret = read_msr(first_cpu, MSR_RAPL_POWER_UNIT, value); + + return ret; +} + +double c_rapl_interface::get_power_unit() +{ + int ret; + uint64_t value; + + ret = get_rapl_power_unit(&value); + if(ret < 0) + { + return ret; + } + + return (double) 1/pow((double)2, (double)(value & 0xf)); +} + +double c_rapl_interface::get_energy_status_unit() +{ + int ret; + uint64_t value; + + ret = get_rapl_power_unit(&value); + if(ret < 0) + { + return ret; + } + + return (double)1/ pow((double)2, (double)((value & 0x1f00) >> 8)); +} + +double c_rapl_interface::get_time_unit() +{ + int ret; + uint64_t value; + + ret = get_rapl_power_unit(&value); + if(ret < 0) + { + return ret; + } + + return (double)1 / pow((double)2, (double)((value & 0xf0000) >> 16)); +} + +int c_rapl_interface::get_pkg_energy_status(double *status) +{ + int ret; + uint64_t value; + + if (!pkg_domain_present()) { + return -1; + } + + ret = read_msr(first_cpu, MSR_PKG_ENERY_STATUS, &value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pkg_energy_status failed\n"); + return ret; + } + + *status = (double) (value & 0xffffffff) * get_energy_status_unit(); + + return ret; +} + +int c_rapl_interface::get_pkg_power_info(double *thermal_spec_power, + double *max_power, double *min_power, double *max_time_window) +{ + int ret; + uint64_t value; + + if (!pkg_domain_present()) { + return -1; + } + ret = read_msr(first_cpu, MSR_PKG_POWER_INFO, &value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pkg_power_info failed\n"); + return ret; + } + *thermal_spec_power = (value & 0x7FFF) * power_units; + *min_power = ((value & 0x7FFF0000) >> 16) * power_units; + *max_power = ((value & 0x7FFF00000000) >> 32) * power_units; + *max_time_window = ((value & 0x3f000000000000)>>48) * time_units; + + return ret; +} + +int c_rapl_interface::get_pkg_power_limit(uint64_t *value) +{ + int ret; + + if (!pkg_domain_present()) { + return -1; + } + + ret = read_msr(first_cpu, MSR_PKG_POWER_LIMIT, value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pkg_power_limit failed\n"); + return ret; + } + + return ret; +} + +int c_rapl_interface::set_pkg_power_limit(uint64_t value) +{ + int ret; + + if (!pkg_domain_present()) { + return -1; + } + + ret = write_msr(first_cpu, MSR_PKG_POWER_LIMIT, value); + if(ret < 0) + { + RAPL_ERROR_PRINT("set_pkg_power_limit failed\n"); + return ret; + } + + return ret; +} + +int c_rapl_interface::get_dram_energy_status(double *status) +{ + int ret; + uint64_t value; + + if (!dram_domain_present()) { + return -1; + } + + if (powercap_sysfs_present) { + string str = read_sysfs_string(powercap_dram_path + "energy_uj"); + if (str.length() > 0) { + *status = atof(str.c_str()) / 1000000; // uj to Js + return 0; + } + + return -EINVAL; + } + + ret = read_msr(first_cpu, MSR_DRAM_ENERY_STATUS, &value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_dram_energy_status failed\n"); + return ret; + } + + *status = (double) (value & 0xffffffff) * get_energy_status_unit(); + + return ret; +} + +int c_rapl_interface::get_dram_power_info(double *thermal_spec_power, + double *max_power, double *min_power, double *max_time_window) +{ + int ret; + uint64_t value; + + if (!dram_domain_present()) { + return -1; + } + ret = read_msr(first_cpu, MSR_DRAM_POWER_INFO, &value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_dram_power_info failed\n"); + return ret; + } + + *thermal_spec_power = (value & 0x7FFF) * power_units; + *min_power = ((value & 0x7FFF0000) >> 16) * power_units; + *max_power = ((value & 0x7FFF00000000) >> 32) * power_units; + *max_time_window = ((value & 0x3f000000000000)>>48) * time_units; + + return ret; +} + +int c_rapl_interface::get_dram_power_limit(uint64_t *value) +{ + int ret; + + if (!dram_domain_present()) { + return -1; + } + + ret = read_msr(first_cpu, MSR_DRAM_POWER_LIMIT, value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_dram_power_limit failed\n"); + return ret; + } + + return ret; +} + +int c_rapl_interface::set_dram_power_limit(uint64_t value) +{ + int ret; + + if (!dram_domain_present()) { + return -1; + } + + ret = write_msr(first_cpu, MSR_DRAM_POWER_LIMIT, value); + if(ret < 0) + { + RAPL_ERROR_PRINT("set_dram_power_limit failed\n"); + return ret; + } + + return ret; +} + +int c_rapl_interface::get_pp0_energy_status(double *status) +{ + int ret; + uint64_t value; + + if (!pp0_domain_present()) { + return -1; + } + + if (powercap_sysfs_present) { + string str = read_sysfs_string(powercap_core_path + "energy_uj"); + if (str.length() > 0) { + *status = atof(str.c_str()) / 1000000; // uj to Js + return 0; + } + + return -EINVAL; + } + + ret = read_msr(first_cpu, MSR_PP0_ENERY_STATUS, &value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pp0_energy_status failed\n"); + return ret; + } + + *status = (double) (value & 0xffffffff) * get_energy_status_unit(); + + return ret; +} + +int c_rapl_interface::get_pp0_power_limit(uint64_t *value) +{ + int ret; + + if (!pp0_domain_present()) { + return -1; + } + + ret = read_msr(first_cpu, MSR_PP0_POWER_LIMIT, value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pp0_power_limit failed\n"); + return ret; + } + + return ret; +} + +int c_rapl_interface::set_pp0_power_limit(uint64_t value) +{ + int ret; + + if (!pp0_domain_present()) { + return -1; + } + + ret = write_msr(first_cpu, MSR_PP0_POWER_LIMIT, value); + if(ret < 0) + { + RAPL_ERROR_PRINT("set_pp0_power_limit failed\n"); + return ret; + } + + return ret; +} + +int c_rapl_interface::get_pp0_power_policy(unsigned int *pp0_power_policy) +{ + int ret; + uint64_t value; + + if (!pp0_domain_present()) { + return -1; + } + + ret = read_msr(first_cpu, MSR_PP0_POLICY, &value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pp0_power_policy failed\n"); + return ret; + } + + *pp0_power_policy = value & 0x0f; + + return ret; +} + +int c_rapl_interface::get_pp1_energy_status(double *status) +{ + int ret; + uint64_t value; + + if (!pp1_domain_present()) { + return -1; + } + + if (powercap_sysfs_present) { + string str = read_sysfs_string(powercap_uncore_path + "energy_uj"); + if (str.length() > 0) { + *status = atof(str.c_str()) / 1000000; // uj to Js + return 0; + } + + return -EINVAL; + } + + ret = read_msr(first_cpu, MSR_PP1_ENERY_STATUS, &value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pp1_energy_status failed\n"); + return ret; + } + + *status = (double) (value & 0xffffffff) * get_energy_status_unit(); + + return ret; +} + +int c_rapl_interface::get_pp1_power_limit(uint64_t *value) +{ + int ret; + + if (!pp1_domain_present()) { + return -1; + } + + ret = read_msr(first_cpu, MSR_PP1_POWER_LIMIT, value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pp1_power_info failed\n"); + return ret; + } + + return ret; +} + +int c_rapl_interface::set_pp1_power_limit(uint64_t value) +{ + int ret; + + if (!pp1_domain_present()) { + return -1; + } + + ret = write_msr(first_cpu, MSR_PP1_POWER_LIMIT, value); + if(ret < 0) + { + RAPL_ERROR_PRINT("set_pp1_power_limit failed\n"); + return ret; + } + + return ret; +} + +int c_rapl_interface::get_pp1_power_policy(unsigned int *pp1_power_policy) +{ + int ret; + uint64_t value; + + if (!pp1_domain_present()) { + return -1; + } + + ret = read_msr(first_cpu, MSR_PP1_POLICY, &value); + if(ret < 0) + { + RAPL_ERROR_PRINT("get_pp1_power_policy failed\n"); + return ret; + } + + *pp1_power_policy = value & 0x0f; + + return ret; +} + +void c_rapl_interface::rapl_measure_energy() +{ +#ifdef RAPL_TEST_MODE + int ret; + double energy_status; + double thermal_spec_power; + double max_power; + double min_power; + double max_time_window; + double pkg_watts = 0; + double dram_watts = 0; + double pp0_watts = 0; + double pp1_watts = 0; + double pkg_joules = 0; + double dram_joules = 0; + double pp0_joules = 0; + double pp1_joules = 0; + + get_pkg_power_info(&thermal_spec_power, &max_power, &min_power, &max_time_window); + RAPL_DBG_PRINT("Pkg Power Info: Thermal spec %f watts, max %f watts, min %f watts, max time window %f seconds\n", thermal_spec_power, max_power, min_power, max_time_window); + get_dram_power_info(&thermal_spec_power, &max_power, &min_power, &max_time_window); + RAPL_DBG_PRINT("DRAM Power Info: Thermal spec %f watts, max %f watts, min %f watts, max time window %f seconds\n", thermal_spec_power, max_power, min_power, max_time_window); + + for (;;) { + if (pkg_domain_present()) { + ret = get_pkg_energy_status(&energy_status); + if (last_pkg_energy_status == 0) + last_pkg_energy_status = energy_status; + if (ret > 0) { + pkg_joules = energy_status; + pkg_watts = (energy_status-last_pkg_energy_status)/measurment_interval; + } + last_pkg_energy_status = energy_status; + } + if (dram_domain_present()) { + ret = get_dram_energy_status(&energy_status); + if (last_dram_energy_status == 0) + last_dram_energy_status = energy_status; + if (ret > 0){ + dram_joules = energy_status; + dram_watts = (energy_status-last_dram_energy_status)/measurment_interval; + } + last_dram_energy_status = energy_status; + } + if (pp0_domain_present()) { + ret = get_pp0_energy_status(&energy_status); + if (last_pp0_energy_status == 0) + last_pp0_energy_status = energy_status; + if (ret > 0){ + pp0_joules = energy_status; + pp0_watts = (energy_status-last_pp0_energy_status)/measurment_interval; + } + last_pp0_energy_status = energy_status; + } + if (pp1_domain_present()) { + ret = get_pp1_energy_status(&energy_status); + if (last_pp1_energy_status == 0) + last_pp1_energy_status = energy_status; + if (ret > 0){ + pp1_joules = energy_status; + pp1_watts = (energy_status-last_pp1_energy_status)/measurment_interval; + } + last_pp1_energy_status = energy_status; + } + RAPL_DBG_PRINT("%f, %f, %f, %f\n", pkg_watts, dram_watts, pp0_watts, pp1_watts); + sleep(measurment_interval); + } +#endif +} diff --git a/src/cpu/rapl/rapl_interface.h b/src/cpu/rapl/rapl_interface.h new file mode 100644 index 0000000..c8e9683 --- /dev/null +++ b/src/cpu/rapl/rapl_interface.h @@ -0,0 +1,91 @@ +/* rapl_interface.h: rapl interface for power top + * + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * Author Name <Srinivas.Pandruvada@linux.intel.com> + * + */ + +#ifndef RAPL_INTERFACE_H +#define RAPL_INTERFACE_H + +class c_rapl_interface +{ +private: + static const int def_sampling_interval = 1; //In seconds + bool powercap_sysfs_present; + string powercap_core_path; + string powercap_uncore_path; + string powercap_dram_path; + + unsigned char rapl_domains; + int first_cpu; + + double power_units; + double energy_status_units; + double time_units; + + int read_msr(int cpu, unsigned int idx, uint64_t *val); + int write_msr(int cpu, unsigned int idx, uint64_t val); + +protected: + int measurment_interval; + double last_pkg_energy_status; + double last_dram_energy_status; + double last_pp0_energy_status; + double last_pp1_energy_status; + +public: + c_rapl_interface(const char *dev_name = "package-0", int cpu = 0); + + int get_rapl_power_unit(uint64_t *value); + double get_power_unit(); + double get_energy_status_unit(); + double get_time_unit(); + + int get_pkg_energy_status(double *status); + int get_pkg_power_info(double *thermal_spec_power, + double *max_power, double *min_power, double *max_time_window); + int get_pkg_power_limit(uint64_t *value); + int set_pkg_power_limit(uint64_t value); + + int get_dram_energy_status(double *status); + int get_dram_power_info(double *thermal_spec_power, + double *max_power, double *min_power, double *max_time_window); + int get_dram_power_limit(uint64_t *value); + int set_dram_power_limit(uint64_t value); + + int get_pp0_energy_status(double *status); + int get_pp0_power_limit(uint64_t *value); + int set_pp0_power_limit(uint64_t value); + int get_pp0_power_policy(unsigned int *pp0_power_policy); + + int get_pp1_energy_status(double *status); + int get_pp1_power_limit(uint64_t *value); + int set_pp1_power_limit(uint64_t value); + int get_pp1_power_policy(unsigned int *pp1_power_policy); + + bool pkg_domain_present(); + bool dram_domain_present(); + bool pp0_domain_present(); + bool pp1_domain_present(); + + void rapl_measure_energy(); +}; + +#endif diff --git a/src/csstoh.sh b/src/csstoh.sh new file mode 100755 index 0000000..681e6a5 --- /dev/null +++ b/src/csstoh.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# This program file 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; version 2 of the License. +# +# 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 in a file named COPYING; if not, write to the +# Free Software Foundation, Inc, +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# or just google for it. +# +# Written by Igor Zhbanov <i.zhbanov at samsung.com> + +if [ $# -ne 2 ]; then + echo "Usage: csstoh.sh cssfile header.h" >&2 + exit 1 +fi +if [ ! -f "$1" ]; then + echo "$1: no such file or directory" >&2 + exit 1 +fi +# redirect stdout to a file +exec 1> "$2" || exit $? + +# header +cat <<HERE || exit $? +#ifndef __INCLUDE_GUARD_CCS_H +#define __INCLUDE_GUARD_CCS_H + +const char css[] = +HERE +# body +sed -r 's/^[ \t]*//; s/^(.*)$/\t\"\1\\n\"/' "$1" || exit $? +# footer +cat <<HERE || exit $? +; +#endif +HERE + +# close output file +exec 1>&- +# return status of output file write +exit $? diff --git a/src/devices/ahci.cpp b/src/devices/ahci.cpp new file mode 100644 index 0000000..efa66b3 --- /dev/null +++ b/src/devices/ahci.cpp @@ -0,0 +1,428 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> + +#include <stdio.h> +#include <sys/types.h> +#include <dirent.h> +#include <limits.h> + + +using namespace std; + +#include "device.h" +#include "report/report.h" +#include "report/report-maker.h" +#include "ahci.h" +#include "../parameters/parameters.h" +#include "report/report-data-html.h" +#include <string.h> + +vector <class ahci *> links; + +static string disk_name(char *path, char *target, char *shortname) +{ + + DIR *dir; + struct dirent *dirent; + char pathname[PATH_MAX]; + string diskname = ""; + + snprintf(pathname, sizeof(pathname), "%s/%s", path, target); + dir = opendir(pathname); + if (!dir) + return diskname; + + while ((dirent = readdir(dir))) { + char line[4096], *c; + FILE *file; + if (dirent->d_name[0]=='.') + continue; + + if (!strchr(dirent->d_name, ':')) + continue; + + snprintf(line, sizeof(line), "%s/%s/model", pathname, dirent->d_name); + file = fopen(line, "r"); + if (file) { + if (fgets(line, sizeof(line), file) == NULL) { + fclose(file); + break; + } + fclose(file); + c = strchr(line, '\n'); + if (c) + *c = 0; + diskname = line; + break; + } + } + closedir(dir); + + return diskname; +} + +static string model_name(char *path, char *shortname) +{ + + DIR *dir; + struct dirent *dirent; + char pathname[PATH_MAX]; + + snprintf(pathname, sizeof(pathname), "%s/device", path); + + dir = opendir(pathname); + if (!dir) + return strdup(shortname); + + while ((dirent = readdir(dir))) { + if (dirent->d_name[0]=='.') + continue; + + if (!strchr(dirent->d_name, ':')) + continue; + if (!strstr(dirent->d_name, "target")) + continue; + return disk_name(pathname, dirent->d_name, shortname); + } + closedir(dir); + + return ""; +} + +ahci::ahci(char *_name, char *path): device() +{ + char buffer[4096]; + char devname[128]; + string diskname; + + end_active = 0; + end_slumber = 0; + end_devslp = 0; + end_partial = 0; + start_active = 0; + start_slumber = 0; + start_devslp = 0; + start_partial = 0; + pt_strcpy(sysfs_path, path); + + register_sysfs_path(sysfs_path); + + snprintf(devname, sizeof(devname), "ahci:%s", _name); + pt_strcpy(name, devname); + active_index = get_param_index("ahci-link-power-active"); + partial_index = get_param_index("ahci-link-power-partial"); + + snprintf(buffer, sizeof(buffer), "%s-active", name); + active_rindex = get_result_index(buffer); + + snprintf(buffer, sizeof(buffer), "%s-partial", name); + partial_rindex = get_result_index(buffer); + + snprintf(buffer, sizeof(buffer), "%s-slumber", name); + slumber_rindex = get_result_index(buffer); + + snprintf(buffer, sizeof(buffer), "%s-devslp", name); + devslp_rindex = get_result_index(buffer); + + diskname = model_name(path, _name); + + if (strlen(diskname.c_str()) == 0) + snprintf(humanname, sizeof(humanname), _("SATA link: %s"), _name); + else + snprintf(humanname, sizeof(humanname), _("SATA disk: %s"), diskname.c_str()); +} + +void ahci::start_measurement(void) +{ + char filename[PATH_MAX]; + ifstream file; + + snprintf(filename, sizeof(filename), "%s/ahci_alpm_active", sysfs_path); + try { + file.open(filename, ios::in); + if (file) { + file >> start_active; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/ahci_alpm_partial", sysfs_path); + file.open(filename, ios::in); + + if (file) { + file >> start_partial; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/ahci_alpm_slumber", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> start_slumber; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/ahci_alpm_devslp", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> start_devslp; + } + file.close(); + } + catch (std::ios_base::failure &c) { + fprintf(stderr, "%s\n", c.what()); + } + +} + +void ahci::end_measurement(void) +{ + char filename[PATH_MAX]; + char powername[4096]; + ifstream file; + double p; + double total; + + try { + snprintf(filename, sizeof(filename), "%s/ahci_alpm_active", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> end_active; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/ahci_alpm_partial", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> end_partial; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/ahci_alpm_slumber", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> end_slumber; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/ahci_alpm_devslp", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> end_devslp; + } + file.close(); + } + catch (std::ios_base::failure &c) { + fprintf(stderr, "%s\n", c.what()); + } + if (end_active < start_active) + end_active = start_active; + if (end_partial < start_partial) + end_partial = start_partial; + if (end_slumber < start_slumber) + end_slumber = start_slumber; + + total = 0.001 + end_active + end_partial + end_slumber + end_devslp - + start_active - start_partial - start_slumber - start_devslp; + + /* percent in active */ + p = (end_active - start_active) / total * 100.0; + if (p < 0) + p = 0; + snprintf(powername, sizeof(powername), "%s-active", name); + report_utilization(powername, p); + + /* percent in partial */ + p = (end_partial - start_partial) / total * 100.0; + if (p < 0) + p = 0; + snprintf(powername, sizeof(powername), "%s-partial", name); + report_utilization(powername, p); + + /* percent in slumber */ + p = (end_slumber - start_slumber) / total * 100.0; + if (p < 0) + p = 0; + snprintf(powername, sizeof(powername), "%s-slumber", name); + report_utilization(powername, p); + + /* percent in devslp */ + p = (end_devslp - start_devslp) / total * 100.0; + if (p < 0) + p = 0; + snprintf(powername, sizeof(powername), "%s-devslp", name); + report_utilization(powername, p); +} + + +double ahci::utilization(void) +{ + double p; + + p = (end_partial - start_partial + end_active - start_active) / (0.001 + end_active + end_partial + end_slumber + end_devslp - start_active - start_partial - start_slumber - start_devslp) * 100.0; + + if (p < 0) + p = 0; + + return p; +} + +const char * ahci::device_name(void) +{ + return name; +} + +void create_all_ahcis(void) +{ + struct dirent *entry; + DIR *dir; + char filename[PATH_MAX]; + + dir = opendir("/sys/class/scsi_host/"); + if (!dir) + return; + while (1) { + class ahci *bl; + ofstream file; + ifstream check_file; + entry = readdir(dir); + if (!entry) + break; + if (entry->d_name[0] == '.') + continue; + snprintf(filename, sizeof(filename), "/sys/class/scsi_host/%s/ahci_alpm_accounting", entry->d_name); + + check_file.open(filename, ios::in); + check_file.get(); + check_file.close(); + if (check_file.bad()) + continue; + + file.open(filename, ios::in); + if (!file) + continue; + file << 1 ; + file.close(); + snprintf(filename, sizeof(filename), "/sys/class/scsi_host/%s", entry->d_name); + + bl = new class ahci(entry->d_name, filename); + all_devices.push_back(bl); + register_parameter("ahci-link-power-active", 0.6); /* active sata link takes about 0.6 W */ + register_parameter("ahci-link-power-partial"); + links.push_back(bl); + } + closedir(dir); + +} + + + +double ahci::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + + power = 0; + + factor = get_parameter_value(active_index, bundle); + util = get_result_value(active_rindex, result); + power += util * factor / 100.0; + + + factor = get_parameter_value(partial_index, bundle); + util = get_result_value(partial_rindex, result); + power += util * factor / 100.0; + + return power; +} + +void ahci_create_device_stats_table(void) +{ + unsigned int i; + int cols=0; + int rows=0; + + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "clear_block", "ahci"); + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Add section */ + report.add_div(&div_attr); + + if (links.size() == 0) { + report.add_title(&title_attr, __("AHCI ALPM Residency Statistics - Not supported on this macine")); + report.end_div(); + return; + } + + /* Set Table attributes, rows, and cols */ + table_attributes std_table_css; + cols=5; + rows=links.size()+1; + init_std_side_table_attr(&std_table_css, rows, cols); + + + + /* Set array of data in row Major order */ + string *ahci_data = new string[cols * rows]; + ahci_data[0]=__("Link"); + ahci_data[1]=__("Active"); + ahci_data[2]=__("Partial"); + ahci_data[3]=__("Slumber"); + ahci_data[4]=__("Devslp"); + + /* traverse list of all devices and put their residency in the table */ + for (i = 0; i < links.size(); i++){ + links[i]->report_device_stats(ahci_data, i); + } + report.add_title(&title_attr, __("AHCI ALPM Residency Statistics")); + report.add_table(ahci_data, &std_table_css); + report.end_div(); + delete [] ahci_data; +} + +void ahci::report_device_stats(string *ahci_data, int idx) +{ + int offset=(idx*5+5); + char util[128]; + double active_util = get_result_value(active_rindex, &all_results); + double partial_util = get_result_value(partial_rindex, &all_results); + double slumber_util = get_result_value(slumber_rindex, &all_results); + double devslp_util = get_result_value(devslp_rindex, &all_results); + + snprintf(util, sizeof(util), "%5.1f", active_util); + ahci_data[offset]= util; + offset +=1; + + snprintf(util, sizeof(util), "%5.1f", partial_util); + ahci_data[offset]= util; + offset +=1; + + snprintf(util, sizeof(util), "%5.1f", slumber_util); + ahci_data[offset]= util; + offset +=1; + + snprintf(util, sizeof(util), "%5.1f", devslp_util); + ahci_data[offset]= util; +} diff --git a/src/devices/ahci.h b/src/devices/ahci.h new file mode 100644 index 0000000..7431fb5 --- /dev/null +++ b/src/devices/ahci.h @@ -0,0 +1,72 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_AHCI_H +#define _INCLUDE_GUARD_AHCI_H + + +#include <string> +#include <limits.h> +#include "device.h" +#include "../parameters/parameters.h" +#include <stdint.h> + +class ahci: public device { + uint64_t start_active, end_active; + uint64_t start_partial, end_partial; + uint64_t start_slumber, end_slumber; + uint64_t start_devslp, end_devslp; + char sysfs_path[PATH_MAX]; + char name[4096]; + int partial_rindex; + int active_rindex; + int slumber_rindex; + int devslp_rindex; + int partial_index; + int active_index; + char humanname[4096]; +public: + + ahci(char *_name, char *path); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "ahci";}; + + virtual const char * device_name(void); + virtual const char * human_name(void) { return humanname;}; + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual int power_valid(void) { return utilization_power_valid(partial_rindex) + utilization_power_valid(active_rindex);}; + virtual int grouping_prio(void) { return 1; }; + virtual void report_device_stats(string *ahci_data, int idx); +}; + +extern void create_all_ahcis(void); +extern void ahci_create_device_stats_table(void); + + +#endif diff --git a/src/devices/alsa.cpp b/src/devices/alsa.cpp new file mode 100644 index 0000000..7e22975 --- /dev/null +++ b/src/devices/alsa.cpp @@ -0,0 +1,207 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> + +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + +using namespace std; + +#include "device.h" +#include "alsa.h" +#include "../parameters/parameters.h" + +#include "../devlist.h" + +#include <string.h> +#include <unistd.h> + +alsa::alsa(const char *_name, const char *path): device() +{ + ifstream file; + + char devname[4096]; + char model[4096]; + char vendor[4096]; + end_active = 0; + start_active = 0; + end_inactive = 0; + start_inactive = 0; + pt_strcpy(sysfs_path, path); + + snprintf(devname, sizeof(devname), "alsa:%s", _name); + snprintf(humanname, sizeof(humanname), "alsa:%s", _name); + pt_strcpy(name, devname); + rindex = get_result_index(name); + + guilty[0] = 0; + model[0] = 0; + vendor[0] = 0; + snprintf(devname, sizeof(devname), "%s/modelname", path); + file.open(devname); + if (file) { + file.getline(model, sizeof(model)); + file.close(); + } + snprintf(devname, sizeof(devname), "%s/vendor_name", path); + file.open(devname); + if (file) { + file.getline(vendor, sizeof(vendor)); + file.close(); + } + if (strlen(model) && strlen(vendor)) + snprintf(humanname, sizeof(humanname), _("Audio codec %s: %s (%s)"), name, model, vendor); + else if (strlen(model)) + snprintf(humanname, sizeof(humanname), _("Audio codec %s: %s"), _name, model); + else if (strlen(vendor)) + snprintf(humanname, sizeof(humanname), _("Audio codec %s: %s"), _name, vendor); +} + +void alsa::start_measurement(void) +{ + char filename[PATH_MAX]; + ifstream file; + + snprintf(filename, sizeof(filename), "%s/power_off_acct", sysfs_path); + try { + file.open(filename, ios::in); + if (file) { + file >> start_inactive; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/power_on_acct", sysfs_path); + file.open(filename, ios::in); + + if (file) { + file >> start_active; + } + file.close(); + } + catch (std::ios_base::failure &c) { + fprintf(stderr, "%s\n", c.what()); + } +} + +void alsa::end_measurement(void) +{ + char filename[PATH_MAX]; + ifstream file; + double p; + + snprintf(filename, sizeof(filename), "%s/power_off_acct", sysfs_path); + try { + file.open(filename, ios::in); + if (file) { + file >> end_inactive; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/power_on_acct", sysfs_path); + file.open(filename, ios::in); + + if (file) { + file >> end_active; + } + file.close(); + } + catch (std::ios_base::failure &c) { + fprintf(stderr, "%s\n", c.what()); + } + + p = (end_active - start_active) / (0.001 + end_active + end_inactive - start_active - start_inactive) * 100.0; + report_utilization(name, p); +} + + +double alsa::utilization(void) +{ + double p; + + p = (end_active - start_active) / (0.001 + end_active - start_active + end_inactive - start_inactive) * 100.0; + + return p; +} + +const char * alsa::device_name(void) +{ + return name; +} + +static void create_all_alsa_callback(const char *d_name) +{ + char filename[PATH_MAX]; + class alsa *bl; + + if (strncmp(d_name, "hwC", 3) != 0) + return; + + snprintf(filename, sizeof(filename), "/sys/class/sound/%s/power_on_acct", d_name); + if (access(filename, R_OK) != 0) + return; + + snprintf(filename, sizeof(filename), "/sys/class/sound/%s", d_name); + bl = new class alsa(d_name, filename); + all_devices.push_back(bl); + register_parameter("alsa-codec-power", 0.5); +} + +void create_all_alsa(void) +{ + process_directory("/sys/class/sound/", create_all_alsa_callback); +} + +double alsa::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + static int index = 0; + + power = 0; + if (!index) + index = get_param_index("alsa-codec-power"); + + factor = get_parameter_value(index, bundle); + + util = get_result_value(rindex, result); + + power += util * factor / 100.0; + + return power; +} + +void alsa::register_power_with_devlist(struct result_bundle *results, struct parameter_bundle *bundle) +{ + register_devpower(&name[7], power_usage(results, bundle), this); +} + +const char * alsa::human_name(void) +{ + pt_strcpy(temp_buf, humanname); + if (strlen(guilty) > 0) + snprintf(temp_buf, sizeof(temp_buf), "%s (%s)", humanname, guilty); + return temp_buf; +} diff --git a/src/devices/alsa.h b/src/devices/alsa.h new file mode 100644 index 0000000..b68203f --- /dev/null +++ b/src/devices/alsa.h @@ -0,0 +1,67 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_ALSA_H +#define _INCLUDE_GUARD_ALSA_H + + +#include "device.h" +#include "../parameters/parameters.h" + +#include <stdint.h> +#include <limits.h> + +class alsa: public device { + uint64_t start_active, end_active; + uint64_t start_inactive, end_inactive; + char sysfs_path[PATH_MAX]; + char name[4096]; + char humanname[4096]; + char temp_buf[4096]; + int rindex; +public: + + alsa(const char *_name, const char *path); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "alsa";}; + + virtual const char * device_name(void); + virtual const char * human_name(void); + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual int power_valid(void) { return utilization_power_valid(rindex);}; + + virtual void register_power_with_devlist(struct result_bundle *results, struct parameter_bundle *bundle); + virtual int grouping_prio(void) { return 0; }; + +}; + +extern void create_all_alsa(void); + + +#endif diff --git a/src/devices/backlight.cpp b/src/devices/backlight.cpp new file mode 100644 index 0000000..c73e4c9 --- /dev/null +++ b/src/devices/backlight.cpp @@ -0,0 +1,225 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> + +#include <stdio.h> +#include <sys/types.h> +#include <dirent.h> +#include <limits.h> + + +using namespace std; + +#include "device.h" +#include "backlight.h" +#include "../parameters/parameters.h" + +#include <string.h> + + +backlight::backlight(const char *_name, const char *path): device() +{ + min_level = 0; + max_level = 0; + start_level = 0; + end_level = 0; + pt_strcpy(sysfs_path, path); + register_sysfs_path(sysfs_path); + snprintf(name, sizeof(name) - 1, "backlight:%s", _name); + r_index = get_result_index(name); + r_index_power = 0; +} + +void backlight::start_measurement(void) +{ + char filename[PATH_MAX]; + ifstream file; + + snprintf(filename, sizeof(filename), "%s/max_brightness", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> max_level; + } + file.close(); + + snprintf(filename, sizeof(filename), "%s/actual_brightness", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> start_level; + file.close(); + } +} + +static int dpms_screen_on(void) +{ + DIR *dir; + struct dirent *entry; + char filename[PATH_MAX]; + char line[4096]; + ifstream file; + + dir = opendir("/sys/class/drm/card0"); + if (!dir) + return 1; + while (1) { + entry = readdir(dir); + if (!entry) + break; + + if (strncmp(entry->d_name, "card", 4) != 0) + continue; + snprintf(filename, sizeof(filename), "/sys/class/drm/card0/%s/enabled", entry->d_name); + file.open(filename, ios::in); + if (!file) + continue; + file.getline(line, sizeof(line)); + file.close(); + if (strcmp(line, "enabled") != 0) + continue; + snprintf(filename, sizeof(filename), "/sys/class/drm/card0/%s/dpms", entry->d_name); + file.open(filename, ios::in); + if (!file) + continue; + file.getline(line, sizeof(line)); + file.close(); + if (strcmp(line, "On") == 0) { + closedir(dir); + return 1; + } + } + closedir(dir); + return 0; +} + +void backlight::end_measurement(void) +{ + char filename[PATH_MAX]; + char powername[4096]; + ifstream file; + double p; + int _backlight = 0; + + snprintf(filename, sizeof(filename), "%s/actual_brightness", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> end_level; + } + file.close(); + + if (dpms_screen_on()) { + p = 100.0 * (end_level + start_level) / 2 / max_level; + _backlight = 100; + } else { + p = 0; + } + + report_utilization(name, p); + snprintf(powername, sizeof(powername), "%s-power", name); + report_utilization(powername, _backlight); +} + + +double backlight::utilization(void) +{ + double p; + + p = 100.0 * (end_level + start_level) / 2 / max_level; + return p; +} + +const char * backlight::device_name(void) +{ + return name; +} + +static void create_all_backlights_callback(const char *d_name) +{ + class backlight *bl; + char filename[PATH_MAX]; + snprintf(filename, sizeof(filename), "/sys/class/backlight/%s", d_name); + bl = new class backlight(d_name, filename); + all_devices.push_back(bl); +} + +void create_all_backlights(void) +{ + process_directory("/sys/class/backlight/", create_all_backlights_callback); + register_parameter("backlight"); + register_parameter("backlight-power"); + register_parameter("backlight-boost-40", 0, 0.5); + register_parameter("backlight-boost-80", 0, 0.5); + register_parameter("backlight-boost-100", 0, 0.5); +} + +double backlight::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double _utilization; + char powername[4096]; + static int bl_index = 0, blp_index = 0, bl_boost_index40 = 0, bl_boost_index80, bl_boost_index100; + + if (!bl_index) + bl_index = get_param_index("backlight"); + if (!blp_index) + blp_index = get_param_index("backlight-power"); + if (!bl_boost_index40) + bl_boost_index40 = get_param_index("backlight-boost-40"); + if (!bl_boost_index80) + bl_boost_index80 = get_param_index("backlight-boost-80"); + if (!bl_boost_index100) + bl_boost_index100 = get_param_index("backlight-boost-100"); + + power = 0; + factor = get_parameter_value(bl_index, bundle); + _utilization = get_result_value(r_index, result); + + power += _utilization * factor / 100.0; + + /* + * most machines have a non-linear backlight scale. to compensate, add a fixed value + * once the brightness hits 40% and 80% + */ + + if (_utilization >=99) + power += get_parameter_value(bl_boost_index100, bundle); + else if (_utilization >=80) + power += get_parameter_value(bl_boost_index80, bundle); + else if (_utilization >=40) + power += get_parameter_value(bl_boost_index40, bundle); + + factor = get_parameter_value(blp_index, bundle); + + if (!r_index_power) { + sprintf(powername, "%s-power", name); + r_index_power = get_result_index(powername); + } + _utilization = get_result_value(r_index_power, result); + + power += _utilization * factor / 100.0; + + return power; +} diff --git a/src/devices/backlight.h b/src/devices/backlight.h new file mode 100644 index 0000000..1dac778 --- /dev/null +++ b/src/devices/backlight.h @@ -0,0 +1,59 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_BACKLIGHT_H +#define _INCLUDE_GUARD_BACKLIGHT_H + +#include <limits.h> + +#include "device.h" + +class backlight: public device { + int min_level, max_level; + int start_level, end_level; + char sysfs_path[PATH_MAX]; + char name[4096]; + int r_index; + int r_index_power; +public: + + backlight(const char *_name, const char *path); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "backlight";}; + + virtual const char * device_name(void); + virtual const char * human_name(void) { return "Display backlight";}; + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual int grouping_prio(void) { return 10; }; +}; + +extern void create_all_backlights(void); + + +#endif diff --git a/src/devices/devfreq.cpp b/src/devices/devfreq.cpp new file mode 100644 index 0000000..b194ac4 --- /dev/null +++ b/src/devices/devfreq.cpp @@ -0,0 +1,334 @@ +/* + * Copyright 2012, Linaro + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Rajagopal Venkat <rajagopal.venkat@linaro.org> + */ + +#include <iostream> +#include <fstream> + +#include <dirent.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +#include "device.h" +#include "devfreq.h" +#include "../display.h" +#include "../cpu/cpu.h" +#include "../report/report.h" +#include "../report/report-maker.h" + +static bool is_enabled = true; +static DIR *dir = NULL; + +static vector<class devfreq *> all_devfreq; + +devfreq::devfreq(const char* dpath): device() +{ + pt_strcpy(dir_name, dpath); +} + +uint64_t devfreq::parse_freq_time(char* pchr) +{ + char *cptr, *pptr = pchr; + uint64_t ctime; + + cptr = strtok(pchr, " :"); + while (cptr != NULL) { + cptr = strtok(NULL, " :"); + if (cptr ) + pptr = cptr; + } + + ctime = strtoull(pptr, NULL, 10); + return ctime; +} + +void devfreq::process_time_stamps() +{ + unsigned int i; + uint64_t active_time = 0; + + sample_time = (1000000.0 * (stamp_after.tv_sec - stamp_before.tv_sec)) + + ((stamp_after.tv_usec - stamp_before.tv_usec) ); + + for (i=0; i < dstates.size()-1; i++) { + struct frequency *state = dstates[i]; + state->time_after = 1000 * (state->time_after - state->time_before); + active_time += state->time_after; + } + /* Compute idle time for the device */ + dstates[i]->time_after = sample_time - active_time; +} + +void devfreq::add_devfreq_freq_state(uint64_t freq, uint64_t time) +{ + struct frequency *state; + + state = new(std::nothrow) struct frequency; + if (!state) + return; + + memset(state, 0, sizeof(*state)); + dstates.push_back(state); + + state->freq = freq; + if (freq == 0) + strcpy(state->human_name, "Idle"); + else + hz_to_human(freq, state->human_name); + state->time_before = time; +} + +void devfreq::update_devfreq_freq_state(uint64_t freq, uint64_t time) +{ + unsigned int i; + struct frequency *state = NULL; + + for(i=0; i < dstates.size(); i++) { + if (freq == dstates[i]->freq) + state = dstates[i]; + } + + if (state == NULL) { + add_devfreq_freq_state(freq, time); + return; + } + + state->time_after = time; +} + +void devfreq::parse_devfreq_trans_stat(char *dname) +{ + ifstream file; + char filename[256]; + + snprintf(filename, sizeof(filename), "/sys/class/devfreq/%s/trans_stat", dir_name); + file.open(filename); + + if (!file) + return; + + char line[1024]; + char *c; + + while (file) { + uint64_t freq; + uint64_t time; + char *pchr; + + memset(line, 0, sizeof(line)); + file.getline(line, sizeof(line)); + + pchr = strchr(line, '*'); + pchr = (pchr != NULL) ? pchr+1 : line; + + freq = strtoull(pchr, &c, 10); + if (!freq) + continue; + + time = parse_freq_time(pchr); + update_devfreq_freq_state(freq, time); + } + file.close(); +} + +void devfreq::start_measurement(void) +{ + unsigned int i; + + for (i=0; i < dstates.size(); i++) + delete dstates[i]; + dstates.resize(0); + sample_time = 0; + + gettimeofday(&stamp_before, NULL); + parse_devfreq_trans_stat(dir_name); + /* add device idle state */ + update_devfreq_freq_state(0, 0); +} + +void devfreq::end_measurement(void) +{ + parse_devfreq_trans_stat(dir_name); + gettimeofday(&stamp_after, NULL); + process_time_stamps(); +} + +double devfreq::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + return 0; +} + +double devfreq::utilization(void) +{ + return 0; +} + +void devfreq::fill_freq_utilization(unsigned int idx, char *buf) +{ + buf[0] = 0; + + if (idx < dstates.size() && dstates[idx]) { + struct frequency *state = dstates[idx]; + sprintf(buf, " %5.1f%% ", percentage(1.0 * state->time_after / sample_time)); + } +} + +void devfreq::fill_freq_name(unsigned int idx, char *buf) +{ + buf[0] = 0; + + if (idx < dstates.size() && dstates[idx]) { + sprintf(buf, "%-15s", dstates[idx]->human_name); + } +} + +void start_devfreq_measurement(void) +{ + unsigned int i; + + for (i=0; i<all_devfreq.size(); i++) + all_devfreq[i]->start_measurement(); +} + +void end_devfreq_measurement(void) +{ + unsigned int i; + + for (i=0; i<all_devfreq.size(); i++) + all_devfreq[i]->end_measurement(); +} + +static void devfreq_dev_callback(const char *d_name) +{ + devfreq *df = new(std::nothrow) class devfreq(d_name); + if (df) + all_devfreq.push_back(df); +} + +void create_all_devfreq_devices(void) +{ + int num = 0; + + std::string p = "/sys/class/devfreq/"; + dir = opendir(p.c_str()); + if (dir == NULL) { + fprintf(stderr, "Devfreq not enabled\n"); + is_enabled = false; + return; + } + + while(readdir(dir) != NULL) + num++; + + if (num == 2) { + fprintf(stderr, "Devfreq not enabled\n"); + is_enabled = false; + closedir(dir); + dir = NULL; + return; + } + + callback fn = &devfreq_dev_callback; + process_directory(p.c_str(), fn); +} + +void initialize_devfreq(void) +{ + if (is_enabled) + create_tab("Device Freq stats", _("Device Freq stats")); +} + +void display_devfreq_devices(void) +{ + unsigned int i, j; + WINDOW *win; + char fline[1024]; + char buf[128]; + + win = get_ncurses_win("Device Freq stats"); + if (!win) + return; + + wclear(win); + wmove(win, 2,0); + + if (!is_enabled) { + wprintw(win, _(" Devfreq is not enabled")); + return; + } + + if (!all_devfreq.size()) { + wprintw(win, _(" No devfreq devices available")); + return; + } + + for (i=0; i<all_devfreq.size(); i++) { + + class devfreq *df = all_devfreq[i]; + wprintw(win, "\n%s\n", df->device_name()); + + for(j=0; j < df->dstates.size(); j++) { + memset(fline, 0, sizeof(fline)); + strcpy(fline, "\t"); + df->fill_freq_name(j, buf); + strcat(fline, buf); + df->fill_freq_utilization(j, buf); + strcat(fline, buf); + strcat(fline, "\n"); + wprintw(win, "%s", fline); + } + wprintw(win, "\n"); + } +} + +void report_devfreq_devices(void) +{ + if (!is_enabled) { + return; + } + +/* todo: adapt to new report format */ + +} + +void clear_all_devfreq() +{ + unsigned int i, j; + + for (i=0; i < all_devfreq.size(); i++) { + class devfreq *df = all_devfreq[i]; + + for(j=0; j < df->dstates.size(); j++) + delete df->dstates[j]; + + delete df; + } + all_devfreq.clear(); + /* close /sys/class/devfreq */ + if (dir != NULL) { + closedir(dir); + dir = NULL; + } +} diff --git a/src/devices/devfreq.h b/src/devices/devfreq.h new file mode 100644 index 0000000..4a8983b --- /dev/null +++ b/src/devices/devfreq.h @@ -0,0 +1,76 @@ +/* + * Copyright 2012, Linaro + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Rajagopal Venkat <rajagopal.venkat@linaro.org> + */ +#ifndef _INCLUDE_GUARD_DEVFREQ_H +#define _INCLUDE_GUARD_DEVFREQ_H + +#include "device.h" +#include "../parameters/parameters.h" +#include <sys/time.h> + +struct frequency; + +class devfreq: public device { + char dir_name[128]; + struct timeval stamp_before, stamp_after; + double sample_time; + + uint64_t parse_freq_time(char *ptr); + void add_devfreq_freq_state(uint64_t freq, uint64_t time); + void update_devfreq_freq_state(uint64_t freq, uint64_t time); + void parse_devfreq_trans_stat(char *dname); + void process_time_stamps(); + +public: + + vector<struct frequency *> dstates; + + devfreq(const char *c); + void fill_freq_utilization(unsigned int idx, char *buf); + void fill_freq_name(unsigned int idx, char *buf); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "devfreq";}; + + virtual const char * device_name(void) { return dir_name;}; + virtual const char * human_name(void) { return "devfreq";}; + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual const char * util_units(void) { return " rpm"; }; + virtual int power_valid(void) { return 0; /*utilization_power_valid(r_index);*/}; + virtual int grouping_prio(void) { return 1; }; +}; + +extern void create_all_devfreq_devices(void); +extern void clear_all_devfreq(void); +extern void display_devfreq_devices(void); +extern void report_devfreq_devices(void); +extern void initialize_devfreq(void); +extern void start_devfreq_measurement(void); +extern void end_devfreq_measurement(void); + +#endif diff --git a/src/devices/device.cpp b/src/devices/device.cpp new file mode 100644 index 0000000..f191072 --- /dev/null +++ b/src/devices/device.cpp @@ -0,0 +1,345 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "device.h" +#include <vector> +#include <algorithm> +#include <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <unistd.h> + +using namespace std; + +#include "backlight.h" +#include "usb.h" +#include "ahci.h" +#include "alsa.h" +#include "rfkill.h" +#include "i915-gpu.h" +#include "thinkpad-fan.h" +#include "thinkpad-light.h" +#include "network.h" +#include "runtime_pm.h" + +#include "../parameters/parameters.h" +#include "../display.h" +#include "../lib.h" +#include "../report/report.h" +#include "../report/report-maker.h" +#include "../report/report-data-html.h" +#include "../measurement/measurement.h" +#include "../devlist.h" +#include <unistd.h> + +device::device(void) +{ + cached_valid = 0; + hide = 0; + + memset(guilty, 0, sizeof(guilty)); + memset(real_path, 0, sizeof(real_path)); +} + + +void device::register_sysfs_path(const char *path) +{ + char current_path[PATH_MAX + 1]; + int iter = 0; + pt_strcpy(current_path, path); + + while (iter++ < 10) { + char test_path[PATH_MAX + 1]; + snprintf(test_path, sizeof(test_path), "%s/device", current_path); + if (access(test_path, R_OK) == 0) + strcpy(current_path, test_path); + else + break; + } + + if (!realpath(current_path, real_path)) + real_path[0] = 0; +} + +void device::start_measurement(void) +{ + hide = false; +} + +void device::end_measurement(void) +{ +} + +double device::utilization(void) +{ + return 0.0; +} + + + +vector<class device *> all_devices; + + +void devices_start_measurement(void) +{ + unsigned int i; + for (i = 0; i < all_devices.size(); i++) + all_devices[i]->start_measurement(); +} + +void devices_end_measurement(void) +{ + unsigned int i; + for (i = 0; i < all_devices.size(); i++) + all_devices[i]->end_measurement(); + + clear_devpower(); + + for (i = 0; i < all_devices.size(); i++) { + all_devices[i]->hide = false; + all_devices[i]->register_power_with_devlist(&all_results, &all_parameters); + } +} + +static bool power_device_sort(class device * i, class device * j) +{ + double pI, pJ; + pI = i->power_usage(&all_results, &all_parameters); + pJ = j->power_usage(&all_results, &all_parameters); + + if (equals(pI, pJ)) { + int vI, vJ; + vI = i->power_valid(); + vJ = j->power_valid(); + + if (vI != vJ) + return vI > vJ; + + return i->utilization() > j->utilization(); + } + return pI > pJ; +} + + +void report_devices(void) +{ + WINDOW *win; + unsigned int i; + int show_power; + double pw; + + char util[128]; + char power[128]; + + win = get_ncurses_win("Device stats"); + if (!win) + return; + + show_power = global_power_valid(); + + wclear(win); + wmove(win, 2,0); + + sort(all_devices.begin(), all_devices.end(), power_device_sort); + + + + pw = global_power(); + if (pw > 0.0001) { + char buf[32]; + wprintw(win, _("The battery reports a discharge rate of %sW\n"), + fmt_prefix(pw, buf)); + wprintw(win, _("The energy consumed was %sJ\n"), + fmt_prefix(global_joules(), buf)); + } + + if (show_power) { + char buf[32]; + wprintw(win, _("System baseline power is estimated at %sW\n"), + fmt_prefix(get_parameter_value("base power"), buf)); + } + + if (pw > 0.0001 || show_power) + wprintw(win, "\n"); + if (show_power) + wprintw(win, _("Power est. Usage Device name\n")); + else + wprintw(win, _(" Usage Device name\n")); + + for (i = 0; i < all_devices.size(); i++) { + double P; + + util[0] = 0; + + if (all_devices[i]->util_units()) { + if (all_devices[i]->utilization() < 1000) + sprintf(util, "%5.1f%s", all_devices[i]->utilization(), all_devices[i]->util_units()); + else + sprintf(util, "%5i%s", (int)all_devices[i]->utilization(), all_devices[i]->util_units()); + } + while (strlen(util) < 13) strcat(util, " "); + + P = all_devices[i]->power_usage(&all_results, &all_parameters); + + format_watts(P, power, 11); + + if (!show_power || !all_devices[i]->power_valid()) + strcpy(power, " "); + + + wprintw(win, "%s %s %s\n", + power, + util, + all_devices[i]->human_name() + ); + } +} + +void show_report_devices(void) +{ + unsigned int i; + int show_power, cols, rows, idx; + double pw; + + show_power = global_power_valid(); + sort(all_devices.begin(), all_devices.end(), power_device_sort); + + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "clear_block", "devinfo"); + + /* Set Table attributes, rows, and cols */ + table_attributes std_table_css; + cols=2; + if (show_power) + cols=3; + + idx = cols; + rows= all_devices.size() + 1; + init_std_side_table_attr(&std_table_css, rows, cols); + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Add section */ + report.add_div(&div_attr); + + /* Device Summary */ + int summary_size=2; + string *summary = new string[summary_size]; + pw = global_power(); + char buf[32]; + if (pw > 0.0001) { + summary[0]= __("The battery reports a discharge rate of: "); + summary[1]=string(fmt_prefix(pw, buf)); + summary[1].append(" W"); + report.add_summary_list(summary, summary_size); + + summary[0]= __("The energy consumed was : "); + summary[1]=string(fmt_prefix(global_joules(), buf)); + summary[1].append(" J"); + report.add_summary_list(summary, summary_size); + } + + if (show_power) { + summary[0]=__("The system baseline power is estimated at: "); + summary[1]=string(fmt_prefix(get_parameter_value("base power"), buf)); + summary[1].append(" W"); + report.add_summary_list(summary, summary_size); + } + delete [] summary; + + /* Set array of data in row Major order */ + string *device_data = new string[cols * rows]; + device_data[0]= __("Usage"); + device_data[1]= __("Device Name"); + if (show_power) + device_data[2]= __("PW Estimate"); + + for (i = 0; i < all_devices.size(); i++) { + double P; + char util[128]; + char power[128]; + + util[0] = 0; + if (all_devices[i]->util_units()) { + if (all_devices[i]->utilization() < 1000) + sprintf(util, "%5.1f%s", + all_devices[i]->utilization(), + all_devices[i]->util_units()); + else + sprintf(util, "%5i%s", + (int)all_devices[i]->utilization(), + all_devices[i]->util_units()); + } + + P = all_devices[i]->power_usage(&all_results, &all_parameters); + format_watts(P, power, 11); + + if (!show_power || !all_devices[i]->power_valid()) + strcpy(power, " "); + + device_data[idx]= string(util); + idx+=1; + + device_data[idx]= string(all_devices[i]->human_name()); + idx+=1; + + if (show_power) { + device_data[idx]= string(power); + idx+=1; + } + } + /* Report Output */ + report.add_title(&title_attr, __("Device Power Report")); + report.add_table(device_data, &std_table_css); + delete [] device_data; +} + + +void create_all_devices(void) +{ + create_all_backlights(); + create_all_usb_devices(); + create_all_ahcis(); + create_all_alsa(); + create_all_rfkills(); + create_i915_gpu(); + create_thinkpad_fan(); + create_thinkpad_light(); + create_all_nics(); + create_all_runtime_pm_devices(); +} + + +void clear_all_devices(void) +{ + unsigned int i; + for (i = 0; i < all_devices.size(); i++) { + delete all_devices[i]; + } + all_devices.clear(); +} diff --git a/src/devices/device.h b/src/devices/device.h new file mode 100644 index 0000000..a373875 --- /dev/null +++ b/src/devices/device.h @@ -0,0 +1,85 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_DEVICE_H +#define _INCLUDE_GUARD_DEVICE_H + + +#include <vector> +#include <limits.h> + +struct parameter_bundle; +struct result_bundle; + +class device { +public: + int cached_valid; + bool hide; + + char guilty[4096]; + char real_path[PATH_MAX+1]; + + virtual void start_measurement(void); + virtual void end_measurement(void); + + device(void); + + virtual ~device() {}; + + void register_sysfs_path(const char *path); + + virtual double utilization(void); /* percentage */ + + virtual const char * util_units(void) { return "%"; }; + + virtual const char * class_name(void) { return "abstract device";}; + virtual const char * device_name(void) { return "abstract device";}; + + virtual const char * human_name(void) { return device_name(); }; + + virtual double power_usage(struct result_bundle *results, struct parameter_bundle *bundle) { return 0.0; }; + + virtual bool show_in_list(void) {return !hide;}; + + virtual int power_valid(void) { return 1;}; + + virtual void register_power_with_devlist(struct result_bundle *results, struct parameter_bundle *bundle) { ; }; + + virtual int grouping_prio(void) { return 0; }; /* priority of this device class if multiple classes match to the same underlying device. 0 is lowest */ +}; + +using namespace std; + +extern vector<class device *> all_devices; + +extern void devices_start_measurement(void); +extern void devices_end_measurement(void); +extern void show_report_devices(void); +extern void report_devices(void); + + +extern void create_all_devices(void); +extern void clear_all_devices(void); + +#endif diff --git a/src/devices/gpu_rapl_device.cpp b/src/devices/gpu_rapl_device.cpp new file mode 100644 index 0000000..71d71a0 --- /dev/null +++ b/src/devices/gpu_rapl_device.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Srinivas Pandruvada<Srinivas.Pandruvada@linux.intel.com> + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "../parameters/parameters.h" +#include "gpu_rapl_device.h" + +gpu_rapl_device::gpu_rapl_device(i915gpu *parent) + : i915gpu(), + device_valid(false) +{ + last_time = time(NULL); + if (rapl.pp1_domain_present()) { + device_valid = true; + parent->add_child(this); + rapl.get_pp1_energy_status(&last_energy); + } +} + +void gpu_rapl_device::start_measurement(void) +{ + last_time = time(NULL); + + rapl.get_pp1_energy_status(&last_energy); +} + +void gpu_rapl_device::end_measurement(void) +{ + time_t curr_time = time(NULL); + double energy; + + consumed_power = 0.0; + if ((curr_time - last_time) > 0) { + rapl.get_pp1_energy_status(&energy); + consumed_power = (energy-last_energy)/(curr_time-last_time); + last_energy = energy; + last_time = curr_time; + } +} + +double gpu_rapl_device::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + if (rapl.pp1_domain_present()) + return consumed_power; + else + return 0.0; +} diff --git a/src/devices/gpu_rapl_device.h b/src/devices/gpu_rapl_device.h new file mode 100644 index 0000000..fbde246 --- /dev/null +++ b/src/devices/gpu_rapl_device.h @@ -0,0 +1,57 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Srinivas Pandruvada <Srinivas.Pandruvada@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_GPU_RAPL_DEVICE_H +#define _INCLUDE_GUARD_GPU_RAPL_DEVICE_H + +#include <vector> +#include <string> + +using namespace std; + +#include <sys/time.h> +#include "i915-gpu.h" +#include "cpu/rapl/rapl_interface.h" + +class gpu_rapl_device: public i915gpu { + + c_rapl_interface rapl; + time_t last_time; + double last_energy; + double consumed_power; + bool device_valid; + +public: + gpu_rapl_device(i915gpu *parent); + virtual const char * class_name(void) { return "GPU core";}; + virtual const char * device_name(void) { return "GPU core";}; + bool device_present() { return device_valid;} + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual void start_measurement(void); + virtual void end_measurement(void); + +}; + + +#endif diff --git a/src/devices/i915-gpu.cpp b/src/devices/i915-gpu.cpp new file mode 100644 index 0000000..d0f1d69 --- /dev/null +++ b/src/devices/i915-gpu.cpp @@ -0,0 +1,121 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> + +#include <stdio.h> +#include <sys/types.h> +#include <dirent.h> +#include <unistd.h> +#include <limits.h> +#include "../lib.h" + +using namespace std; + +#include "device.h" +#include "i915-gpu.h" +#include "../parameters/parameters.h" +#include "../process/powerconsumer.h" +#include "gpu_rapl_device.h" + +#include <string.h> +#include <unistd.h> + +i915gpu::i915gpu(): device() +{ + index = get_param_index("gpu-operations"); + rindex = get_result_index("gpu-operations"); +} + +const char * i915gpu::device_name(void) +{ + if (child_devices.size()) + return "GPU misc"; + else + return "GPU"; +} + +void i915gpu::start_measurement(void) +{ +} + +void i915gpu::end_measurement(void) +{ +} + + +double i915gpu::utilization(void) +{ + return get_result_value(rindex); + +} + +void create_i915_gpu(void) +{ + char filename[PATH_MAX]; + class i915gpu *gpu; + gpu_rapl_device *rapl_dev; + + pt_strcpy(filename, "/sys/kernel/debug/tracing/events/i915/i915_gem_ring_dispatch/format"); + + if (access(filename, R_OK) !=0) { + /* try an older tracepoint */ + pt_strcpy(filename, "/sys/kernel/debug/tracing/events/i915/i915_gem_request_submit/format"); + if (access(filename, R_OK) != 0) + return; + } + + register_parameter("gpu-operations"); + + gpu = new class i915gpu(); + all_devices.push_back(gpu); + + rapl_dev = new class gpu_rapl_device(gpu); + if (rapl_dev->device_present()) + all_devices.push_back(rapl_dev); +} + + + +double i915gpu::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + double child_power; + + power = 0; + factor = get_parameter_value(index, bundle); + util = get_result_value(rindex, result); + + power += util * factor / 100.0; + for (unsigned int i = 0; i < child_devices.size(); ++i) { + child_power = child_devices[i]->power_usage(result, bundle); + if ((power - child_power) > 0.0) + power -= child_power; + } + + return power; +} diff --git a/src/devices/i915-gpu.h b/src/devices/i915-gpu.h new file mode 100644 index 0000000..7653b94 --- /dev/null +++ b/src/devices/i915-gpu.h @@ -0,0 +1,58 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_i915_GPU_H +#define _INCLUDE_GUARD_i915_GPU_H + + +#include "device.h" + +class i915gpu: public device { + int index; + int rindex; + vector<device *>child_devices; + +public: + + i915gpu(); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "GPU";}; + + virtual const char * device_name(void); + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual bool show_in_list(void) {return false;}; + virtual const char * util_units(void) { return " ops/s"; }; + + virtual void add_child(device *dev_ptr) { child_devices.push_back(dev_ptr);} +}; + +extern void create_i915_gpu(void); + + +#endif
\ No newline at end of file diff --git a/src/devices/network.cpp b/src/devices/network.cpp new file mode 100644 index 0000000..8087b7f --- /dev/null +++ b/src/devices/network.cpp @@ -0,0 +1,441 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> +#include <vector> +#include <string> +#include <map> + +#include <stdio.h> +#include <sys/types.h> +#include <libgen.h> +#include <stdlib.h> +#include <unistd.h> + +#include <linux/ethtool.h> + +using namespace std; + +#include "device.h" +#include "network.h" +#include "../lib.h" +#include "../parameters/parameters.h" +#include "../process/process.h" +extern "C" { +#include "../tuning/iw.h" +} + +#include <string.h> +#include <net/if.h> +#include <linux/sockios.h> +#include <sys/ioctl.h> +#include <unistd.h> + +static map<string, class network *> nics; + +#ifdef DISABLE_TRYCATCH + +static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, + __u32 speed) +{ + + ep->speed = (__u16)speed; + ep->speed_hi = (__u16)(speed >> 16); +} + +static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) +{ + return (ep->speed_hi << 16) | ep->speed; +} + +#endif + +static void do_proc_net_dev(void) +{ + static time_t last_time; + class network *dev; + ifstream file; + char line[4096]; + char *c, *c2; + + if (time(NULL) == last_time) + return; + + last_time = time(NULL); + + file.open("/proc/net/dev", ios::in); + if (!file) + return; + + file.getline(line, 4096); + file.getline(line, 4096); + + while (file) { + int i = 0; + unsigned long val = 0; + uint64_t pkt = 0; + file.getline(line, 4096); + c = strchr(line, ':'); + if (!c) + continue; + *c = 0; + c2 = c +1; + c = line; while (c && *c == ' ') c++; + /* c now points to the name of the nic */ + + dev = nics[c]; + if (!dev) + continue; + + c = c2++; + while (c != c2 && strlen(c) > 0) { + c2 = c; + val = strtoull(c, &c, 10); + i++; + if (i == 2 || i == 10) + pkt += val; + + } + dev->pkts = pkt; + } + file.close(); +} + + +network::network(const char *_name, const char *path): device() +{ + char line[4096]; + std::string filename(path); + char devname[128]; + start_up = 0; + end_up = 0; + start_speed = 0; + end_speed = 0; + start_pkts = 0; + end_pkts = 0; + pkts = 0; + valid_100 = -1; + valid_1000 = -1; + valid_high = -1; + valid_powerunsave = -1; + + pt_strcpy(sysfs_path, path); + register_sysfs_path(sysfs_path); + pt_strcpy(devname, _name); + sprintf(humanname, "nic:%s", _name); + pt_strcpy(name, devname); + + snprintf(devname, sizeof(devname), "%s-up", _name); + index_up = get_param_index(devname); + rindex_up = get_result_index(devname); + + snprintf(devname, sizeof(devname), "%s-powerunsave", _name); + index_powerunsave = get_param_index(devname); + rindex_powerunsave = get_result_index(devname); + + snprintf(devname, sizeof(devname), "%s-link-100", _name); + index_link_100 = get_param_index(devname); + rindex_link_100 = get_result_index(devname); + + snprintf(devname, sizeof(devname), "%s-link-1000", _name); + index_link_1000 = get_param_index(devname); + rindex_link_1000 = get_result_index(devname); + + snprintf(devname, sizeof(devname), "%s-link-high", _name); + index_link_high = get_param_index(devname); + rindex_link_high = get_result_index(devname); + + snprintf(devname, sizeof(devname), "%s-packets", _name); + index_pkts = get_param_index(devname); + rindex_pkts = get_result_index(devname); + + memset(line, 0, 4096); + filename.append("/device/driver"); + if (readlink(filename.c_str(), line, 4096) > 0) { + snprintf(humanname, sizeof(humanname), _("Network interface: %s (%s)"), _name, basename(line)); + }; +} + +static int net_iface_up(const char *iface) +{ + int sock; + struct ifreq ifr; + int ret; + + memset(&ifr, 0, sizeof(struct ifreq)); + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock<0) + return 0; + + pt_strcpy(ifr.ifr_name, iface); + + /* Check if the interface is up */ + ret = ioctl(sock, SIOCGIFFLAGS, &ifr); + if (ret<0) { + close(sock); + return 0; + } + + if (ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) { + close(sock); + return 1; + } + + close(sock); + + return 0; +} + +static int iface_link(const char *name) +{ + int sock; + struct ifreq ifr; + struct ethtool_value cmd; + int link; + + memset(&ifr, 0, sizeof(struct ifreq)); + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock<0) + return 0; + + pt_strcpy(ifr.ifr_name, name); + + memset(&cmd, 0, sizeof(cmd)); + + cmd.cmd = ETHTOOL_GLINK; + ifr.ifr_data = (caddr_t)&cmd; + ioctl(sock, SIOCETHTOOL, &ifr); + close(sock); + + link = cmd.data; + + return link; +} + + +static int iface_speed(const char *name) +{ + int sock; + struct ifreq ifr; + struct ethtool_cmd cmd; + int speed; + + memset(&ifr, 0, sizeof(struct ifreq)); + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock<0) + return 0; + + pt_strcpy(ifr.ifr_name, name); + + memset(&cmd, 0, sizeof(cmd)); + + cmd.cmd = ETHTOOL_GSET; + ifr.ifr_data = (caddr_t)&cmd; + ioctl(sock, SIOCETHTOOL, &ifr); + close(sock); + + speed = ethtool_cmd_speed(&cmd); + + + if (speed > 0 && speed <= 100) + speed = 100; + if (speed > 100 && speed <= 1000) + speed = 1000; + if (speed == 65535 || !iface_link(name)) + speed = 0; /* no link */ + + return speed; +} + +void network::start_measurement(void) +{ + start_up = 1; + start_speed = 0; + end_up = 1; + end_speed = 0; + + start_speed = iface_speed(name); + + start_up = net_iface_up(name); + + do_proc_net_dev(); + start_pkts = pkts; + + gettimeofday(&before, NULL); +} + + +void network::end_measurement(void) +{ + int u_100, u_1000, u_high, u_powerunsave; + + gettimeofday(&after, NULL); + + end_speed = iface_speed(name); + end_up = net_iface_up(name); + do_proc_net_dev(); + end_pkts = pkts; + + duration = (after.tv_sec - before.tv_sec) + (after.tv_usec - before.tv_usec) / 1000000.0; + + u_100 = 0; + u_1000 = 0; + u_high = 0; + + if (start_speed == 100) + u_100 += 50; + if (start_speed == 1000) + u_1000 += 50; + if (start_speed > 1000) + u_high += 50; + if (end_speed == 100) + u_100 += 50; + if (end_speed == 1000) + u_1000 += 50; + if (end_speed > 1000) + u_high += 50; + + if (start_pkts > end_pkts) + end_pkts = start_pkts; + + u_powerunsave = 100 - 100 * get_wifi_power_saving(name); + + report_utilization(rindex_link_100, u_100); + report_utilization(rindex_link_1000, u_1000); + report_utilization(rindex_link_high, u_high); + report_utilization(rindex_up, (start_up+end_up) / 2.0); + report_utilization(rindex_pkts, (end_pkts - start_pkts)/(duration + 0.001)); + report_utilization(rindex_powerunsave, u_powerunsave); +} + + +double network::utilization(void) +{ + return (end_pkts - start_pkts) / (duration + 0.001); +} + +const char * network::device_name(void) +{ + return name; +} + +static void netdev_callback(const char *d_name) +{ + char devname[128]; + + std::string f_name("/sys/class/net/"); + if (strcmp(d_name, "lo") == 0) + return; + + f_name.append(d_name); + + snprintf(devname, sizeof(devname), "%s-up", d_name); + register_parameter(devname); + + snprintf(devname, sizeof(devname), "%s-powerunsave", d_name); + register_parameter(devname); + + snprintf(devname, sizeof(devname), "%s-link-100", d_name); + register_parameter(devname); + + snprintf(devname, sizeof(devname), "%s-link-1000", d_name); + register_parameter(devname); + + snprintf(devname, sizeof(devname), "%s-link-high", d_name); + register_parameter(devname); + + snprintf(devname, sizeof(devname), "%s-packets", d_name); + register_parameter(devname); + + network *bl = new(std::nothrow) class network(d_name, f_name.c_str()); + if (bl) { + all_devices.push_back(bl); + nics[d_name] = bl; + } +} + +void create_all_nics(callback fn) +{ + if (!fn) + fn = &netdev_callback; + process_directory("/sys/class/net/", fn); +} + +double network::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + + power = 0; + factor = get_parameter_value(index_up, bundle); + util = get_result_value(rindex_up, result); + + power += util * factor; + + if (valid_100 == -1) { + valid_100 = utilization_power_valid(rindex_link_100); + valid_1000 = utilization_power_valid(rindex_link_1000); + valid_high = utilization_power_valid(rindex_link_high); + valid_powerunsave = utilization_power_valid(rindex_powerunsave); + } + + if (valid_100 > 0) { + factor = get_parameter_value(index_link_100, bundle); + util = get_result_value(rindex_link_100, result); + power += util * factor / 100; + } + + + if (valid_1000 > 0) { + factor = get_parameter_value(index_link_1000, bundle); + util = get_result_value(rindex_link_1000, result); + power += util * factor / 100; + } + + if (valid_high > 0) { + factor = get_parameter_value(index_link_high, bundle); + util = get_result_value(rindex_link_high, result); + power += util * factor / 100; + } + + if (valid_powerunsave > 0) { + factor = get_parameter_value(index_powerunsave, bundle); + util = get_result_value(rindex_powerunsave, result); + power += util * factor / 100; + } + + factor = get_parameter_value(index_pkts, bundle); + util = get_result_value(rindex_pkts, result); + if (util > 5000) + util = 5000; + + power += util * factor / 100; + + return power; +} diff --git a/src/devices/network.h b/src/devices/network.h new file mode 100644 index 0000000..7fb4cc6 --- /dev/null +++ b/src/devices/network.h @@ -0,0 +1,85 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_NETWORK_H +#define _INCLUDE_GUARD_NETWORK_H + +#include <sys/time.h> +#include <limits.h> + +#include "device.h" +#include "../parameters/parameters.h" + +class network: public device { + int start_up, end_up; + uint64_t start_pkts, end_pkts; + struct timeval before, after; + + int start_speed; /* 0 is "no link" */ + int end_speed; /* 0 is "no link" */ + + char sysfs_path[PATH_MAX]; + char name[4096]; + char humanname[4096]; + int index_up; + int rindex_up; + int index_link_100; + int rindex_link_100; + int index_link_1000; + int rindex_link_1000; + int index_link_high; + int rindex_link_high; + int index_pkts; + int rindex_pkts; + int index_powerunsave; + int rindex_powerunsave; + + int valid_100; + int valid_1000; + int valid_high; + int valid_powerunsave; +public: + uint64_t pkts; + double duration; + + network(const char *_name, const char *path); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); + virtual const char * util_units(void) { return " pkts/s"; }; + + virtual const char * class_name(void) { return "ethernet";}; + + virtual const char * device_name(void); + virtual const char * human_name(void) { return humanname; }; + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual int power_valid(void) { return utilization_power_valid(rindex_up) + utilization_power_valid(rindex_link_100) + utilization_power_valid(rindex_link_1000) + utilization_power_valid(rindex_link_high);}; + virtual int grouping_prio(void) { return 10; }; +}; + +extern void create_all_nics(callback fn = NULL); + +#endif diff --git a/src/devices/rfkill.cpp b/src/devices/rfkill.cpp new file mode 100644 index 0000000..99a652f --- /dev/null +++ b/src/devices/rfkill.cpp @@ -0,0 +1,177 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> + +#include <stdio.h> +#include <sys/types.h> +#include <libgen.h> +#include <unistd.h> +#include <limits.h> + + +using namespace std; + +#include "device.h" +#include "rfkill.h" +#include "../parameters/parameters.h" + +#include <string.h> +#include <unistd.h> + +rfkill::rfkill(char *_name, char *path): device() +{ + char line[4096]; + char filename[PATH_MAX]; + char devname[128]; + start_soft = 0; + start_hard = 0; + end_soft = 0; + end_hard = 0; + pt_strcpy(sysfs_path, path); + register_sysfs_path(sysfs_path); + snprintf(devname, sizeof(devname), "radio:%s", _name); + snprintf(humanname, sizeof(humanname), "radio:%s", _name); + pt_strcpy(name, devname); + register_parameter(devname); + index = get_param_index(devname); + rindex = get_result_index(name); + + memset(line, 0, 4096); + snprintf(filename, sizeof(filename), "%s/device/driver", path); + if (readlink(filename, line, sizeof(line)) > 0) { + snprintf(humanname, sizeof(humanname), _("Radio device: %s"), basename(line)); + } + snprintf(filename, sizeof(filename), "%s/device/device/driver", path); + if (readlink(filename, line, sizeof(line)) > 0) { + snprintf(humanname, sizeof(humanname), _("Radio device: %s"), basename(line)); + } +} + +void rfkill::start_measurement(void) +{ + char filename[PATH_MAX]; + ifstream file; + + start_hard = 1; + start_soft = 1; + end_hard = 1; + end_soft = 1; + + snprintf(filename, sizeof(filename), "%s/hard", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> start_hard; + } + file.close(); + + snprintf(filename, sizeof(filename), "%s/soft", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> start_soft; + } + file.close(); +} + +void rfkill::end_measurement(void) +{ + char filename[PATH_MAX]; + ifstream file; + + snprintf(filename, sizeof(filename), "%s/hard", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> end_hard; + } + file.close(); + snprintf(filename, sizeof(filename), "%s/soft", sysfs_path); + file.open(filename, ios::in); + if (file) { + file >> end_soft; + } + file.close(); + + report_utilization(name, utilization()); +} + + +double rfkill::utilization(void) +{ + double p; + int rfk; + + rfk = start_soft+end_soft; + if (rfk < start_hard+end_hard) + rfk = start_hard+end_hard; + + p = 100 - 50.0 * rfk; + + return p; +} + +const char * rfkill::device_name(void) +{ + return name; +} + +static void create_all_rfkills_callback(const char *d_name) +{ + char filename[PATH_MAX]; + char name[4096] = {0}; + class rfkill *bl; + ifstream file; + + snprintf(filename, sizeof(filename), "/sys/class/rfkill/%s/name", d_name); + strncpy(name, d_name, sizeof(name) - 1); + file.open(filename, ios::in); + if (file) { + file.getline(name, 100); + file.close(); + } + + snprintf(filename, sizeof(filename), "/sys/class/rfkill/%s", d_name); + bl = new class rfkill(name, filename); + all_devices.push_back(bl); +} + +void create_all_rfkills(void) +{ + process_directory("/sys/class/rfkill/", create_all_rfkills_callback); +} + +double rfkill::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + + power = 0; + factor = get_parameter_value(index, bundle); + util = get_result_value(rindex, result); + + power += util * factor / 100.0; + + return power; +} diff --git a/src/devices/rfkill.h b/src/devices/rfkill.h new file mode 100644 index 0000000..429ba18 --- /dev/null +++ b/src/devices/rfkill.h @@ -0,0 +1,62 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_RFKILL_H +#define _INCLUDE_GUARD_RFKILL_H + +#include <limits.h> + +#include "device.h" +#include "../parameters/parameters.h" + +class rfkill: public device { + int start_soft, end_soft; + int start_hard, end_hard; + char sysfs_path[PATH_MAX]; + char name[4096]; + char humanname[4096]; + int index; + int rindex; +public: + + rfkill(char *_name, char *path); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "radio";}; + + virtual const char * device_name(void); + virtual const char * human_name(void) { return humanname; }; + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual int power_valid(void) { return utilization_power_valid(rindex);}; + virtual int grouping_prio(void) { return 5; }; +}; + +extern void create_all_rfkills(void); + + +#endif
\ No newline at end of file diff --git a/src/devices/runtime_pm.cpp b/src/devices/runtime_pm.cpp new file mode 100644 index 0000000..26f9d32 --- /dev/null +++ b/src/devices/runtime_pm.cpp @@ -0,0 +1,257 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "runtime_pm.h" + +#include <string.h> + +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <dirent.h> +#include <limits.h> + +#include "../parameters/parameters.h" +#include "../lib.h" + +#include <iostream> +#include <fstream> + +runtime_pmdevice::runtime_pmdevice(const char *_name, const char *path) : device() +{ + pt_strcpy(sysfs_path, path); + register_sysfs_path(sysfs_path); + pt_strcpy(name, _name); + snprintf(humanname, sizeof(humanname), "runtime-%s", _name); + + index = get_param_index(humanname); + r_index = get_result_index(humanname); + + before_suspended_time = 0; + before_active_time = 0; + after_suspended_time = 0; + after_active_time = 0; + + register_parameter(humanname); +} + +void runtime_pmdevice::start_measurement(void) +{ + char filename[PATH_MAX]; + ifstream file; + + before_suspended_time = 0; + before_active_time = 0; + after_suspended_time = 0; + after_active_time = 0; + + snprintf(filename, sizeof(filename), "%s/power/runtime_suspended_time", sysfs_path); + file.open(filename, ios::in); + if (!file) + return; + file >> before_suspended_time; + file.close(); + + snprintf(filename, sizeof(filename), "%s/power/runtime_active_time", sysfs_path); + file.open(filename, ios::in); + if (!file) + return; + file >> before_active_time; + file.close(); +} + +void runtime_pmdevice::end_measurement(void) +{ + char filename[PATH_MAX]; + ifstream file; + + snprintf(filename, sizeof(filename), "%s/power/runtime_suspended_time", sysfs_path); + file.open(filename, ios::in); + if (!file) + return; + file >> after_suspended_time; + file.close(); + + snprintf(filename, sizeof(filename), "%s/power/runtime_active_time", sysfs_path); + file.open(filename, ios::in); + if (!file) + return; + file >> after_active_time; + file.close(); +} + +double runtime_pmdevice::utilization(void) /* percentage */ +{ + double d; + d = 100 * (after_active_time - before_active_time) / (0.0001 + after_active_time - before_active_time + after_suspended_time - before_suspended_time); + + if (d < 0.00) + d = 0.0; + if (d > 99.9) + d = 100.0; + return d; +} + +const char * runtime_pmdevice::device_name(void) +{ + return name; +} + +const char * runtime_pmdevice::human_name(void) +{ + return humanname; +} + + +double runtime_pmdevice::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + + power = 0; + + factor = get_parameter_value(index, bundle); + util = get_result_value(r_index, result); + power += util * factor / 100.0; + + return power; +} + +void runtime_pmdevice::set_human_name(char *_name) +{ + pt_strcpy(humanname, _name); +} + + +int device_has_runtime_pm(const char *sysfs_path) +{ + char filename[PATH_MAX]; + ifstream file; + unsigned long value; + + snprintf(filename, sizeof(filename), "%s/power/runtime_suspended_time", sysfs_path); + file.open(filename, ios::in); + if (!file) + return 0; + file >> value; + file.close(); + if (value) + return 1; + + snprintf(filename, sizeof(filename), "%s/power/runtime_active_time", sysfs_path); + file.open(filename, ios::in); + if (!file) + return 0; + file >> value; + file.close(); + if (value) + return 1; + + return 0; +} + +static void do_bus(const char *bus) +{ + /* /sys/bus/pci/devices/0000\:00\:1f.0/power/runtime_suspended_time */ + + struct dirent *entry; + DIR *dir; + char filename[PATH_MAX]; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/", bus); + dir = opendir(filename); + if (!dir) + return; + while (1) { + ifstream file; + class runtime_pmdevice *dev; + entry = readdir(dir); + + if (!entry) + break; + if (entry->d_name[0] == '.') + continue; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s", bus, entry->d_name); + dev = new class runtime_pmdevice(entry->d_name, filename); + + if (strcmp(bus, "i2c") == 0) { + string devname; + char dev_name[4096]; + bool is_adapter = false; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/new_device", bus, entry->d_name); + if (access(filename, W_OK) == 0) + is_adapter = true; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/name", bus, entry->d_name); + file.open(filename, ios::in); + if (file) { + getline(file, devname); + file.close(); + } + + snprintf(dev_name, sizeof(dev_name), _("I2C %s (%s): %s"), (is_adapter ? _("Adapter") : _("Device")), entry->d_name, devname.c_str()); + dev->set_human_name(dev_name); + } + + if (strcmp(bus, "pci") == 0) { + uint16_t vendor = 0, device = 0; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/vendor", bus, entry->d_name); + + file.open(filename, ios::in); + if (file) { + file >> hex >> vendor; + file.close(); + } + + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/device", bus, entry->d_name); + file.open(filename, ios::in); + if (file) { + file >> hex >> device; + file.close(); + } + + if (vendor && device) { + char devname[4096]; + snprintf(devname, sizeof(devname), _("PCI Device: %s"), + pci_id_to_name(vendor, device, filename, 4095)); + dev->set_human_name(devname); + } + } + all_devices.push_back(dev); + } + closedir(dir); +} + +void create_all_runtime_pm_devices(void) +{ + do_bus("pci"); + do_bus("spi"); + do_bus("platform"); + do_bus("i2c"); +} diff --git a/src/devices/runtime_pm.h b/src/devices/runtime_pm.h new file mode 100644 index 0000000..77bf398 --- /dev/null +++ b/src/devices/runtime_pm.h @@ -0,0 +1,66 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_RUNTIMEPM_H +#define _INCLUDE_GUARD_RUNTIMEPM_H + +#include <limits.h> + +#include "device.h" +#include "../parameters/parameters.h" + +class runtime_pmdevice: public device { + uint64_t before_suspended_time, before_active_time; + uint64_t after_suspended_time, after_active_time; + char sysfs_path[PATH_MAX]; + char name[4096]; + char humanname[4096]; + int index; + int r_index; +public: + + runtime_pmdevice(const char *_name, const char *path); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "runtime_pm";}; + + virtual const char * device_name(void); + virtual const char * human_name(void); + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual int power_valid(void) { return utilization_power_valid(r_index);}; + + void set_human_name(char *name); + virtual int grouping_prio(void) { return 1; }; +}; + +extern void create_all_runtime_pm_devices(void); + +extern int device_has_runtime_pm(const char *sysfs_path); + + +#endif
\ No newline at end of file diff --git a/src/devices/thinkpad-fan.cpp b/src/devices/thinkpad-fan.cpp new file mode 100644 index 0000000..8e2ce53 --- /dev/null +++ b/src/devices/thinkpad-fan.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> + +#include <stdio.h> +#include <sys/types.h> +#include <dirent.h> +#include <math.h> +#include <unistd.h> +#include <limits.h> + +#include "../lib.h" + + +#include "device.h" +#include "thinkpad-fan.h" +#include "../parameters/parameters.h" +#include "../process/powerconsumer.h" + +#include <string.h> +#include <unistd.h> + +thinkpad_fan::thinkpad_fan(): device() +{ + start_rate = 0; + end_rate = 0; + fan_index = get_param_index("thinkpad-fan"); + fansqr_index = get_param_index("thinkpad-fan-sqr"); + fancub_index = get_param_index("thinkpad-fan-cub"); + r_index = get_result_index("thinkpad-fan"); + register_sysfs_path("/sys/devices/platform/thinkpad_hwmon"); +} + +void thinkpad_fan::start_measurement(void) +{ + /* read the rpms of the fan */ + start_rate = read_sysfs("/sys/devices/platform/thinkpad_hwmon/fan1_input"); +} + +void thinkpad_fan::end_measurement(void) +{ + end_rate = read_sysfs("/sys/devices/platform/thinkpad_hwmon/fan1_input"); + + report_utilization("thinkpad-fan", utilization()); +} + + +double thinkpad_fan::utilization(void) +{ + return (start_rate+end_rate) / 2; +} + +void create_thinkpad_fan(void) +{ + char filename[PATH_MAX]; + class thinkpad_fan *fan; + + pt_strcpy(filename, "/sys/devices/platform/thinkpad_hwmon/fan1_input"); + + if (access(filename, R_OK) !=0) + return; + + register_parameter("thinkpad-fan", 10); + register_parameter("thinkpad-fan-sqr", 5); + register_parameter("thinkpad-fan-cub", 10); + + fan = new class thinkpad_fan(); + all_devices.push_back(fan); +} + + + +double thinkpad_fan::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + + + power = 0; + util = get_result_value(r_index, result); + + if (util < 0) + util = 0; + + + /* physics dictact that fan power goes cubic with the rpms, but there's also a linear component for friction*/ + factor = get_parameter_value(fancub_index, bundle); + power += factor * pow(util / 3600.0, 3); + + factor = get_parameter_value(fansqr_index, bundle) - 5.0; + power += factor * pow(util / 3600.0, 2); + + factor = get_parameter_value(fan_index, bundle) - 10.0; + power += util / 5000.0 * factor; + + if (power <= 0.0) + power = 0.0; + + return power; +} diff --git a/src/devices/thinkpad-fan.h b/src/devices/thinkpad-fan.h new file mode 100644 index 0000000..34c4c43 --- /dev/null +++ b/src/devices/thinkpad-fan.h @@ -0,0 +1,58 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_THINKPAD_FAN_H +#define _INCLUDE_GUARD_THINKPAD_FAN_H + + +#include "device.h" +#include "../parameters/parameters.h" + +class thinkpad_fan: public device { + double start_rate, end_rate; + int fan_index, fansqr_index, fancub_index; + int r_index; +public: + + thinkpad_fan(); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "fan";}; + + virtual const char * device_name(void) { return "Fan-1";}; + virtual const char * human_name(void) { return "Laptop fan";}; + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual const char * util_units(void) { return " rpm"; }; + virtual int power_valid(void) { return utilization_power_valid(r_index);}; + virtual int grouping_prio(void) { return 1; }; +}; + +extern void create_thinkpad_fan(void); + + +#endif
\ No newline at end of file diff --git a/src/devices/thinkpad-light.cpp b/src/devices/thinkpad-light.cpp new file mode 100644 index 0000000..d047ab3 --- /dev/null +++ b/src/devices/thinkpad-light.cpp @@ -0,0 +1,113 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> + +#include <stdio.h> +#include <sys/types.h> +#include <dirent.h> +#include <math.h> +#include <unistd.h> +#include <limits.h> + +#include "../lib.h" + + +#include "device.h" +#include "thinkpad-light.h" +#include "../parameters/parameters.h" +#include "../process/powerconsumer.h" + +#include <string.h> +#include <unistd.h> + +thinkpad_light::thinkpad_light(): device() +{ + start_rate = 0; + end_rate = 0; + light_index = get_param_index("thinkpad-light"); + r_index = get_result_index("thinkpad-light"); + register_sysfs_path("/sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight"); +} + +void thinkpad_light::start_measurement(void) +{ + /* read the rpms of the light */ + start_rate = read_sysfs("/sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/brightness"); +} + +void thinkpad_light::end_measurement(void) +{ + end_rate = read_sysfs("/sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/brightness"); + + report_utilization("thinkpad-light", utilization()); +} + + +double thinkpad_light::utilization(void) +{ + return (start_rate+end_rate) / 2.55 / 2.0; +} + +void create_thinkpad_light(void) +{ + char filename[PATH_MAX]; + class thinkpad_light *light; + + pt_strcpy(filename, "/sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/brightness"); + + if (access(filename, R_OK) !=0) + return; + + register_parameter("thinkpad-light", 10); + + light = new class thinkpad_light(); + all_devices.push_back(light); +} + + + +double thinkpad_light::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + + + power = 0; + util = get_result_value(r_index, result); + + if (util < 0) + util = 0; + + + factor = get_parameter_value(light_index, bundle) - 10.0; + power += util / 100.0 * factor; + + if (power <= 0.0) + power = 0.0; + + return power; +} diff --git a/src/devices/thinkpad-light.h b/src/devices/thinkpad-light.h new file mode 100644 index 0000000..64a1789 --- /dev/null +++ b/src/devices/thinkpad-light.h @@ -0,0 +1,58 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_THINKPAD_LIGHT_H +#define _INCLUDE_GUARD_THINKPAD_LIGHT_H + + +#include "device.h" +#include "../parameters/parameters.h" + +class thinkpad_light: public device { + double start_rate, end_rate; + int light_index; + int r_index; +public: + + thinkpad_light(); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "light";}; + + virtual const char * device_name(void) { return "Light-1";}; + virtual const char * human_name(void) { return "Thinkpad light";}; + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual const char * util_units(void) { return "%"; }; + virtual int power_valid(void) { return utilization_power_valid(r_index);}; + virtual int grouping_prio(void) { return 1; }; +}; + +extern void create_thinkpad_light(void); + + +#endif
\ No newline at end of file diff --git a/src/devices/usb.cpp b/src/devices/usb.cpp new file mode 100644 index 0000000..5042699 --- /dev/null +++ b/src/devices/usb.cpp @@ -0,0 +1,254 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "usb.h" + +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <limits.h> + +#include "../lib.h" +#include "../devlist.h" +#include "../parameters/parameters.h" + +#include <iostream> +#include <fstream> + +usbdevice::usbdevice(const char *_name, const char *path, const char *devid): device() +{ + ifstream file; + char filename[PATH_MAX]; + char vendor[4096]; + char product[4096]; + + pt_strcpy(sysfs_path, path); + register_sysfs_path(sysfs_path); + pt_strcpy(name, _name); + pt_strcpy(devname, devid); + snprintf(humanname, sizeof(humanname), _("USB device: %s"), pretty_print(devid, vendor, 4096)); + active_before = 0; + active_after = 0; + connected_before = 0; + connected_after = 0; + busnum = 0; + devnum = 0; + + index = get_param_index(devname); + r_index = get_result_index(name); + rootport = 0; + cached_valid = 0; + + + /* root ports and hubs should count as 0 power ... their activity is derived */ + snprintf(filename, sizeof(filename), "%s/bDeviceClass", path); + file.open(filename, ios::in); + if (file) { + int dclass = 0; + + file >> dclass; + file.close(); + if (dclass == 9) + rootport = 1; + }; + + vendor[0] = 0; + product[0] = 0; + snprintf(filename, sizeof(filename), "%s/manufacturer", path); + file.open(filename, ios::in); + if (file) { + file.getline(vendor, 2047); + if (strstr(vendor, "Linux ")) + vendor[0] = 0; + file.close(); + }; + snprintf(filename, sizeof(filename), "%s/product", path); + file.open(filename, ios::in); + if (file) { + file.getline(product, 2040); + file.close(); + }; + if (strlen(vendor) && strlen(product)) + snprintf(humanname, sizeof(humanname), _("USB device: %s (%s)"), product, vendor); + else if (strlen(product)) + snprintf(humanname, sizeof(humanname), _("USB device: %s"), product); + else if (strlen(vendor)) + snprintf(humanname, sizeof(humanname), _("USB device: %s"), vendor); + + /* For usbdevfs we need bus number and device number */ + snprintf(filename, sizeof(filename), "%s/busnum", path); + file.open(filename, ios::in); + if (file) { + + file >> busnum; + file.close(); + }; + snprintf(filename, sizeof(filename), "%s/devnum", path); + file.open(filename, ios::in); + if (file) { + + file >> devnum; + file.close(); + }; +} + + + +void usbdevice::start_measurement(void) +{ + ifstream file; + char fullpath[PATH_MAX]; + + active_before = 0; + active_after = 0; + connected_before = 0; + connected_after = 0; + + snprintf(fullpath, sizeof(fullpath), "%s/power/active_duration", sysfs_path); + file.open(fullpath, ios::in); + if (file) { + file >> active_before; + } + file.close(); + + snprintf(fullpath, sizeof(fullpath), "%s/power/connected_duration", sysfs_path); + file.open(fullpath, ios::in); + if (file) { + file >> connected_before; + } + file.close(); +} + +void usbdevice::end_measurement(void) +{ + ifstream file; + char fullpath[PATH_MAX]; + + snprintf(fullpath, sizeof(fullpath), "%s/power/active_duration", sysfs_path); + file.open(fullpath, ios::in); + if (file) { + file >> active_after; + } + file.close(); + + snprintf(fullpath, sizeof(fullpath), "%s/power/connected_duration", sysfs_path); + file.open(fullpath, ios::in); + if (file) { + file >> connected_after; + } + file.close(); + report_utilization(name, utilization()); + +} + +double usbdevice::utilization(void) /* percentage */ +{ + double d; + d = 100.0 * (active_after - active_before) / (0.01 + connected_after - connected_before); + if (d < 0.0) + d = 0.0; + if (d > 99.8) + d = 100.0; + return d; +} + +const char * usbdevice::device_name(void) +{ + return name; +} + +const char * usbdevice::human_name(void) +{ + return humanname; +} + +void usbdevice::register_power_with_devlist(struct result_bundle *results, struct parameter_bundle *bundle) +{ + char devfs_name[1024]; + + snprintf(devfs_name, sizeof(devfs_name), "usb/%03d/%03d", busnum, + devnum); + + register_devpower(devfs_name, power_usage(results, bundle), this); +} + +double usbdevice::power_usage(struct result_bundle *result, struct parameter_bundle *bundle) +{ + double power; + double factor; + double util; + + if (rootport || !cached_valid) + return 0.0; + + + power = 0; + factor = get_parameter_value(index, bundle); + util = get_result_value(r_index, result); + + power += util * factor / 100.0; + + return power; +} + +static void create_all_usb_devices_callback(const char *d_name) +{ + char filename[PATH_MAX]; + ifstream file; + class usbdevice *usb; + char device_name[PATH_MAX]; + char vendorid[64], devid[64]; + char devid_name[4096]; + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s", d_name); + snprintf(device_name, sizeof(device_name), "%s/power/active_duration", filename); + if (access(device_name, R_OK) != 0) + return; + + snprintf(device_name, sizeof(device_name), "%s/idVendor", filename); + file.open(device_name, ios::in); + if (file) + file.getline(vendorid, 64); + file.close(); + snprintf(device_name, sizeof(device_name), "%s/idProduct", filename); + file.open(device_name, ios::in); + if (file) + file.getline(devid, 64); + file.close(); + + snprintf(devid_name, sizeof(devid_name), "usb-device-%s-%s", vendorid, devid); + snprintf(device_name, sizeof(device_name), "usb-device-%s-%s-%s", d_name, vendorid, devid); + if (result_device_exists(device_name)) + return; + + usb = new class usbdevice(device_name, filename, devid_name); + all_devices.push_back(usb); + register_parameter(devid_name, 0.1); +} + +void create_all_usb_devices(void) +{ + process_directory("/sys/bus/usb/devices/", create_all_usb_devices_callback); +} diff --git a/src/devices/usb.h b/src/devices/usb.h new file mode 100644 index 0000000..7e76a55 --- /dev/null +++ b/src/devices/usb.h @@ -0,0 +1,67 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_USB_H +#define _INCLUDE_GUARD_USB_H + +#include <limits.h> + +#include "device.h" +#include "../parameters/parameters.h" + +class usbdevice: public device { + int active_before, active_after; + int connected_before, connected_after; + char sysfs_path[PATH_MAX]; + char name[4096]; + char devname[4096]; + char humanname[4096]; + int index; + int r_index; + int rootport; + int busnum; + int devnum; +public: + + usbdevice(const char *_name, const char *path, const char *devid); + + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double utilization(void); /* percentage */ + + virtual const char * class_name(void) { return "usb";}; + + virtual const char * device_name(void); + virtual const char * human_name(void); + virtual void register_power_with_devlist(struct result_bundle *results, struct parameter_bundle *bundle); + virtual double power_usage(struct result_bundle *result, struct parameter_bundle *bundle); + virtual int power_valid(void) { return utilization_power_valid(r_index);}; + virtual int grouping_prio(void) { return 4; }; +}; + +extern void create_all_usb_devices(void); + + +#endif
\ No newline at end of file diff --git a/src/devlist.cpp b/src/devlist.cpp new file mode 100644 index 0000000..70ae70e --- /dev/null +++ b/src/devlist.cpp @@ -0,0 +1,351 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +/* + * Code to track centrally which process has what /dev files open + */ +#include <iostream> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sys/stat.h> +#include <vector> +#include <algorithm> +#include <unistd.h> +#include <sys/types.h> +#include <dirent.h> +#include <string.h> +#include <ctype.h> +#include <limits.h> + +using namespace std; + +#include "devlist.h" +#include "lib.h" +#include "report/report.h" +#include "report/report-maker.h" +#include "report/report-data-html.h" + +#include "process/process.h" +#include "devices/device.h" +/* + +* collect list of processes that have devices open + (alternate between before and after lists) + +* charge a "surcharge" to a device (sub)string + - count how many openers + - add proprotion to each process that has it open + +* list of devices + power they use for processing + +*/ + +static vector<struct devuser *> one; +static vector<struct devuser *> two; +static vector<struct devpower *> devpower; + +static int phase; +/* + * 0 - one = before, two = after + * 1 - one = after, two = before + */ + +void clean_open_devices() +{ + unsigned int i=0; + + for (i = 0; i < one.size(); i++) { + free(one[i]); + } + + for (i = 0; i < two.size(); i++) { + free(two[i]); + } + + for (i = 0; i < devpower.size(); i++){ + free(devpower[i]); + } +} + +void collect_open_devices(void) +{ + struct dirent *entry; + DIR *dir; + char filename[PATH_MAX]; + char link[PATH_MAX]; + unsigned int i; + vector<struct devuser *> *target; + + if (phase == 1) + target = &one; + else + target = &two; + + for (i = 0; i < target->size(); i++) { + free((*target)[i]); + } + target->resize(0); + + + dir = opendir("/proc/"); + if (!dir) + return; + while (1) { + struct dirent *entry2; + DIR *dir2; + entry = readdir(dir); + + if (!entry) + break; + if (entry->d_name[0] == '.') + continue; + if (strcmp(entry->d_name, "self") == 0) + continue; + + snprintf(filename, sizeof(filename), "/proc/%s/fd/", entry->d_name); + + dir2 = opendir(filename); + if (!dir2) + continue; + while (1) { + int ret; + struct devuser * dev; + entry2 = readdir(dir2); + if (!entry2) + break; + if (!isdigit(entry2->d_name[0])) + continue; + snprintf(filename, sizeof(filename), "/proc/%s/fd/%s", entry->d_name, entry2->d_name); + memset(link, 0, sizeof(link)); + ret = readlink(filename, link, sizeof(link) - 1); + if (ret < 0) + continue; + + if (strcmp(link, "/dev/null") == 0) + continue; + if (strcmp(link, "/dev/.udev/queue.bin") == 0) + continue; + if (strcmp(link, "/dev/initctl") == 0) + continue; + if (strcmp(link, "/dev/ptmx") == 0) + continue; + if (strstr(link, "/dev/pts/")) + continue; + if (strstr(link, "/dev/shm/")) + continue; + if (strstr(link, "/dev/urandom")) + continue; + if (strstr(link, "/dev/tty")) + continue; + + if (strncmp(link, "/dev", 4)==0) { + dev = (struct devuser *)malloc(sizeof(struct devuser)); + if (!dev) + continue; + dev->pid = strtoull(entry->d_name, NULL, 10); + strncpy(dev->device, link, 251); + dev->device[251] = '\0'; + strncpy(dev->comm, read_sysfs_string("/proc/%s/comm", entry->d_name).c_str(), 31); + dev->comm[31] = '\0'; + target->push_back(dev); + + } + } + closedir(dir2); + } + closedir(dir); + + if (phase) + phase = 0; + else + phase = 1; +} + + +/* returns 0 if no process is identified as having the device open and a value > 0 otherwise */ +int charge_device_to_openers(const char *devstring, double power, class device *_dev) +{ + unsigned int i; + int openers = 0; + class process *proc; + /* 1. count the number of openers */ + + for (i = 0; i < one.size(); i++) { + if (strstr(one[i]->device, devstring)) + openers++; + } + for (i = 0; i < two.size(); i++) { + if (strstr(two[i]->device, devstring)) + openers++; + } + + + /* 2. divide power by this number */ + + if (!openers) + return 0; + power = power / openers; + + + /* 3. for each process that has it open, add the charge */ + + for (i = 0; i < one.size(); i++) + if (strstr(one[i]->device, devstring)) { + proc = find_create_process(one[i]->comm, one[i]->pid); + if (proc) { + proc->power_charge += power; + if (strlen(_dev->guilty) < 2000 && strstr(_dev->guilty, one[i]->comm) == NULL) { + strcat(_dev->guilty, one[i]->comm); + strcat(_dev->guilty, " "); + } + } + } + + for (i = 0; i < two.size(); i++) + if (strstr(two[i]->device, devstring)) { + proc = find_create_process(two[i]->comm, two[i]->pid); + if (proc) { + proc->power_charge += power; + if (strlen(_dev->guilty) < 2000 && strstr(_dev->guilty, two[i]->comm) == NULL) { + strcat(_dev->guilty, two[i]->comm); + strcat(_dev->guilty, " "); + } + } + } + + + + return openers; +} + +void clear_devpower(void) +{ + unsigned int i; + + for (i = 0; i < devpower.size(); i++) { + devpower[i]->power = 0.0; + devpower[i]->dev->guilty[0] = 0; + } +} + +void register_devpower(const char *devstring, double power, class device *_dev) +{ + unsigned int i; + struct devpower *dev = NULL; + + for (i = 0; i < devpower.size(); i++) + if (strcmp(devstring, devpower[i]->device) == 0) { + dev = devpower[i]; + } + + if (!dev) { + dev = (struct devpower *)malloc(sizeof (struct devpower)); + pt_strcpy(dev->device, devstring); + dev->power = 0.0; + devpower.push_back(dev); + } + dev->dev = _dev; + dev->power = power; +} + +void run_devpower_list(void) +{ + unsigned int i; + + for (i = 0; i < devpower.size(); i++) { + int ret; + ret = charge_device_to_openers(devpower[i]->device, devpower[i]->power, devpower[i]->dev); + if (ret) + devpower[i]->dev->hide = true; + else + devpower[i]->dev->hide = false; + + } + +} + +static bool devlist_sort(struct devuser * i, struct devuser * j) +{ + if (i->pid != j->pid) + return i->pid < j->pid; + + return (strcmp(i->device, j->device)< 0); +} + +void report_show_open_devices(void) +{ + vector<struct devuser *> *target; + unsigned int i; + char prev[128], proc[128]; + int idx, cols, rows; + + prev[0] = 0; + if (phase == 1) + target = &one; + else + target = &two; + + if (target->size() == 0) + return; + + + /* Set Table attributes, rows, and cols */ + table_attributes std_table_css; + cols = 2; + idx = cols; + rows= target->size() + 1; + init_std_table_attr(&std_table_css, rows, cols); + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Set array of data in row Major order */ + string *process_data = new string[cols * rows]; + + sort(target->begin(), target->end(), devlist_sort); + process_data[0]=__("Process"); + process_data[1]=__("Device"); + + for (i = 0; i < target->size(); i++) { + proc[0] = 0; + if (strcmp(prev, (*target)[i]->comm) != 0) + snprintf(proc, sizeof(proc), "%s", (*target)[i]->comm); + + process_data[idx]=string(proc); + idx+=1; + process_data[idx]=string((*target)[i]->device); + idx+=1; + snprintf(prev, sizeof(prev), "%s", (*target)[i]->comm); + } + + /* Report Output */ + /* No div attribute here inherits from device power report */ + report.add_title(&title_attr, __("Process Device Activity")); + report.add_table(process_data, &std_table_css); + delete [] process_data; + report.end_div(); +} diff --git a/src/devlist.h b/src/devlist.h new file mode 100644 index 0000000..35dfd6c --- /dev/null +++ b/src/devlist.h @@ -0,0 +1,27 @@ +#ifndef __INCLUDE_GUARD_DEVLIST_H__ +#define __INCLUDE_GUARD_DEVLIST_H__ + +struct devuser { + unsigned int pid; + char comm[32]; + char device[252]; +}; + +class device; + +struct devpower { + char device[252]; + double power; + class device *dev; +}; + +extern void clean_open_devices(); +extern void collect_open_devices(void); + +extern void clear_devpower(void); +extern void register_devpower(const char *devstring, double power, class device *dev); +extern void run_devpower_list(void); + +extern void report_show_open_devices(void); + +#endif diff --git a/src/display.cpp b/src/display.cpp new file mode 100644 index 0000000..cc03919 --- /dev/null +++ b/src/display.cpp @@ -0,0 +1,342 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "display.h" +#include "lib.h" + +#include <ncurses.h> + + +#include <vector> +#include <map> +#include <string> +#include <string.h> + +using namespace std; + +static int display = 0; + +vector<string> tab_names; +map<string, class tab_window *> tab_windows; +map<string, string> tab_translations; + +map<string, string> bottom_lines; + +void create_tab(const string &name, const string &translation, class tab_window *w, string bottom_line) +{ + if (!w) + w = new(class tab_window); + + w->win = newpad(1000,1000); + tab_names.push_back(name); + tab_windows[name] = w; + tab_translations[name] = translation; + bottom_lines[name] = bottom_line; +} + + +void init_display(void) +{ + initscr(); + start_color(); + + cbreak(); /* character at a time input */ + noecho(); /* don't show the user input */ + keypad(stdscr, TRUE); /* enable cursor/etc keys */ + + use_default_colors(); + + create_tab("Overview", _("Overview")); + create_tab("Idle stats", _("Idle stats")); + create_tab("Frequency stats", _("Frequency stats")); + create_tab("Device stats", _("Device stats")); + + display = 1; +} + +void reset_display(void) +{ + if (!display) + return; + + keypad(stdscr, FALSE); + echo(); + nocbreak(); + + resetterm(); +} + + +WINDOW *tab_bar = NULL; +WINDOW *bottom_line = NULL; + +static int current_tab; + +void show_tab(unsigned int tab) +{ + class tab_window *win; + unsigned int i; + int tab_pos = 17; + const char *c; + + if (!display) + return; + + if (tab_bar) { + delwin(tab_bar); + tab_bar = NULL; + } + + if (bottom_line) { + delwin(bottom_line); + bottom_line = NULL; + } + + tab_bar = newwin(1, 0, 0, 0); + + wattrset(tab_bar, A_REVERSE); + mvwprintw(tab_bar, 0,0, "%120s", ""); + mvwprintw(tab_bar, 0,0, "PowerTOP %s", PACKAGE_VERSION); + + bottom_line = newwin(1, 0, LINES-1, 0); + wattrset(bottom_line, A_REVERSE); + mvwprintw(bottom_line, 0,0, "%120s", ""); + + c = bottom_lines[tab_names[tab]].c_str(); + if (c && strlen(c) > 0) + mvwprintw(bottom_line, 0,0, "%s", c); + else + mvwprintw(bottom_line, 0, 0, + "<ESC> %s | <TAB> / <Shift + TAB> %s | ", _("Exit"), + _("Navigate")); + + + current_tab = tab; + + for (i = 0; i < tab_names.size(); i++) { + if (i == tab) + wattrset(tab_bar, A_NORMAL); + else + wattrset(tab_bar, A_REVERSE); + mvwprintw(tab_bar, 0, tab_pos, " %s ", tab_translations[tab_names[i]].c_str()); + + tab_pos += 3 + tab_names[i].length(); + } + + wrefresh(tab_bar); + wrefresh(bottom_line); + + win = tab_windows[tab_names[tab]]; + if (!win) + return; + + prefresh(win->win, win->ypad_pos, win->xpad_pos, 1, 0, LINES - 3, COLS - 1); +} + +WINDOW *get_ncurses_win(const char *name) +{ + class tab_window *w; + WINDOW *win; + + w= tab_windows[name]; + if (!w) + return NULL; + + win = w->win; + + return win; +} + +WINDOW *get_ncurses_win(int nr) +{ + class tab_window *w; + WINDOW *win; + + w= tab_windows[tab_names[nr]]; + if (!w) + return NULL; + + win = w->win; + + return win; +} + +WINDOW *get_ncurses_win(const string &name) +{ + return get_ncurses_win(name.c_str()); +} + +void show_prev_tab(void) +{ + class tab_window *w; + + if (!display) + return; + w = tab_windows[tab_names[current_tab]]; + if (w) + w->hide(); + + current_tab --; + if (current_tab < 0) + current_tab = tab_names.size() - 1; + + w = tab_windows[tab_names[current_tab]]; + if (w) + w->expose(); + + show_tab(current_tab); +} + +void show_next_tab(void) +{ + class tab_window *w; + + if (!display) + return; + + w = tab_windows[tab_names[current_tab]]; + if (w) + w->hide(); + + current_tab ++; + if (current_tab >= (int)tab_names.size()) + current_tab = 0; + + w = tab_windows[tab_names[current_tab]]; + if (w) + w->expose(); + + show_tab(current_tab); +} + +void show_cur_tab(void) +{ + if (!display) + return; + show_tab(current_tab); +} + +void cursor_down(void) +{ + class tab_window *w; + + w = tab_windows[tab_names[current_tab]]; + if (w) { + if (w->ypad_pos < 1000) { + if (tab_names[current_tab] == "Tunables" || tab_names[current_tab] == "WakeUp") { + if ((w->cursor_pos + 7) >= LINES) { + prefresh(w->win, ++w->ypad_pos, w->xpad_pos, + 1, 0, LINES - 3, COLS - 1); + } + w->cursor_down(); + } else { + prefresh(w->win, ++w->ypad_pos, w->xpad_pos, + 1, 0, LINES - 3, COLS - 1); + } + } + } + + show_cur_tab(); +} + +void cursor_up(void) +{ + class tab_window *w; + + w = tab_windows[tab_names[current_tab]]; + + if (w) { + w->cursor_up(); + if(w->ypad_pos > 0) { + prefresh(w->win, --w->ypad_pos, w->xpad_pos, + 1, 0, LINES - 3, COLS - 1); + } + } + + show_cur_tab(); +} + +void cursor_left(void) +{ + class tab_window *w; + + w = tab_windows[tab_names[current_tab]]; + + if (w) { + if (w->xpad_pos > 0) { + prefresh(w->win, w->ypad_pos,--w->xpad_pos, + 1, 0, LINES - 3, COLS - 1); + } + } +} + +void cursor_right(void) +{ + class tab_window *w; + + w = tab_windows[tab_names[current_tab]]; + + if (w) { + if (w->xpad_pos < 1000) { + prefresh(w->win, w->ypad_pos, ++w->xpad_pos, + 1, 0, LINES - 3, COLS - 1); + } + } +} + +void cursor_enter(void) +{ + class tab_window *w; + + w = tab_windows[tab_names[current_tab]]; + + if (w) { + w->cursor_enter(); + w->repaint(); + } + show_cur_tab(); +} + +void window_refresh() +{ + class tab_window *w; + + w = tab_windows[tab_names[current_tab]]; + + if (w) { + w->ypad_pos = 0; + w->xpad_pos = 0; + w->window_refresh(); + w->repaint(); + } + + show_cur_tab(); +} + +int ncurses_initialized(void) +{ + if (display) + return 1; + return 0; +} diff --git a/src/display.h b/src/display.h new file mode 100644 index 0000000..9db87ec --- /dev/null +++ b/src/display.h @@ -0,0 +1,99 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_DISPLAY_H_ +#define __INCLUDE_GUARD_DISPLAY_H_ + + +#include <map> +#include <string> +#include <ncurses.h> + +using namespace std; + +extern void init_display(void); +extern void reset_display(void); +extern int ncurses_initialized(void); +extern void show_tab(unsigned int tab); +extern void show_next_tab(void); +extern void show_prev_tab(void); +extern void show_cur_tab(void); +extern void cursor_up(void); +extern void cursor_down(void); +extern void cursor_right(void); +extern void cursor_left(void); +extern void cursor_enter(void); +extern void window_refresh(void); + +class tab_window { +public: + int cursor_pos; + int cursor_max; + short int xpad_pos, ypad_pos; + WINDOW *win; + + tab_window() { + cursor_pos = 0; + cursor_max = 0; + xpad_pos =0; + ypad_pos = 0; + win = NULL; + } + + virtual void cursor_down(void) { + if (cursor_pos < cursor_max) + cursor_pos++; + repaint(); + } ; + virtual void cursor_up(void) { + if (cursor_pos > 0) + cursor_pos--; + repaint(); + }; + virtual void cursor_left(void) { }; + virtual void cursor_right(void) { }; + + virtual void cursor_enter(void) { }; + virtual void window_refresh() { }; + + virtual void repaint(void) { }; + virtual void expose(void) { cursor_pos = 0; repaint();}; + virtual void hide(void) { }; + + virtual ~tab_window() + { + delwin(win); + win = NULL; + } +}; + +extern map<string, class tab_window *> tab_windows; + +WINDOW *get_ncurses_win(const char *name); +WINDOW *get_ncurses_win(const string &name); +WINDOW *get_ncurses_win(int nr); + +void create_tab(const string &name, const string &translation, class tab_window *w = NULL, string bottom_line = ""); + +#endif diff --git a/src/lib.cpp b/src/lib.cpp new file mode 100644 index 0000000..5cd1c4a --- /dev/null +++ b/src/lib.cpp @@ -0,0 +1,597 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + * Peter Anvin + */ +#include <map> +#include <string.h> +#include <iostream> +#include <utility> +#include <iostream> +#include <fstream> +#include <string> +#include <ctype.h> +#include <stdio.h> +#include <math.h> +#include <stdlib.h> +#include <limits.h> + +#include "lib.h" + +#ifndef HAVE_NO_PCI +extern "C" { +#include <pci/pci.h> +} +#endif + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <locale.h> +#include <libintl.h> +#include <limits> +#include <math.h> +#include <ncurses.h> +#include <fcntl.h> +#include <glob.h> + +static int kallsyms_read = 0; + +int is_turbo(uint64_t freq, uint64_t max, uint64_t maxmo) +{ + if (freq != max) + return 0; + if (maxmo + 1000 != max) + return 0; + return 1; +} + +double percentage(double F) +{ + F = F * 100.0; +// if (F > 100.0) +// F = 100.0; + if (F < 0.0) + F = 0.0; + return F; +} + +char *hz_to_human(unsigned long hz, char *buffer, int digits) +{ + unsigned long long Hz; + + buffer[0] = 0; + + Hz = hz; + + /* default: just put the Number in */ + sprintf(buffer,"%9lli", Hz); + + if (Hz>1000) { + if (digits == 2) + sprintf(buffer, "%4lli MHz", (Hz+500)/1000); + else + sprintf(buffer, "%6lli MHz", (Hz+500)/1000); + } + + if (Hz>1500000) { + if (digits == 2) + sprintf(buffer, "%4.2f GHz", (Hz+5000.0)/1000000); + else + sprintf(buffer, "%3.1f GHz", (Hz+5000.0)/1000000); + } + + return buffer; +} + +using namespace std; + +map<unsigned long, string> kallsyms; + +static void read_kallsyms(void) +{ + ifstream file; + char line[1024]; + kallsyms_read = 1; + + file.open("/proc/kallsyms", ios::in); + + while (file) { + char *c = NULL, *c2 = NULL; + unsigned long address = 0; + memset(line, 0, 1024); + file.getline(line, 1024); + c = strchr(line, ' '); + if (!c) + continue; + *c = 0; + c2 = c + 1; + if (*c2) c2++; + if (*c2) c2++; + + address = strtoull(line, NULL, 16); + c = strchr(c2, '\t'); + if (c) + *c = 0; + if (address != 0) + kallsyms[address] = c2; + } + file.close(); +} + +const char *kernel_function(uint64_t address) +{ + const char *c; + if (!kallsyms_read) + read_kallsyms(); + + c = kallsyms[address].c_str(); + if (!c) + return ""; + return c; +} + +static int _max_cpu; +int get_max_cpu(void) +{ + return _max_cpu; +} + +void set_max_cpu(int cpu) +{ + if (cpu > _max_cpu) + _max_cpu = cpu; +} + + +void write_sysfs(const string &filename, const string &value) +{ + ofstream file; + + file.open(filename.c_str(), ios::out); + if (!file) + return; + try + { + file << value; + file.close(); + } catch (std::exception &exc) { + return; + } +} + +int read_sysfs(const string &filename, bool *ok) +{ + ifstream file; + int i; + + file.open(filename.c_str(), ios::in); + if (!file) { + if (ok) + *ok = false; + return 0; + } + try + { + file >> i; + if (ok) + *ok = true; + } catch (std::exception &exc) { + if (ok) + *ok = false; + i = 0; + } + file.close(); + return i; +} + +string read_sysfs_string(const string &filename) +{ + ifstream file; + char content[4096]; + char *c; + + file.open(filename.c_str(), ios::in); + if (!file) + return ""; + try + { + file.getline(content, 4096); + file.close(); + c = strchr(content, '\n'); + if (c) + *c = 0; + } catch (std::exception &exc) { + file.close(); + return ""; + } + return content; +} + +string read_sysfs_string(const char *format, const char *param) +{ + ifstream file; + char content[4096]; + char *c; + char filename[PATH_MAX]; + + + snprintf(filename, sizeof(filename), format, param); + + file.open(filename, ios::in); + if (!file) + return ""; + try + { + file.getline(content, 4096); + file.close(); + c = strchr(content, '\n'); + if (c) + *c = 0; + } catch (std::exception &exc) { + file.close(); + return ""; + } + return content; +} + +void align_string(char *buffer, size_t min_sz, size_t max_sz) +{ + size_t sz; + + /** mbsrtowcs() allows NULL dst and zero sz, + * comparing to mbstowcs(), which causes undefined + * behaviour under given circumstances*/ + + /* start with mbsrtowcs() local mbstate_t * and + * NULL dst pointer*/ + sz = mbsrtowcs(NULL, (const char **)&buffer, max_sz, NULL); + if (sz == (size_t)-1) { + buffer[min_sz] = 0x00; + return; + } + while (sz < min_sz) { + strcat(buffer, " "); + sz++; + } +} + +void format_watts(double W, char *buffer, unsigned int len) +{ + buffer[0] = 0; + char buf[32]; + sprintf(buffer, _("%7sW"), fmt_prefix(W, buf)); + + if (W < 0.0001) + sprintf(buffer, _(" 0 mW")); + + align_string(buffer, len, len); +} + +#ifndef HAVE_NO_PCI +static struct pci_access *pci_access; + +char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len) +{ + char *ret; + + buffer[0] = 0; + + if (!pci_access) { + pci_access = pci_alloc(); + pci_init(pci_access); + } + + ret = pci_lookup_name(pci_access, buffer, len, PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, vendor, device); + + return ret; +} + +void end_pci_access(void) +{ + if (pci_access) + pci_free_name_list(pci_access); +} + +#else + +char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len) +{ + return NULL; +} + +void end_pci_access(void) +{ +} + +#endif /* HAVE_NO_PCI */ + +int utf_ok = -1; + + + +/* pretty print numbers while limiting the precision */ +char *fmt_prefix(double n, char *buf) +{ + static const char prefixes[] = "yzafpnum kMGTPEZY"; + char tmpbuf[16]; + int omag, npfx; + char *p, *q, pfx, *c; + int i; + + if (utf_ok == -1) { + char *g; + g = getenv("LANG"); + if (g && strstr(g, "UTF-8")) + utf_ok = 1; + else + utf_ok = 0; + } + + p = buf; + + *p = ' '; + if (n < 0.0) { + *p = '-'; + n = -n; + p++; + } + + snprintf(tmpbuf, sizeof tmpbuf, "%.2e", n); + c = strchr(tmpbuf, 'e'); + if (!c) { + sprintf(buf, "NaN"); + return buf; + } + omag = atoi(c + 1); + + npfx = ((omag + 27) / 3) - (27/3); + omag = (omag + 27) % 3; + + q = tmpbuf; + if (omag == 2) + omag = -1; + + for (i = 0; i < 3; i++) { + while (!isdigit(*q)) + q++; + *p++ = *q++; + if (i == omag) + *p++ = '.'; + } + *p++ = ' '; + + pfx = prefixes[npfx + 8]; + + if (pfx == ' ') { + /* do nothing */ + } else if (pfx == 'u' && utf_ok > 0) { + strcpy(p, "µ"); /* Mu is a multibyte sequence */ + while (*p) + p++; + } else { + *p++ = pfx; + } + *p = '\0'; + + return buf; +} + +static map<string, string> pretty_prints; +static int pretty_print_init = 0; + +static void init_pretty_print(void) +{ + pretty_prints["[12] i8042"] = _("PS/2 Touchpad / Keyboard / Mouse"); + pretty_prints["ahci"] = _("SATA controller"); + pretty_prints["usb-device-8087-0020"] = _("Intel built in USB hub"); + + pretty_print_init = 1; +} + + +char *pretty_print(const char *str, char *buf, int len) +{ + const char *p; + + if (!pretty_print_init) + init_pretty_print(); + + p = pretty_prints[str].c_str(); + + if (strlen(p) == 0) + p = str; + + snprintf(buf, len, "%s", p); + + if (len) + buf[len - 1] = 0; + return buf; +} + +int equals(double a, double b) +{ + return fabs(a - b) <= std::numeric_limits<double>::epsilon(); +} + +void process_directory(const char *d_name, callback fn) +{ + struct dirent *entry; + DIR *dir; + dir = opendir(d_name); + if (!dir) + return; + while (1) { + entry = readdir(dir); + if (!entry) + break; + if (entry->d_name[0] == '.') + continue; + fn(entry->d_name); + } + closedir(dir); +} + +void process_glob(const char *d_glob, callback fn) +{ + glob_t g; + size_t c; + + switch (glob(d_glob, GLOB_ERR | GLOB_MARK | GLOB_NOSORT, NULL, &g)) { + case GLOB_NOSPACE: + fprintf(stderr,_("glob returned GLOB_NOSPACE\n")); + globfree(&g); + return; + case GLOB_ABORTED: + fprintf(stderr,_("glob returned GLOB_ABORTED\n")); + globfree(&g); + return; + case GLOB_NOMATCH: + fprintf(stderr,_("glob returned GLOB_NOMATCH\n")); + globfree(&g); + return; + } + + for (c=0; c < g.gl_pathc; c++) { + fn(g.gl_pathv[c]); + } + globfree(&g); +} + +int get_user_input(char *buf, unsigned sz) +{ + fflush(stdout); + echo(); + /* Upon successful completion, these functions return OK. Otherwise, they return ERR. */ + int ret = getnstr(buf, sz); + noecho(); + fflush(stdout); + /* to distinguish between getnstr error and empty line */ + return ret || strlen(buf); +} + +int read_msr(int cpu, uint64_t offset, uint64_t *value) +{ +#if defined(__i386__) || defined(__x86_64__) + ssize_t retval; + uint64_t msr; + int fd; + char msr_path[256]; + + snprintf(msr_path, sizeof(msr_path), "/dev/cpu/%d/msr", cpu); + + if (access(msr_path, R_OK) != 0){ + snprintf(msr_path, sizeof(msr_path), "/dev/msr%d", cpu); + + if (access(msr_path, R_OK) != 0){ + fprintf(stderr, + _("Model-specific registers (MSR)\ + not found (try enabling CONFIG_X86_MSR).\n")); + return -1; + } + } + + fd = open(msr_path, O_RDONLY); + if (fd < 0) + return -1; + retval = pread(fd, &msr, sizeof msr, offset); + close(fd); + if (retval != sizeof msr) { + return -1; + } + *value = msr; + + return retval; +#else + return -1; +#endif +} + +int write_msr(int cpu, uint64_t offset, uint64_t value) +{ +#if defined(__i386__) || defined(__x86_64__) + ssize_t retval; + int fd; + char msr_path[256]; + + snprintf(msr_path, sizeof(msr_path), "/dev/cpu/%d/msr", cpu); + + if (access(msr_path, R_OK) != 0){ + snprintf(msr_path, sizeof(msr_path), "/dev/msr%d", cpu); + + if (access(msr_path, R_OK) != 0){ + fprintf(stderr, + _("Model-specific registers (MSR)\ + not found (try enabling CONFIG_X86_MSR).\n")); + return -1; + } + } + + fd = open(msr_path, O_WRONLY); + if (fd < 0) + return -1; + retval = pwrite(fd, &value, sizeof value, offset); + close(fd); + if (retval != sizeof value) { + return -1; + } + + return retval; +#else + return -1; +#endif +} + +#define UI_NOTIFY_BUFF_SZ 2048 + +void ui_notify_user_ncurses(const char *frmt, ...) +{ + char notify[UI_NOTIFY_BUFF_SZ]; + va_list list; + + start_color(); + init_pair(1, COLOR_BLACK, COLOR_WHITE); + attron(COLOR_PAIR(1)); + va_start(list, frmt); + /* there is no ncurses *print() function which takes + * int x, int y and va_list, this is why we use temp + * buffer */ + vsnprintf(notify, UI_NOTIFY_BUFF_SZ - 1, frmt, list); + va_end(list); + mvprintw(1, 0, "%s", notify); + attroff(COLOR_PAIR(1)); +} + +void ui_notify_user_console(const char *frmt, ...) +{ + va_list list; + + va_start(list, frmt); + vprintf(frmt, list); + va_end(list); +} diff --git a/src/lib.h b/src/lib.h new file mode 100644 index 0000000..6d85eb6 --- /dev/null +++ b/src/lib.h @@ -0,0 +1,95 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef INCLUDE_GUARD_LIB_H +#define INCLUDE_GUARD_LIB_H + +#include <libintl.h> +#include <stdint.h> +#include <stdlib.h> +#include <cstring> + +/* Include only for Automake builds */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#define _(STRING) gettext(STRING) +#else +#define _(STRING) (STRING) +#endif + +extern int is_turbo(uint64_t freq, uint64_t max, uint64_t maxmo); + +extern int get_max_cpu(void); +extern void set_max_cpu(int cpu); + +extern double percentage(double F); +extern char *hz_to_human(unsigned long hz, char *buffer, int digits = 2); + + +extern const char *kernel_function(uint64_t address); + + + +#include <ctime> +#include <string> +using namespace std; + +extern void write_sysfs(const string &filename, const string &value); +extern int read_sysfs(const string &filename, bool *ok = NULL); +extern string read_sysfs_string(const string &filename); +extern string read_sysfs_string(const char *format, const char *param); + +extern void format_watts(double W, char *buffer, unsigned int len); + +extern char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len); +extern void end_pci_access(void); + + +extern char *fmt_prefix(double n, char *buf); +extern char *pretty_print(const char *str, char *buf, int len); +extern int equals(double a, double b); + +template<size_t N> void pt_strcpy(char (&d)[N], const char *s) +{ + strncpy(d, s, N); + d[N-1] = '\0'; +} + +typedef void (*callback)(const char*); +extern void process_directory(const char *d_name, callback fn); +extern void process_glob(const char *glob, callback fn); +extern int utf_ok; +extern int get_user_input(char *buf, unsigned sz); +extern int read_msr(int cpu, uint64_t offset, uint64_t *value); +extern int write_msr(int cpu, uint64_t offset, uint64_t value); + +extern void align_string(char *buffer, size_t min_sz, size_t max_sz); + +extern void ui_notify_user_ncurses(const char *frmt, ...); +extern void ui_notify_user_console(const char *frmt, ...); +extern void (*ui_notify_user) (const char *frmt, ...); +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..45aaa58 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,578 @@ +/* + * Copyright 2010, Intel Corporation + * + * This is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * getopt code is taken from "The GNU C Library" reference manual, + * section 24.2 "Parsing program options using getopt" + * http://www.gnu.org/s/libc/manual/html_node/Getopt-Long-Option-Example.html + * Manual published under the terms of the Free Documentation License. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sys/stat.h> +#include <sys/statfs.h> +#include <getopt.h> +#include <unistd.h> +#include <locale.h> +#include <sys/resource.h> +#include <limits.h> +#include <pthread.h> + +#include "cpu/cpu.h" +#include "process/process.h" +#include "perf/perf.h" +#include "perf/perf_bundle.h" +#include "lib.h" +#include "../config.h" + + +#include "devices/device.h" +#include "devices/devfreq.h" +#include "devices/usb.h" +#include "devices/ahci.h" +#include "measurement/measurement.h" +#include "parameters/parameters.h" +#include "calibrate/calibrate.h" + + +#include "tuning/tuning.h" +#include "wakeup/wakeup.h" + +#include "display.h" +#include "devlist.h" +#include "report/report.h" + +#define DEBUGFS_MAGIC 0x64626720 + +#define NR_OPEN_DEF 1024 * 1024 + +int debug_learning = 0; +unsigned time_out = 20; +int leave_powertop = 0; +void (*ui_notify_user) (const char *frmt, ...); + +enum { + OPT_AUTO_TUNE = CHAR_MAX + 1, + OPT_EXTECH, + OPT_DEBUG +}; + +static const struct option long_options[] = +{ + /* These options set a flag. */ + {"auto-tune", no_argument, NULL, OPT_AUTO_TUNE}, + {"calibrate", no_argument, NULL, 'c'}, + {"csv", optional_argument, NULL, 'C'}, + {"debug", no_argument, &debug_learning, OPT_DEBUG}, + {"extech", optional_argument, NULL, OPT_EXTECH}, + {"html", optional_argument, NULL, 'r'}, + {"iteration", optional_argument, NULL, 'i'}, + {"quiet", no_argument, NULL, 'q'}, + {"sample", optional_argument, NULL, 's'}, + {"time", optional_argument, NULL, 't'}, + {"workload", optional_argument, NULL, 'w'}, + {"version", no_argument, NULL, 'V'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0} +}; + +static void print_version() +{ + printf(_("PowerTOP version " PACKAGE_VERSION "\n")); +} + +static bool set_refresh_timeout() +{ + static char buf[4]; + mvprintw(1, 0, "%s (currently %u): ", _("Set refresh time out"), time_out); + memset(buf, '\0', sizeof(buf)); + get_user_input(buf, sizeof(buf) - 1); + show_tab(0); + unsigned time = strtoul(buf, NULL, 0); + if (!time) return 0; + if (time > 32) time = 32; + time_out = time; + return 1; +} + +static void print_usage() +{ + printf("%s\n\n", _("Usage: powertop [OPTIONS]")); + printf(" --auto-tune\t %s\n", _("sets all tunable options to their GOOD setting")); + printf(" -c, --calibrate\t %s\n", _("runs powertop in calibration mode")); + printf(" -C, --csv%s\t %s\n", _("[=filename]"), _("generate a csv report")); + printf(" --debug\t\t %s\n", _("run in \"debug\" mode")); + printf(" --extech%s\t %s\n", _("[=devnode]"), _("uses an Extech Power Analyzer for measurements")); + printf(" -r, --html%s\t %s\n", _("[=filename]"), _("generate a html report")); + printf(" -i, --iteration%s\n", _("[=iterations] number of times to run each test")); + printf(" -q, --quiet\t\t %s\n", _("suppress stderr output")); + printf(" -s, --sample%s\t %s\n", _("[=seconds]"), _("interval for power consumption measurement")); + printf(" -t, --time%s\t %s\n", _("[=seconds]"), _("generate a report for 'x' seconds")); + printf(" -w, --workload%s %s\n", _("[=workload]"), _("file to execute for workload")); + printf(" -V, --version\t\t %s\n", _("print version information")); + printf(" -h, --help\t\t %s\n", _("print this help menu")); + printf("\n"); + printf("%s\n\n", _("For more help please refer to the 'man 8 powertop'")); +} + +static void do_sleep(int seconds) +{ + time_t target; + int delta; + + if (!ncurses_initialized()) { + sleep(seconds); + return; + } + target = time(NULL) + seconds; + delta = seconds; + do { + int c; + usleep(6000); + halfdelay(delta * 10); + + c = getch(); + switch (c) { + case KEY_BTAB: + show_prev_tab(); + break; + case '\t': + show_next_tab(); + break; + case KEY_RIGHT: + cursor_right(); + break; + case KEY_LEFT: + cursor_left(); + break; + case KEY_NPAGE: + case KEY_DOWN: + cursor_down(); + break; + case KEY_PPAGE: + case KEY_UP: + cursor_up(); + break; + case ' ': + case '\n': + cursor_enter(); + break; + case 's': + if (set_refresh_timeout()) + return; + break; + case 'r': + window_refresh(); + return; + case KEY_EXIT: + case 'q': + case 27: // Escape + leave_powertop = 1; + return; + } + + delta = target - time(NULL); + if (delta <= 0) + break; + + } while (1); +} + +extern "C" { + static volatile bool end_thread; + void* measure_background_thread(void *arg) + { + int sleep_time = *((int *) arg); + while (!end_thread) { + do_sleep(sleep_time); + global_sample_power(); + } + return 0; + } +} + +void one_measurement(int seconds, int sample_interval, char *workload) +{ + create_all_usb_devices(); + start_power_measurement(); + devices_start_measurement(); + start_devfreq_measurement(); + start_process_measurement(); + start_cpu_measurement(); + + if (workload && workload[0]) { + pthread_t thread = 0UL; + end_thread = false; + if (pthread_create(&thread, NULL, measure_background_thread, &sample_interval)) + fprintf(stderr, "ERROR: workload measurement thread creation failed\n"); + + if (system(workload)) + fprintf(stderr, _("Unknown issue running workload!\n")); + + if (thread) + { + end_thread = true; + pthread_join( thread, NULL); + } + global_sample_power(); + } else { + while (seconds > 0) + { + do_sleep(sample_interval > seconds ? seconds : sample_interval); + seconds -= sample_interval; + global_sample_power(); + } + } + end_cpu_measurement(); + end_process_measurement(); + collect_open_devices(); + end_devfreq_measurement(); + devices_end_measurement(); + end_power_measurement(); + + process_cpu_data(); + process_process_data(); + + /* output stats */ + process_update_display(); + report_summary(); + w_display_cpu_cstates(); + w_display_cpu_pstates(); + if (reporttype != REPORT_OFF) { + report_display_cpu_cstates(); + report_display_cpu_pstates(); + } + report_process_update_display(); + tuning_update_display(); + wakeup_update_display(); + end_process_data(); + + global_power(); + compute_bundle(); + + show_report_devices(); + report_show_open_devices(); + + report_devices(); + display_devfreq_devices(); + report_devfreq_devices(); + ahci_create_device_stats_table(); + store_results(measurement_time); + end_cpu_data(); +} + +void out_of_memory() +{ + reset_display(); + printf("%s...\n",_("PowerTOP is out of memory. PowerTOP is Aborting")); + abort(); +} + +void make_report(int time, char *workload, int iterations, int sample_interval, char *file) +{ + + /* one to warm up everything */ + fprintf(stderr, _("Preparing to take measurements\n")); + utf_ok = 0; + one_measurement(1, sample_interval, NULL); + + if (!workload[0]) + fprintf(stderr, _("Taking %d measurement(s) for a duration of %d second(s) each.\n"),iterations,time); + else + fprintf(stderr, _("Measuring workload %s.\n"), workload); + for (int i=0; i != iterations; i++){ + init_report_output(file, iterations); + initialize_tuning(); + initialize_wakeup(); + /* and then the real measurement */ + one_measurement(time, sample_interval, workload); + report_show_tunables(); + report_show_wakeup(); + finish_report_output(); + clear_tuning(); + } + /* and wrap up */ + learn_parameters(50, 0); + save_all_results("saved_results.powertop"); + save_parameters("saved_parameters.powertop"); + end_pci_access(); + exit(0); +} + +static void checkroot() { + int uid; + uid = getuid(); + + if (uid != 0) { + printf(_("PowerTOP " PACKAGE_VERSION " must be run with root privileges.\n")); + printf(_("exiting...\n")); + exit(EXIT_FAILURE); + } + +} + +static int get_nr_open(void) { + int nr_open = NR_OPEN_DEF; + ifstream file; + + file.open("/proc/sys/fs/nr_open", ios::in); + if (file) { + file >> nr_open; + file.close(); + } + return nr_open; +} + +static void powertop_init(int auto_tune) +{ + static char initialized = 0; + int ret; + struct statfs st_fs; + struct rlimit rlmt; + + if (initialized) + return; + + checkroot(); + + rlmt.rlim_cur = rlmt.rlim_max = get_nr_open(); + setrlimit (RLIMIT_NOFILE, &rlmt); + + if (system("/sbin/modprobe cpufreq_stats > /dev/null 2>&1")) + fprintf(stderr, _("modprobe cpufreq_stats failed\n")); +#if defined(__i386__) || defined(__x86_64__) + if (system("/sbin/modprobe msr > /dev/null 2>&1")) + fprintf(stderr, _("modprobe msr failed\n")); +#endif + statfs("/sys/kernel/debug", &st_fs); + + if (st_fs.f_type != (long) DEBUGFS_MAGIC) { + if (access("/bin/mount", X_OK) == 0) { + ret = system("/bin/mount -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1"); + } else { + ret = system("mount -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1"); + } + if (ret != 0) { + if (!auto_tune) { + fprintf(stderr, _("Failed to mount debugfs!\n")); + fprintf(stderr, _("exiting...\n")); + exit(EXIT_FAILURE); + } else { + fprintf(stderr, _("Failed to mount debugfs!\n")); + fprintf(stderr, _("Should still be able to auto tune...\n")); + } + } + } + + srand(time(NULL)); + + if (access("/var/cache/", W_OK) == 0) + mkdir("/var/cache/powertop", 0600); + else + mkdir("/data/local/powertop", 0600); + + load_results("saved_results.powertop"); + load_parameters("saved_parameters.powertop"); + + enumerate_cpus(); + create_all_devices(); + create_all_devfreq_devices(); + detect_power_meters(); + + register_parameter("base power", 100, 0.5); + register_parameter("cpu-wakeups", 39.5); + register_parameter("cpu-consumption", 1.56); + register_parameter("gpu-operations", 0.5576); + register_parameter("disk-operations-hard", 0.2); + register_parameter("disk-operations", 0.0); + register_parameter("xwakes", 0.1); + + load_parameters("saved_parameters.powertop"); + + initialized = 1; +} + +void clean_shutdown() +{ + close_results(); + clean_open_devices(); + clear_all_devices(); + clear_all_devfreq(); + clear_all_cpus(); + + return; +} + + +int main(int argc, char **argv) +{ + int option_index; + int c; + char filename[PATH_MAX]; + char workload[PATH_MAX] = {0}; + int iterations = 1, auto_tune = 0, sample_interval = 5; + + set_new_handler(out_of_memory); + + setlocale (LC_ALL, ""); + +#ifdef ENABLE_NLS + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); +#endif + ui_notify_user = ui_notify_user_ncurses; + while (1) { /* parse commandline options */ + c = getopt_long(argc, argv, "cC::r::i:qt:w:Vh", long_options, &option_index); + /* Detect the end of the options. */ + if (c == -1) + break; + switch (c) { + case OPT_AUTO_TUNE: + auto_tune = 1; + leave_powertop = 1; + ui_notify_user = ui_notify_user_console; + break; + case 'c': + powertop_init(0); + calibrate(); + break; + case 'C': /* csv report */ + reporttype = REPORT_CSV; + snprintf(filename, sizeof(filename), "%s", optarg ? optarg : "powertop.csv"); + if (!strlen(filename)) + { + fprintf(stderr, _("Invalid CSV filename\n")); + exit(1); + } + break; + case OPT_DEBUG: + /* implemented using getopt_long(3) flag */ + break; + case OPT_EXTECH: /* Extech power analyzer support */ + checkroot(); + extech_power_meter(optarg ? optarg : "/dev/ttyUSB0"); + break; + case 'r': /* html report */ + reporttype = REPORT_HTML; + snprintf(filename, sizeof(filename), "%s", optarg ? optarg : "powertop.html"); + if (!strlen(filename)) + { + fprintf(stderr, _("Invalid HTML filename\n")); + exit(1); + } + break; + case 'i': + iterations = (optarg ? atoi(optarg) : 1); + break; + case 'q': + if (freopen("/dev/null", "a", stderr)) + fprintf(stderr, _("Quiet mode failed!\n")); + break; + case 's': + sample_interval = (optarg ? atoi(optarg) : 5); + break; + case 't': + time_out = (optarg ? atoi(optarg) : 20); + break; + case 'w': /* measure workload */ + snprintf(workload, sizeof(workload), "%s", optarg ? optarg : ""); + break; + case 'V': + print_version(); + exit(0); + break; + case 'h': + print_usage(); + exit(0); + break; + case '?': /* Unknown option */ + /* getopt_long already printed an error message. */ + exit(1); + break; + } + } + + powertop_init(auto_tune); + + if (reporttype != REPORT_OFF) + make_report(time_out, workload, iterations, sample_interval, filename); + + if (debug_learning) + printf("Learning debugging enabled\n"); + + learn_parameters(250, 0); + save_parameters("saved_parameters.powertop"); + + + if (debug_learning) { + learn_parameters(1000, 1); + dump_parameter_bundle(); + end_pci_access(); + exit(0); + } + if (!auto_tune) + init_display(); + + initialize_devfreq(); + initialize_tuning(); + initialize_wakeup(); + /* first one is short to not let the user wait too long */ + one_measurement(1, sample_interval, NULL); + + if (!auto_tune) { + tuning_update_display(); + show_tab(0); + } else { + auto_toggle_tuning(); + } + + while (!leave_powertop) { + if (!auto_tune) + show_cur_tab(); + one_measurement(time_out, sample_interval, NULL); + learn_parameters(15, 0); + } + if (!auto_tune) + endwin(); + fprintf(stderr, "%s\n", _("Leaving PowerTOP")); + + end_process_data(); + clear_process_data(); + end_cpu_data(); + clear_cpu_data(); + + save_all_results("saved_results.powertop"); + save_parameters("saved_parameters.powertop"); + learn_parameters(500, 0); + save_parameters("saved_parameters.powertop"); + end_pci_access(); + clear_tuning(); + reset_display(); + + clean_shutdown(); + + return 0; +} diff --git a/src/measurement/acpi.cpp b/src/measurement/acpi.cpp new file mode 100644 index 0000000..572852c --- /dev/null +++ b/src/measurement/acpi.cpp @@ -0,0 +1,213 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "measurement.h" +#include "acpi.h" +#include <iostream> +#include <fstream> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include "../lib.h" + +using namespace std; + +acpi_power_meter::acpi_power_meter(const char *acpi_name) +{ + rate = 0.0; + capacity = 0.0; + voltage = 0.0; + pt_strcpy(battery_name, acpi_name); +} + +/* +present: yes +capacity state: ok +charging state: discharging +present rate: 8580 mW +remaining capacity: 34110 mWh +present voltage: 12001 mV +*/ + +void acpi_power_meter::measure(void) +{ + char filename[PATH_MAX]; + char line[4096]; + ifstream file; + + double _rate = 0; + double _capacity = 0; + double _voltage = 0; + + char rate_units[16]; + char capacity_units[16]; + char voltage_units[16]; + + rate_units[0] = 0; + capacity_units[0] = 0; + voltage_units[0] = 0; + + rate = 0; + voltage = 0; + capacity = 0; + + snprintf(filename, sizeof(filename), "/proc/acpi/battery/%s/state", battery_name); + + file.open(filename, ios::in); + if (!file) + return; + + while (file) { + char *c; + file.getline(line, sizeof(line)); + + if (strstr(line, "present:") && (strstr(line, "yes") == NULL)) { + return; + } + if (strstr(line, "charging state:") && (strstr(line, "discharging") == NULL)) { + return; /* not discharging */ + } + if (strstr(line, "present rate:")) { + c = strchr(line, ':'); + c++; + while (*c == ' ') c++; + _rate = strtoull(c, NULL, 10); + c = strchr(c, ' '); + if (c) { + c++; + pt_strcpy(rate_units, c); + } else { + _rate = 0; + strcpy(rate_units, "Unknown"); + } + + } + if (strstr(line, "remaining capacity:")) { + c = strchr(line, ':'); + c++; + while (*c == ' ') c++; + _capacity = strtoull(c, NULL, 10); + c = strchr(c, ' '); + if (c) { + c++; + pt_strcpy(capacity_units, c); + } else { + _capacity = 0; + strcpy(capacity_units, "Unknown"); + } + } + if (strstr(line, "present voltage:")) { + c = strchr(line, ':'); + c++; + while (*c == ' ') c++; + _voltage = strtoull(c, NULL, 10); + c = strchr(c, ' '); + if (c) { + c++; + pt_strcpy(voltage_units, c); + } else { + _voltage = 0; + strcpy(voltage_units, "Unknown"); + } + } + } + file.close(); + + /* BIOS report random crack-inspired units. Lets try to get to the Si-system units */ + + if (strcmp(voltage_units, "mV") == 0) { + _voltage = _voltage / 1000.0; + strcpy(voltage_units, "V"); + } + + if (strcmp(rate_units, "mW") == 0) { + _rate = _rate / 1000.0; + strcpy(rate_units, "W"); + } + + if (strcmp(rate_units, "mA") == 0) { + _rate = _rate / 1000.0; + strcpy(rate_units, "A"); + } + + if (strcmp(capacity_units, "mAh") == 0) { + _capacity = _capacity / 1000.0; + strcpy(capacity_units, "Ah"); + } + if (strcmp(capacity_units, "mWh") == 0) { + _capacity = _capacity / 1000.0; + strcpy(capacity_units, "Wh"); + } + if (strcmp(capacity_units, "Wh") == 0) { + _capacity = _capacity * 3600.0; + strcpy(capacity_units, "J"); + } + + + if (strcmp(capacity_units, "Ah") == 0 && strcmp(voltage_units, "V") == 0) { + _capacity = _capacity * 3600.0 * _voltage; + strcpy(capacity_units, "J"); + } + + if (strcmp(rate_units, "A") == 0 && strcmp(voltage_units, "V")==0 ) { + _rate = _rate * _voltage; + strcpy(rate_units, "W"); + } + + + + + if (strcmp(capacity_units, "J") == 0) + capacity = _capacity; + else + capacity = 0.0; + + if (strcmp(rate_units, "W")==0) + rate = _rate; + else + rate = 0.0; + + if (strcmp(voltage_units, "V")==0) + voltage = _voltage; + else + voltage = 0.0; +} + + +void acpi_power_meter::end_measurement(void) +{ + measure(); +} + +void acpi_power_meter::start_measurement(void) +{ + /* ACPI battery state is a lagging indication, lets only measure at the end */ +} + + +double acpi_power_meter::power(void) +{ + return rate; +} diff --git a/src/measurement/acpi.h b/src/measurement/acpi.h new file mode 100644 index 0000000..25bbe04 --- /dev/null +++ b/src/measurement/acpi.h @@ -0,0 +1,46 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_ACPI_H +#define __INCLUDE_GUARD_ACPI_H + +#include "measurement.h" + +class acpi_power_meter: public power_meter { + char battery_name[256]; + + double capacity; + double rate; + double voltage; + void measure(void); +public: + acpi_power_meter(const char *_battery_name); + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double power(void); + virtual double dev_capacity(void) { return capacity; }; +}; + +#endif diff --git a/src/measurement/extech.cpp b/src/measurement/extech.cpp new file mode 100644 index 0000000..867aca7 --- /dev/null +++ b/src/measurement/extech.cpp @@ -0,0 +1,354 @@ +/* + * extech - Program for controlling the extech Device + * This file is part of PowerTOP + * + * Based on earlier client by Patrick Mochel for Wattsup Pro device + * Copyright (c) 2005 Patrick Mochel + * Copyright (c) 2006 Intel Corporation + * Copyright (c) 2011 Intel Corporation + * + * Authors: + * Patrick Mochel + * Venkatesh Pallipadi + * Arjan van de Ven + * + * Thanks to Rajiv Kapoor for finding out the DTR, RTS line bits issue below + * Without that this program would never work. + * + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <termios.h> +#include <ctype.h> +#include <getopt.h> +#include <time.h> +#include <signal.h> + +#include <sys/types.h> +#include <sys/ioctl.h> + +#include <sys/stat.h> + +#include "measurement.h" +#include "extech.h" +#include "../lib.h" +#include <iostream> +#include <fstream> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +using namespace std; + +struct packet { + char buf[256]; + char op[32]; + double watts; + int len; +}; + + +static int open_device(const char *device_name) +{ + struct stat s; + int ret; + + ret = stat(device_name, &s); + if (ret < 0) + return -1; + + if (!S_ISCHR(s.st_mode)) + return -1; + + ret = access(device_name, R_OK | W_OK); + if (ret) + return -1; + + ret = open(device_name, O_RDWR | O_NONBLOCK | O_NOCTTY); + if (ret < 0) + return -1; + + return ret; +} + + +static int setup_serial_device(int dev_fd) +{ + struct termios t; + int ret; + int flgs; + + ret = tcgetattr(dev_fd, &t); + if (ret) + return ret; + + cfmakeraw(&t); + cfsetispeed(&t, B9600); + cfsetospeed(&t, B9600); + tcflush(dev_fd, TCIFLUSH); + + t.c_iflag = IGNPAR; + t.c_cflag = B9600 | CS8 | CREAD | CLOCAL; + t.c_oflag = 0; + t.c_lflag = 0; + t.c_cc[VMIN] = 2; + t.c_cc[VTIME] = 0; + + t.c_iflag &= ~(IXON | IXOFF | IXANY); + t.c_oflag &= ~(IXON | IXOFF | IXANY); + + ret = tcsetattr(dev_fd, TCSANOW, &t); + + if (ret) + return ret; + + /* + * Root caused by Rajiv Kapoor. Without this extech reads + * will fail + */ + + /* get DTR and RTS line bits settings */ + ioctl(dev_fd, TIOCMGET, &flgs); + + /* set DTR to 1 and RTS to 0 */ + flgs |= TIOCM_DTR; + flgs &= ~TIOCM_RTS; + ioctl(dev_fd, TIOCMSET, &flgs); + + return 0; +} + + +static unsigned int decode_extech_value(unsigned char byt3, unsigned char byt4, char *a) +{ + unsigned int input = ((unsigned int)byt4 << 8) + byt3; + unsigned int i; + unsigned int idx; + unsigned char revnum[] = { 0x0, 0x8, 0x4, 0xc, + 0x2, 0xa, 0x6, 0xe, + 0x1, 0x9, 0x5, 0xd, + 0x3, 0xb, 0x7, 0xf}; + unsigned char revdec[] = { 0x0, 0x2, 0x1, 0x3}; + + unsigned int digit_map[] = {0x2, 0x3c, 0x3c0, 0x3c00}; + unsigned int digit_shift[] = {1, 2, 6, 10}; + + unsigned int sign; + unsigned int decimal; + + /* this is basically BCD encoded floating point... but kinda weird */ + + decimal = (input & 0xc000) >> 14; + decimal = revdec[decimal]; + + sign = input & 0x1; + + idx = 0; + if (sign) + a[idx++] = '+'; + else + a[idx++] = '-'; + + /* first digit is only one or zero */ + a[idx] = '0'; + if ((input & digit_map[0]) >> digit_shift[0]) + a[idx] += 1; + + idx++; + /* Reverse the remaining three digits and store in the array */ + for (i = 1; i < 4; i++) { + int dig = ((input & digit_map[i]) >> digit_shift[i]); + dig = revnum[dig]; + if (dig > 0xa) + goto error_exit; + + a[idx++] = '0' + dig; + } + + /* Fit the decimal point where appropriate */ + for (i = 0; i < decimal; i++) + a[idx - i] = a[idx - i - 1]; + + a[idx - decimal] = '.'; + a[++idx] = '0'; + a[++idx] = '\0'; + + return 0; +error_exit: + return -1; +} + +static int parse_packet(struct packet * p) +{ + int i; + int ret; + + p->buf[p->len] = '\0'; + + /* + * First character in 5 character block should be '02' + * Fifth character in 5 character block should be '03' + */ + for (i = 0; i < 4; i++) { + if (p->buf[i * 0] != 2 || p->buf[i * 0 + 4] != 3) { + printf("Invalid packet\n"); + return -1; + } + } + + for (i = 0; i < 1; i++) { + ret = decode_extech_value(p->buf[5 * i + 2], + p->buf[5 * i + 3], + &(p->op[8 * i])); + if (ret) { + printf("Invalid packet, conversion failed\n"); + return -1; + } + p->watts = strtod( &(p->op[8 * i]), NULL); + } + return 0; +} + + +static double extech_read(int fd) +{ + struct packet p; + fd_set read_fd; + struct timeval tv; + int ret; + + if (fd < 0) + return 0.0; + + FD_ZERO(&read_fd); + FD_SET(fd, &read_fd); + + tv.tv_sec = 0; + tv.tv_usec = 500000; + + memset(&p, 0, sizeof(p)); + + ret = select(fd + 1, &read_fd, NULL, NULL, &tv); + if (ret <= 0) + return -1; + + ret = read(fd, &p.buf, 250); + if (ret < 0) + return ret; + p.len = ret; + + if (!parse_packet(&p)) + return p.watts; + + return -1000.0; +} + +extech_power_meter::extech_power_meter(const char *extech_name) +{ + rate = 0.0; + pt_strcpy(dev_name, extech_name); + int ret; + + fd = open_device(dev_name); + if (fd < 0) + return; + + ret = setup_serial_device(fd); + if (ret) { + close(fd); + fd = -1; + return; + } +} + + +void extech_power_meter::measure(void) +{ + /* trigger the extech to send data */ + if(write(fd, " ", 1) == -1) + printf("Error: %s\n", strerror(errno)); + + rate = extech_read(fd); + +} + +void extech_power_meter::sample(void) +{ + ssize_t ret; + struct timespec tv; + + tv.tv_sec = 0; + tv.tv_nsec = 200000000; + while (!end_thread) { + nanosleep(&tv, NULL); + /* trigger the extech to send data */ + ret = write(fd, " ", 1); + if (ret < 0) + continue; + + sum += extech_read(fd); + samples++; + + } +} + +extern "C" +{ + void* thread_proc(void *arg) + { + class extech_power_meter *parent; + parent = (class extech_power_meter*)arg; + parent->sample(); + return 0; + } +} + +void extech_power_meter::end_measurement(void) +{ + end_thread = 1; + pthread_join( thread, NULL); + if (samples){ + rate = sum / samples; + } + else + measure(); +} + +void extech_power_meter::start_measurement(void) +{ + end_thread = 0; + sum = samples = 0; + + if (pthread_create(&thread, NULL, thread_proc, this)) + fprintf(stderr, "ERROR: extech measurement thread creation failed\n"); + +} + + +double extech_power_meter::power(void) +{ + return rate; +} diff --git a/src/measurement/extech.h b/src/measurement/extech.h new file mode 100644 index 0000000..b7b330a --- /dev/null +++ b/src/measurement/extech.h @@ -0,0 +1,51 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_EXTECH_H +#define __INCLUDE_GUARD_EXTECH_H + +#include <pthread.h> +#include "measurement.h" + +class extech_power_meter: public power_meter { + char dev_name[256]; + int fd; + + double rate; + void measure(void); + double sum; + int samples; + int end_thread; + pthread_t thread; +public: + extech_power_meter(const char *_dev_name); + virtual void start_measurement(void); + virtual void end_measurement(void); + virtual void sample(void); + + virtual double power(void); + virtual double dev_capacity(void) { return 0.0; }; +}; + +#endif diff --git a/src/measurement/measurement.cpp b/src/measurement/measurement.cpp new file mode 100644 index 0000000..caee24e --- /dev/null +++ b/src/measurement/measurement.cpp @@ -0,0 +1,188 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "measurement.h" +#include "acpi.h" +#include "extech.h" +#include "sysfs.h" +#include "opal-sensors.h" +#include "../parameters/parameters.h" +#include "../lib.h" + +#include <string> +#include <sys/types.h> +#include <dirent.h> +#include <stdio.h> +#include <fstream> +#include <unistd.h> +#include <time.h> + +double min_power = 50000.0; + +void power_meter::start_measurement(void) +{ +} + + +void power_meter::end_measurement(void) +{ +} + + +double power_meter::power(void) +{ + return 0.0; +} + +vector<class power_meter *> power_meters; + +static struct timespec tlast; + +void start_power_measurement(void) +{ + unsigned int i; + clock_gettime(CLOCK_REALTIME, &tlast); + for (i = 0; i < power_meters.size(); i++) + power_meters[i]->start_measurement(); + all_results.joules = 0.0; +} +void end_power_measurement(void) +{ + unsigned int i; + for (i = 0; i < power_meters.size(); i++) + power_meters[i]->end_measurement(); +} + +double global_power(void) +{ + bool global_discharging = false; + double total = 0.0; + unsigned int i; + + for (i = 0; i < power_meters.size(); i++) { + global_discharging |= power_meters[i]->is_discharging(); + total += power_meters[i]->power(); + } + + /* report global time left if at least one battery is discharging */ + if (!global_discharging) + return 0.0; + + all_results.power = total; + if (total < min_power && total > 0.01) + min_power = total; + return total; +} + +void global_sample_power(void) +{ + struct timespec tnow; + + clock_gettime(CLOCK_REALTIME, &tnow); + /* power * time = joules */ + all_results.joules += global_power() * \ + ( ((double)tnow.tv_sec + 1.0e-9*tnow.tv_nsec) - \ + ((double)tlast.tv_sec + 1.0e-9*tlast.tv_nsec)); + tlast = tnow; +} + +double global_joules(void) +{ + return all_results.joules; +} + +double global_time_left(void) +{ + bool global_discharging = false; + double total_capacity = 0.0; + double total_rate = 0.0; + unsigned int i; + for (i = 0; i < power_meters.size(); i++) { + global_discharging |= power_meters[i]->is_discharging(); + total_capacity += power_meters[i]->dev_capacity(); + total_rate += power_meters[i]->power(); + } + /* report global time left if at least one battery is discharging */ + if (!global_discharging) + return 0.0; + + /* return 0.0 instead of INF+ */ + if (total_rate < 0.001) + return 0.0; + return total_capacity / total_rate; +} + +void sysfs_power_meters_callback(const char *d_name) +{ + std::string type = read_sysfs_string("/sys/class/power_supply/%s/type", d_name); + + if (type != "Battery" && type != "UPS") + return; + + class sysfs_power_meter *meter; + meter = new(std::nothrow) class sysfs_power_meter(d_name); + if (meter) + power_meters.push_back(meter); +} + +void acpi_power_meters_callback(const char *d_name) +{ + class acpi_power_meter *meter; + meter = new(std::nothrow) class acpi_power_meter(d_name); + if (meter) + power_meters.push_back(meter); +} + +void sysfs_opal_sensors_callback(const char *d_name) +{ + class opal_sensors_power_meter *meter; + const char *c; + + /* Those that end in / are directories and we don't want them */ + c = strrchr(d_name, '/'); + if (c && *(c+1) == '\0') + return; + + meter = new(std::nothrow) class opal_sensors_power_meter(d_name); + if (meter) + power_meters.push_back(meter); +} + +void detect_power_meters(void) +{ + process_directory("/sys/class/power_supply", sysfs_power_meters_callback); + process_glob("/sys/devices/platform/opal-sensor/hwmon/hwmon*/power*", sysfs_opal_sensors_callback); + if (power_meters.size() == 0) { + process_directory("/proc/acpi/battery", acpi_power_meters_callback); + } +} + +void extech_power_meter(const char *devnode) +{ + class extech_power_meter *meter; + + meter = new class extech_power_meter(devnode); + + power_meters.push_back(meter); +} diff --git a/src/measurement/measurement.h b/src/measurement/measurement.h new file mode 100644 index 0000000..9a84bc2 --- /dev/null +++ b/src/measurement/measurement.h @@ -0,0 +1,71 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_MEASUREMENT_H +#define __INCLUDE_GUARD_MEASUREMENT_H + +#include <vector> + +using namespace std; + +class power_meter { + bool discharging = false; +public: + virtual ~power_meter() {}; + + virtual void start_measurement(void); + virtual void end_measurement(void); + virtual double power(void); + + virtual double dev_capacity(void) + { + return 0.0; /* in Joules */ + } + + virtual void set_discharging(bool d) + { + discharging = d; + } + + virtual bool is_discharging() + { + return discharging; + } +}; + +extern vector<class power_meter *> power_meters; + +extern void start_power_measurement(void); +extern void end_power_measurement(void); +extern double global_power(void); +extern void global_sample_power(void); +extern double global_joules(void); +extern double global_time_left(void); + +extern void detect_power_meters(void); +extern void extech_power_meter(const char *devnode); + +extern double min_power; + +#endif diff --git a/src/measurement/opal-sensors.cpp b/src/measurement/opal-sensors.cpp new file mode 100644 index 0000000..a70ec56 --- /dev/null +++ b/src/measurement/opal-sensors.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015 IBM Corp. + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Stewart Smith <stewart@linux.vnet.ibm.com> + */ +#include "measurement.h" +#include "opal-sensors.h" +#include "../lib.h" +#include <string.h> +#include <stdio.h> +#include <limits.h> + +opal_sensors_power_meter::opal_sensors_power_meter(const char *power_supply_name) +{ + strncpy(name, power_supply_name, sizeof(name)); +} + +double opal_sensors_power_meter::power(void) +{ + bool ok; + int value; + double r = 0; + + value = read_sysfs(name, &ok); + + if(ok) + r = value / 1000000.0; + return r; +} diff --git a/src/measurement/opal-sensors.h b/src/measurement/opal-sensors.h new file mode 100644 index 0000000..7962091 --- /dev/null +++ b/src/measurement/opal-sensors.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015 IBM Corp. + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Stewart Smith <stewart@linux.vnet.ibm.com> + */ +#ifndef INCLUDE_GUARD_OPAL_SENSORS_H +#define INCLUDE_GUARD_OPAL_SENSORS_H + +#include "measurement.h" +#include <limits.h> + +class opal_sensors_power_meter: public power_meter { + char name[PATH_MAX]; +public: + opal_sensors_power_meter(const char *power_supply_name); + virtual void start_measurement(void) {}; + virtual void end_measurement(void) {}; + + virtual double power(void); + virtual double dev_capacity(void) { return 0.0; } +}; + +#endif diff --git a/src/measurement/sysfs.cpp b/src/measurement/sysfs.cpp new file mode 100644 index 0000000..c5a7a12 --- /dev/null +++ b/src/measurement/sysfs.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2011 Anssi Hannula + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Anssi Hannula <anssi.hannula@iki.fi> + */ +#include "measurement.h" +#include "sysfs.h" +#include "../lib.h" +#include <string.h> +#include <stdio.h> +#include <limits.h> + +sysfs_power_meter::sysfs_power_meter(const char *power_supply_name) +{ + rate = 0.0; + capacity = 0.0; + pt_strcpy(name, power_supply_name); +} + +bool sysfs_power_meter::get_sysfs_attr(const char *attribute, int *value) +{ + char filename[PATH_MAX]; + bool ok; + + snprintf(filename, sizeof(filename), "/sys/class/power_supply/%s/%s", name, attribute); + *value = read_sysfs(filename, &ok); + + return ok; +} + +bool sysfs_power_meter::is_present() +{ + int present = 0; + + if (!get_sysfs_attr("present", &present)) + return true; /* assume always present */ + + return present; +} + +double sysfs_power_meter::get_voltage() +{ + int voltage; + + if (!get_sysfs_attr("voltage_now", &voltage)) + return -1.0; + + /* µV to V */ + return voltage / 1000000.0; +} + +bool sysfs_power_meter::set_rate_from_power() +{ + int power; + + if (!get_sysfs_attr("power_now", &power)) + return false; + + /* µW to W */ + rate = power / 1000000.0; + return true; +} + +bool sysfs_power_meter::set_rate_from_current(double voltage) +{ + int current; + + if (!get_sysfs_attr("current_now", ¤t)) + return false; + + /* current: µA + * voltage: V + * rate: W */ + rate = (current / 1000000.0) * voltage; + return true; +} + +bool sysfs_power_meter::set_capacity_from_energy() +{ + int energy; + + if (!get_sysfs_attr("energy_now", &energy)) + return false; + + /* µWh to J */ + capacity = energy / 1000000.0 * 3600.0; + return true; +} + +bool sysfs_power_meter::set_capacity_from_charge(double voltage) +{ + int charge; + + if (!get_sysfs_attr("charge_now", &charge)) + return false; + + /* charge: µAh + * voltage: V + * capacity: J */ + capacity = (charge / 1000000.0) * voltage * 3600.0; + return true; +} + +void sysfs_power_meter::measure() +{ + bool got_rate = false; + bool got_capacity = false; + + rate = 0.0; + capacity = 0.0; + this->set_discharging(false); + + if (!is_present()) + return; + /** do not jump over. we may have discharging battery */ + if (read_sysfs_string("/sys/class/power_supply/%s/status", name) == "Discharging") + this->set_discharging(true); + + got_rate = set_rate_from_power(); + got_capacity = set_capacity_from_energy(); + + if (!got_rate || !got_capacity) { + double voltage = get_voltage(); + if (voltage < 0.0) + return; + if (!got_rate) + set_rate_from_current(voltage); + if (!got_capacity) + set_capacity_from_charge(voltage); + } +} + +void sysfs_power_meter::end_measurement(void) +{ + measure(); +} + +void sysfs_power_meter::start_measurement(void) +{ + /* Battery state is generally a lagging indication, lets only measure at the end */ +} diff --git a/src/measurement/sysfs.h b/src/measurement/sysfs.h new file mode 100644 index 0000000..5b440f5 --- /dev/null +++ b/src/measurement/sysfs.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Anssi Hannula + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Anssi Hannula <anssi.hannula@iki.fi> + */ +#ifndef INCLUDE_GUARD_SYSFS_H +#define INCLUDE_GUARD_SYSFS_H + +#include "measurement.h" + +class sysfs_power_meter: public power_meter { + char name[256]; + + double capacity; + double rate; + + bool get_sysfs_attr(const char *attribute, int *value); + bool is_present(); + double get_voltage(); + + bool set_rate_from_power(); + bool set_rate_from_current(double voltage); + bool set_capacity_from_energy(); + bool set_capacity_from_charge(double voltage); + + void measure(); +public: + sysfs_power_meter(const char *power_supply_name); + virtual void start_measurement(void); + virtual void end_measurement(void); + + virtual double power(void) { return rate; } + virtual double dev_capacity(void) { return capacity; } +}; + +#endif diff --git a/src/parameters/learn.cpp b/src/parameters/learn.cpp new file mode 100644 index 0000000..aaef5a2 --- /dev/null +++ b/src/parameters/learn.cpp @@ -0,0 +1,282 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "parameters.h" +#include "../measurement/measurement.h" + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +extern int debug_learning; + +double calculate_params(struct parameter_bundle *params) +{ + unsigned int i; + + params->score = 0; + + + for (i = 0; i < past_results.size(); i++) + compute_bundle(params, past_results[i]); + + return params->score; +} + + +/* + * gradual linear convergence of non-independent variables works better if once in a while + * you make a wrong move.... + */ +static int random_disturb(int retry_left) +{ + if (retry_left < 10) + return 0; + + if ( (rand() % 500) == 7) + return 1; + return 0; +} + +static int try_zero(double value) +{ + if (value > 0.01) + if ( (rand() % 100) == 1) + return 1; + + if ( (rand() % 5) == 1) + return 1; + return 0; +} + +static unsigned int previous_measurements; + +static void weed_empties(struct parameter_bundle *best_so_far) +{ + double best_score; + unsigned int i; + + best_score = best_so_far->score; + + + for (i = 0; i < best_so_far->parameters.size(); i++) { + double orgvalue; + + orgvalue = best_so_far->parameters[i]; + + + best_so_far->parameters[i] = 0.0; + + calculate_params(best_so_far); + if (best_so_far->score > best_score) { + best_so_far->parameters[i] = orgvalue; + } else { + best_score = best_so_far->score; + } + + } + calculate_params(best_so_far); + +} + +/* leaks like a sieve */ +void learn_parameters(int iterations, int do_base_power) +{ + struct parameter_bundle *best_so_far; + double best_score = 10000000000000000.0; + int retry = iterations; + int prevparam = -1; + int locked = 0; + static unsigned int bpi = 0; + unsigned int i; + time_t start; + + /* don't start fitting anything until we have at least 1 more measurement than we have parameters */ + if (past_results.size() <= all_parameters.parameters.size()) + return; + + + +// if (past_results.size() == previous_measurements) +// return; + + precompute_valid(); + + + previous_measurements = past_results.size(); + + double delta = 0.50; + + best_so_far = &all_parameters; + + if (!bpi) + bpi = get_param_index("base power"); + + calculate_params(best_so_far); + best_score = best_so_far->score; + + delta = 0.001 / pow(0.8, iterations / 2.0); + if (iterations < 25) + delta = 0.001 / pow(0.5, iterations / 2.0); + + if (delta > 0.2) + delta = 0.2; + + if (1.0 * best_score / past_results.size() < 4 && delta > 0.05) + delta = 0.05; + + if (debug_learning) + printf("Delta starts at %5.3f\n", delta); + + if (best_so_far->parameters[bpi] > min_power * 0.9) + best_so_far->parameters[bpi] = min_power * 0.9; + + /* We want to give up a little of base power, to give other parameters room to change; + base power is the end post for everything after all + */ + if (do_base_power && !debug_learning) + best_so_far->parameters[bpi] = best_so_far->parameters[bpi] * 0.9998; + + start = time(NULL); + + while (retry--) { + int changed = 0; + int bestparam; + double newvalue = 0; + double orgscore; + double weight; + + bestparam = -1; + + if (time(NULL) - start > 1 && !debug_learning) + retry = 0; + + calculate_params(best_so_far); + orgscore = best_score = best_so_far->score; + + + for (i = 1; i < best_so_far->parameters.size(); i++) { + double value, orgvalue; + + weight = delta * best_so_far->weights[i]; + + orgvalue = value = best_so_far->parameters[i]; + if (value <= 0.001) { + value = 0.1; + } else + value = value * (1 + weight); + + if (i == bpi && value > min_power) + value = min_power; + + if (i == bpi && orgvalue > min_power) + orgvalue = min_power; + + if (value > 5000) + value = 5000; + +// printf("Trying %s %4.2f -> %4.2f\n", param.c_str(), best_so_far->parameters[param], value); + best_so_far->parameters[i] = value; + + calculate_params(best_so_far); + if (best_so_far->score < best_score || random_disturb(retry)) { + best_score = best_so_far->score; + newvalue = value; + bestparam = i; + changed++; + } + + value = orgvalue * 1 / (1 + weight); + + if (value < 0.0001) + value = 0.0; + + if (try_zero(value)) + value = 0.0; + + + if (value > 5000) + value = 5000; + + +// printf("Trying %s %4.2f -> %4.2f\n", param.c_str(), orgvalue, value); + + if (orgvalue != value) { + best_so_far->parameters[i] = value; + + calculate_params(best_so_far); + + if (best_so_far->score + 0.00001 < best_score || (random_disturb(retry) && value > 0.0)) { + best_score = best_so_far->score; + newvalue = value; + bestparam = i; + changed++; + } + } + best_so_far->parameters[i] = orgvalue; + + } + if (!changed) { + double mult; + + if (!locked) { + mult = 0.8; + if (iterations < 25) + mult = 0.5; + delta = delta * mult; + } + locked = 0; + prevparam = -1; + } else { + if (debug_learning) { + printf("Retry is %i \n", retry); + printf("delta is %5.4f\n", delta); + printf("Best parameter is %i \n", bestparam); + printf("Changing score from %4.3f to %4.3f\n", orgscore, best_score); + printf("Changing value from %4.3f to %4.3f\n", best_so_far->parameters[bestparam], newvalue); + } + best_so_far->parameters[bestparam] = newvalue; + if (prevparam == bestparam) + delta = delta * 1.1; + prevparam = bestparam; + locked = 1; + } + + if (delta < 0.001 && !locked) + break; + + if (retry % 50 == 49) + weed_empties(best_so_far); + } + + + /* now we weed out all parameters that don't have value */ + if (iterations > 50) + weed_empties(best_so_far); + + if (debug_learning) + printf("Final score %4.2f (%i points)\n", best_so_far->score / past_results.size(), (int)past_results.size()); +// dump_parameter_bundle(best_so_far); +// dump_past_results(); +} diff --git a/src/parameters/parameters.cpp b/src/parameters/parameters.cpp new file mode 100644 index 0000000..38e1752 --- /dev/null +++ b/src/parameters/parameters.cpp @@ -0,0 +1,462 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "parameters.h" +#include "../measurement/measurement.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include <vector> +#include <unistd.h> +#include <limits.h> + + +struct parameter_bundle all_parameters; +struct result_bundle all_results; + +vector <struct result_bundle *> past_results; + +map <string, int> param_index; +static int maxindex = 1; +map <string, int> result_index; +static int maxresindex = 1; + +int get_param_index(const char *name) +{ + std::map<string, int>::iterator it; + int index = 0; + + it = param_index.find(name); + if (it == param_index.end()) { + param_index[name] = ++maxindex; + index = maxindex; + } else + index = it->second; + + if (index == 0) + printf("OH BLA\n"); + return index; +} + +int get_result_index(const char *name) +{ + std::map<string, int>::iterator it; + int index = 0; + + it = result_index.find(name); + if (it == result_index.end()) { + result_index[name] = ++maxresindex; + index = maxresindex; + } else + index = it->second; + + return index; +} + + +void register_parameter(const char *name, double default_value, double weight) +{ + int index; + + index = get_param_index(name); + + if (index >= (int)all_parameters.parameters.size()) { + all_parameters.parameters.resize(index+1, 0.0); + all_parameters.weights.resize(index+1, 1.0); + } + + if (all_parameters.parameters[index] <= 0.0001) + all_parameters.parameters[index] = default_value; + + all_parameters.weights[index] = weight; +} + +void set_parameter_value(const char *name, double value, struct parameter_bundle *bundle) +{ + int index; + + index = get_param_index(name); + + if (index >= (int)bundle->parameters.size()) { + bundle->parameters.resize(index+1, 0.0); + bundle->weights.resize(index+1, 1.0); + } + + bundle->parameters[index] = value; +} + +double get_parameter_value(const char *name, struct parameter_bundle *the_bundle) +{ + unsigned int index; + index = get_param_index(name); + return get_parameter_value(index, the_bundle); +} + +double get_parameter_value(unsigned int index, struct parameter_bundle *the_bundle) +{ + if (index >= the_bundle->parameters.size()) { + fprintf(stderr, "BUG: requesting unregistered parameter %d\n", index); + return 0; + } + return the_bundle->parameters[index]; +} + +double get_parameter_weight(int index, struct parameter_bundle *the_bundle) +{ + return the_bundle->weights[index]; +} + +double get_result_value(const char *name, struct result_bundle *the_bundle) +{ + return get_result_value(get_result_index(name), the_bundle); +} + +void set_result_value(const char *name, double value, struct result_bundle *the_bundle) +{ + unsigned int index = get_result_index(name); + if (index >= the_bundle->utilization.size()) + the_bundle->utilization.resize(index+1); + the_bundle->utilization[index] = value; +} + +void set_result_value(unsigned int index, double value, struct result_bundle *the_bundle) +{ + if (index >= the_bundle->utilization.size()) + the_bundle->utilization.resize(index+1); + the_bundle->utilization[index] = value; +} + +double get_result_value(int index, struct result_bundle *the_bundle) +{ + if (!the_bundle) + return 0; + if (index >= (int) the_bundle->utilization.size()) + return 0; + return the_bundle->utilization[index]; +} + + +int result_device_exists(const char *name) +{ + unsigned int i; + for (i = 0; i < all_devices.size(); i++) { + if (strcmp(all_devices[i]->device_name(), name) == 0) + return 1; + } + return 0; +} + +void report_utilization(const char *name, double value, struct result_bundle *bundle) +{ + set_result_value(name, value, bundle); +} +void report_utilization(int index, double value, struct result_bundle *bundle) +{ + set_result_value(index, value, bundle); +} + + + +double compute_bundle(struct parameter_bundle *parameters, struct result_bundle *results) +{ + double power = 0; + unsigned int i; + + static int bpi = 0; + + if (!bpi) + bpi = get_param_index("base power"); + + for (i = 0; i < all_devices.size(); i++) + power += all_devices[i]->power_usage(results, parameters); + + parameters->actual_power = results->power; + parameters->guessed_power = power; + /* scale the squared error by the actual power so that non-idle data points weigh heavier */ + parameters->score += results->power * (power - results->power) * (power - results->power); + parameters->parameters[bpi] = power; + return power; +} + +static int precomputed_valid = 0; +void precompute_valid(void) +{ + unsigned int i; + + + for (i = 0; i < all_devices.size(); i++) { + all_devices[i]->cached_valid = all_devices[i]->power_valid(); + } + precomputed_valid = 1; +} + +double bundle_power(struct parameter_bundle *parameters, struct result_bundle *results) +{ + double power = 0; + unsigned int i; + static int bpi = 0; + + if (!bpi) + bpi = get_param_index("base power"); + + if (!precomputed_valid) + precompute_valid(); + + + power = parameters->parameters[bpi]; + + for (i = 0; i < all_devices.size(); i++) { + + if (all_devices[i]->cached_valid) + power += all_devices[i]->power_usage(results, parameters); + } + + return power; +} + + +void dump_parameter_bundle(struct parameter_bundle *para) +{ + map<string, int>::iterator it; + int index; + + printf("\n\n"); + printf("Parameter state \n"); + printf("----------------------------------\n"); + printf("Value\t\tName\n"); + for (it = param_index.begin(); it != param_index.end(); it++) { + index = it->second; + printf("%5.2f\t\t%s (%i)\n", para->parameters[index], it->first.c_str(), index); + } + + printf("\n"); + printf("Score: %5.1f (%5.1f)\n", sqrt(para->score / (0.001 + past_results.size()) / average_power()), para->score); + printf("Guess: %5.1f\n", para->guessed_power); + printf("Actual: %5.1f\n", para->actual_power); + + printf("----------------------------------\n"); +} + +void dump_result_bundle(struct result_bundle *res) +{ + map<string, int>::iterator it; + unsigned int index; + + printf("\n\n"); + printf("Utilisation state \n"); + printf("----------------------------------\n"); + printf("Value\t\tName\n"); + for (it = result_index.begin(); it != result_index.end(); it++) { + index = get_result_index(it->first.c_str()); + printf("%5.2f%%\t\t%s(%i)\n", res->utilization[index], it->first.c_str(), index); + } + + printf("\n"); + printf("Power: %5.1f\n", res->power); + + printf("----------------------------------\n"); +} + +struct result_bundle * clone_results(struct result_bundle *bundle) +{ + struct result_bundle *b2; + map<string, double>::iterator it; + unsigned int i; + + b2 = new struct result_bundle; + + if (!b2) + return NULL; + + b2->power = bundle->power; + b2->utilization.resize(bundle->utilization.size()); + + for (i = 0; i < bundle->utilization.size(); i++) { + b2->utilization[i] = bundle->utilization[i]; + } + + return b2; +} + + +struct parameter_bundle * clone_parameters(struct parameter_bundle *bundle) +{ + struct parameter_bundle *b2; + unsigned int i; + + b2 = new struct parameter_bundle; + + if (!b2) + return NULL; + + b2->score = 0; + b2->guessed_power = 0; + b2->actual_power = bundle->actual_power; + b2->parameters.resize(bundle->parameters.size()); + for (i = 0; i < bundle->parameters.size(); i++) { + b2->parameters[i] = bundle->parameters[i]; + } + + return b2; +} + + +void store_results(double duration) +{ + if (duration < 5) + return; + global_power(); + if (all_results.power > 0.01) { + unsigned int overflow_index; + overflow_index = 50 + (rand() % MAX_KEEP); + if (past_results.size() >= MAX_PARAM) { + /* memory leak, must free old one first */ + past_results[overflow_index] = clone_results(&all_results); + } else { + past_results.push_back(clone_results(&all_results)); + } + if ((past_results.size() % 10) == 0) + save_all_results("saved_results.powertop"); + } + +} + + + +void dump_past_results(void) +{ + unsigned int j; + unsigned int i; + struct result_bundle *result; + + for (j = 0; j < past_results.size(); j+=10) { + printf("Est "); + for (i = j; i < past_results.size() && i < j + 10; i++) { + result = past_results[i]; + printf("%6.2f ", bundle_power(&all_parameters, result)); + } + printf("\n"); + printf("Actual "); + for (i = j; i < past_results.size() && i < j + 10; i++) { + result = past_results[i]; + printf("%6.2f ", result->power); + } + printf("\n\n"); + } +} + +double average_power(void) +{ + double sum = 0.0; + unsigned int i; + for (i = 0; i < past_results.size(); i++) + sum += past_results[i]->power; + + if (past_results.size()) + sum = sum / past_results.size() + 0.0001; + else + sum = 0.0001; + return sum; +} + +int utilization_power_valid(const char *u) +{ + unsigned int i; + unsigned int index; + double first_value; + + index = get_result_index(u); + if (index <= 0) + return 0; + + first_value = past_results[0]->utilization[index]; + for (i = 1; i < past_results.size(); i++) { + if (get_result_value(index, past_results[i]) < first_value - 0.0001) + return 1; + if (get_result_value(index, past_results[i]) > first_value + 0.0001) + return 1; + } + + return 0; +} + +int utilization_power_valid(int index) +{ + unsigned int i; + double first_value; + + if (index <= 0) + return 0; + + if (past_results.size() == 0) + return 0; + + if (index >= (int)past_results[0]->utilization.size()) + return 0; + first_value = past_results[0]->utilization[index]; + for (i = 1; i < past_results.size(); i++) { + if (get_result_value(index, past_results[i]) < first_value - 0.0001) + return 1; + if (get_result_value(index, past_results[i]) > first_value + 0.0001) + return 1; + } + + return 0; +} + + +/* force power data to be valid to the rest of the system */ +int global_power_override = 0; +int global_run_times=0; +/* + * only report power numbers once we have 3* more measurements than + * we have parameters; anything less and our model fit is highly suspect + */ +int global_power_valid(void) +{ + if (past_results.size() > 3 * all_parameters.parameters.size()) + return 1; + + if (past_results.size() > 0 && global_run_times < 1){ + printf("To show power estimates do %ld measurement(s) connected to battery only\n", + (3 * all_parameters.parameters.size()) - past_results.size()); + global_run_times += 1; + } + + return global_power_override; +} + +/* find the directory to store powertop results/parameters based on distribution*/ +char* get_param_directory(const char *filename) +{ + static char tempfilename[PATH_MAX]; + + if (access("/var/cache/powertop", W_OK ) == 0) + snprintf(tempfilename, sizeof(tempfilename), "/var/cache/powertop/%s", filename); + if (access("/data/local/powertop", W_OK ) == 0) + snprintf(tempfilename, sizeof(tempfilename), "/data/local/powertop/%s", filename); + + return tempfilename; +}; diff --git a/src/parameters/parameters.h b/src/parameters/parameters.h new file mode 100644 index 0000000..1781a0e --- /dev/null +++ b/src/parameters/parameters.h @@ -0,0 +1,123 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_PARAMETERS_H_ +#define __INCLUDE_GUARD_PARAMETERS_H_ + + +#include <map> +#include <vector> +#include <string> + +#include "string.h" +#include "../devices/device.h" +#include "../lib.h" + +using namespace std; + +#define MAX_KEEP 700 +#define MAX_PARAM 750 + + +struct parameter_bundle +{ + double score; + double guessed_power; + double actual_power; + + vector<double> parameters; + vector<double> weights; +}; + +extern struct parameter_bundle all_parameters; +extern map <string, int> param_index; +extern map <string, int> result_index; + +extern int get_param_index(const char *param); +extern int get_result_index(const char *param); + + +extern void register_parameter(const char *name, double default_value = 0.00, double weight = 1.0); +extern double get_parameter_value(const char *name, struct parameter_bundle *bundle = &all_parameters); +extern double get_parameter_value(unsigned int index, struct parameter_bundle *bundle = &all_parameters); +extern void set_parameter_value(const char *name, double value, struct parameter_bundle *bundle = &all_parameters); + + +struct result_bundle +{ + double joules; + double power; + vector <double> utilization; /* device name, device utilization %age */ +}; + +extern struct result_bundle all_results; +extern vector <struct result_bundle *> past_results; + +extern double get_result_value(const char *name, struct result_bundle *bundle = &all_results); +extern double get_result_value(int index, struct result_bundle *bundle = &all_results); + +extern void set_result_value(const char *name, double value, struct result_bundle *bundle = &all_results); + + +extern int result_device_exists(const char *name); + +extern void report_utilization(const char *name, double value, struct result_bundle *bundle = &all_results); +extern void report_utilization(int index, double value, struct result_bundle *bundle = &all_results); + + +extern void precompute_valid(void); + +extern double compute_bundle(struct parameter_bundle *parameters = &all_parameters, struct result_bundle *results = &all_results); + + +void dump_parameter_bundle(struct parameter_bundle *patameters = &all_parameters); +void dump_result_bundle(struct result_bundle *res = &all_results); + +extern struct result_bundle * clone_results(struct result_bundle *bundle); +extern struct parameter_bundle * clone_parameters(struct parameter_bundle *bundle); + +extern void store_results(double duration); +extern void learn_parameters(int iterations, int do_base_power); +extern char *get_param_directory(const char *filename); +extern void save_all_results(const char *filename = "saved_results.powertop"); +extern void close_results(void); +extern void load_results(const char *filename); +extern void save_parameters(const char *filename); +extern void load_parameters(const char *filename); + +extern void dump_past_results(void); +extern double bundle_power(struct parameter_bundle *parameters, struct result_bundle *results); + +extern double average_power(void); + +extern int utilization_power_valid(const char *u); +extern int utilization_power_valid(int index); +extern double calculate_params(struct parameter_bundle *params = &all_parameters); +int global_power_valid(void); + + +extern int global_power_override; + + +#endif diff --git a/src/parameters/persistent.cpp b/src/parameters/persistent.cpp new file mode 100644 index 0000000..0711b4d --- /dev/null +++ b/src/parameters/persistent.cpp @@ -0,0 +1,202 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> +#include <iomanip> +#include <stdlib.h> + +#include "parameters.h" +#include "../measurement/measurement.h" + +using namespace std; + +void save_all_results(const char *filename) +{ + ofstream file; + unsigned int i; + struct result_bundle *bundle; + char* pathname; + + pathname = get_param_directory(filename); + + file.open(pathname, ios::out); + if (!file) { + cout << _("Cannot save to file") << " " << pathname << "\n"; + return; + } + for (i = 0; i < past_results.size(); i++) { + bundle = past_results[i]; + map<string, int>::iterator it; + file << setiosflags(ios::fixed) << setprecision(5) << bundle->power << "\n"; + + for (it = result_index.begin(); it != result_index.end(); it++) { + file << it->first << "\t" << setprecision(5) << get_result_value(it->second, bundle) << "\n"; + } + file << ":\n"; + } + + file.close(); + +} + +void close_results() +{ + for (unsigned int i = 0; i < past_results.size(); i++) { + delete past_results[i]; + } + + past_results.clear(); + return; +} + +void load_results(const char *filename) +{ + ifstream file; + char line[4096]; + char *c1; + struct result_bundle *bundle; + int first = 1; + unsigned int count = 0; + char* pathname; + int bundle_saved = 0; + + pathname = get_param_directory(filename); + + file.open(pathname, ios::in); + if (!file) { + cout << _("Cannot load from file") << " " << pathname << "\n"; + return; + } + + bundle = new struct result_bundle; + + while (file) { + double d; + if (first) { + file.getline(line, 4096); + if (strlen(line)>0) { + sscanf(line, "%lf", &bundle->power); + if (bundle->power < min_power) + min_power = bundle->power; + } + first = 0; + continue; + } + file.getline(line, 4096); + if (strlen(line) < 3) { + int overflow_index; + + bundle_saved = 1; + overflow_index = 50 + (rand() % MAX_KEEP); + if (past_results.size() >= MAX_PARAM) { + /* memory leak, must free old one first */ + past_results[overflow_index] = bundle; + } else { + past_results.push_back(bundle); + } + bundle = new struct result_bundle; + first = 1; + count++; + continue; + } + c1 = strchr(line, '\t'); + if (!c1) + continue; + *c1 = 0; + c1++; + sscanf(c1, "%lf", &d); + set_result_value(line, d, bundle); + } + + if (bundle_saved == 0) + delete bundle; + + file.close(); + // '%i" is for count, do not translate + fprintf(stderr, _("Loaded %i prior measurements\n"), count); +} + +void save_parameters(const char *filename) +{ + ofstream file; + char* pathname; + +// printf("result size is %i, #parameters is %i \n", (int)past_results.size(), (int)all_parameters.parameters.size()); + + if (!global_power_valid()) + return; + + pathname = get_param_directory(filename); + + file.open(pathname, ios::out); + if (!file) { + cout << _("Cannot save to file") << " " << pathname << "\n"; + return; + } + + map<string, int>::iterator it; + + for (it = param_index.begin(); it != param_index.end(); it++) { + int index; + index = it->second; + file << it->first << "\t" << setprecision(9) << all_parameters.parameters[index] << "\n"; + } + file.close(); +} + +void load_parameters(const char *filename) +{ + ifstream file; + char line[4096]; + char *c1; + char* pathname; + + pathname = get_param_directory(filename); + + file.open(pathname, ios::in); + if (!file) { + cout << _("Cannot load from file") << " " << pathname << "\n"; + cout << _("File will be loaded after taking minimum number of measurement(s) with battery only \n"); + return; + } + + while (file) { + double d; + memset(line, 0, 4096); + file.getline(line, 4095); + + c1 = strchr(line, '\t'); + if (!c1) + continue; + *c1 = 0; + c1++; + sscanf(c1, "%lf", &d); + + + set_parameter_value(line, d); + } + + file.close(); +} diff --git a/src/perf/perf.cpp b/src/perf/perf.cpp new file mode 100644 index 0000000..9ed0ba8 --- /dev/null +++ b/src/perf/perf.cpp @@ -0,0 +1,266 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include <iostream> +#include <fstream> + +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> + +#include <fcntl.h> + +#include "perf_event.h" +#include "perf.h" +#include "../lib.h" +#include "../display.h" + +struct pevent *perf_event::pevent; + +static int get_trace_type(const char *eventname) +{ + string str; + int this_trace; + + str = read_sysfs_string("/sys/kernel/debug/tracing/events/%s/id", + eventname); + if (str.length() < 1) + return -1; + + this_trace = strtoull(str.c_str(), NULL, 10); + return this_trace; +} + +static inline int sys_perf_event_open(struct perf_event_attr *attr, + pid_t pid, int cpu, int group_fd, + unsigned long flags) +{ + attr->size = sizeof(*attr); + return syscall(__NR_perf_event_open, attr, pid, cpu, + group_fd, flags); +} + +void perf_event::create_perf_event(char *eventname, int _cpu) +{ + struct perf_event_attr attr; + int ret; + int err; + + struct { + __u64 count; + __u64 time_enabled; + __u64 time_running; + __u64 id; + } read_data; + + if (perf_fd != -1) + clear(); + + memset(&attr, 0, sizeof(attr)); + + attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | + PERF_FORMAT_TOTAL_TIME_RUNNING | + PERF_FORMAT_ID; + + attr.sample_freq = 0; + attr.sample_period = 1; + attr.sample_type |= PERF_SAMPLE_RAW | PERF_SAMPLE_CPU | PERF_SAMPLE_TIME; + + attr.mmap = 1; + attr.comm = 1; + attr.inherit = 0; + attr.disabled = 1; + + attr.type = PERF_TYPE_TRACEPOINT; + attr.config = trace_type; + + if (attr.config <= 0) + return; + + perf_fd = sys_perf_event_open(&attr, -1, _cpu, -1, 0); + + if (perf_fd < 0) { + err = errno; + reset_display(); + if (err == EMFILE) + fprintf(stderr, _("Too many open files, please increase the limit of open file descriptors.\n")); + else { + fprintf(stderr, _("PowerTOP %s needs the kernel to support the 'perf' subsystem\n"), PACKAGE_VERSION); + fprintf(stderr, _("as well as support for trace points in the kernel:\n")); + fprintf(stderr, "CONFIG_PERF_EVENTS=y\nCONFIG_PERF_COUNTERS=y\nCONFIG_TRACEPOINTS=y\nCONFIG_TRACING=y\n"); + } + exit(EXIT_FAILURE); + } + if (read(perf_fd, &read_data, sizeof(read_data)) == -1) { + reset_display(); + perror("Unable to read perf file descriptor\n"); + exit(-1); + } + + fcntl(perf_fd, F_SETFL, O_NONBLOCK); + + perf_mmap = mmap(NULL, (bufsize+1)*getpagesize(), + PROT_READ | PROT_WRITE, MAP_SHARED, perf_fd, 0); + if (perf_mmap == MAP_FAILED) { + fprintf(stderr, "failed to mmap with %d (%s)\n", errno, strerror(errno)); + return; + } + + ret = ioctl(perf_fd, PERF_EVENT_IOC_ENABLE, 0); + + if (ret < 0) { + fprintf(stderr, "failed to enable perf \n"); + } + + pc = (perf_event_mmap_page *)perf_mmap; + data_mmap = (unsigned char *)perf_mmap + getpagesize(); + + +} + +void perf_event::set_event_name(const char *event_name) +{ + free(name); + name = strdup(event_name); + if (!name) { + fprintf(stderr, "failed to allocate event name\n"); + return; + } + + char *c; + + c = strchr(name, ':'); + if (c) + *c = '/'; + + trace_type = get_trace_type(name); +} + +perf_event::~perf_event(void) +{ + free(name); + + if (perf_event::pevent->ref_count == 1) { + pevent_free(perf_event::pevent); + perf_event::pevent = NULL; + clear(); + } else + pevent_unref(perf_event::pevent); +} + +void perf_event::set_cpu(int _cpu) +{ + cpu = _cpu; +} + +static void allocate_pevent(void) +{ + if (!perf_event::pevent) + perf_event::pevent = pevent_alloc(); + else + pevent_ref(perf_event::pevent); +} + +perf_event::perf_event(const char *event_name, int _cpu, int buffer_size) +{ + allocate_pevent(); + name = NULL; + perf_fd = -1; + bufsize = buffer_size; + cpu = _cpu; + perf_mmap = NULL; + trace_type = 0; + set_event_name(event_name); +} + +perf_event::perf_event(void) +{ + allocate_pevent(); + name = NULL; + perf_fd = -1; + bufsize = 128; + perf_mmap = NULL; + cpu = 0; + trace_type = 0; +} + +void perf_event::start(void) +{ + create_perf_event(name, cpu); +} + +void perf_event::stop(void) +{ + int ret; + ret = ioctl(perf_fd, PERF_EVENT_IOC_DISABLE, 0); + if (ret) + cout << "stop failing\n"; +} + +void perf_event::process(void *cookie) +{ + struct perf_event_header *header; + + if (perf_fd < 0) + return; + + while (pc->data_tail != pc->data_head ) { + while (pc->data_tail >= (unsigned int)bufsize * getpagesize()) + pc->data_tail -= bufsize * getpagesize(); + + header = (struct perf_event_header *)( (unsigned char *)data_mmap + pc->data_tail); + + if (header->size == 0) + break; + + pc->data_tail += header->size; + + while (pc->data_tail >= (unsigned int)bufsize * getpagesize()) + pc->data_tail -= bufsize * getpagesize(); + + if (header->type == PERF_RECORD_SAMPLE) + handle_event(header, cookie); + } + pc->data_tail = pc->data_head; +} + +void perf_event::clear(void) +{ + if (perf_mmap) { +// memset(perf_mmap, 0, (bufsize)*getpagesize()); + munmap(perf_mmap, (bufsize+1)*getpagesize()); + perf_mmap = NULL; + } + if (perf_fd != -1) + close(perf_fd); + perf_fd = -1; +} diff --git a/src/perf/perf.h b/src/perf/perf.h new file mode 100644 index 0000000..ee072ae --- /dev/null +++ b/src/perf/perf.h @@ -0,0 +1,76 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_PERF_H_ +#define _INCLUDE_GUARD_PERF_H_ + +#include <iostream> + + +extern "C" { + #include "../traceevent/event-parse.h" +} + + +using namespace std; + +class perf_event { +protected: + int perf_fd; + void * perf_mmap; + void * data_mmap; + struct perf_event_mmap_page *pc; + + + + int bufsize; + char *name; + int cpu; + void create_perf_event(char *eventname, int cpu); + +public: + unsigned int trace_type; + + perf_event(void); + perf_event(const char *event_name, int cpu = 0, int buffer_size = 128); + + virtual ~perf_event(void); + + + void set_event_name(const char *event_name); + void set_cpu(int cpu); + + void start(void); + void stop(void); + void clear(void); + + void process(void *cookie); + + virtual void handle_event(struct perf_event_header *header, void *cookie) { }; + + static struct pevent *pevent; + +}; + +#endif diff --git a/src/perf/perf_bundle.cpp b/src/perf/perf_bundle.cpp new file mode 100644 index 0000000..3d216ff --- /dev/null +++ b/src/perf/perf_bundle.cpp @@ -0,0 +1,348 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <malloc.h> +#include <algorithm> +#include <string.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +#include "perf_bundle.h" +#include "perf_event.h" +#include "perf.h" + +#include "../cpu/cpu.h" + +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) +# define USE_DECLTYPE +#endif + +class perf_bundle_event: public perf_event +{ +public: + perf_bundle_event(void); + virtual void handle_event(struct perf_event_header *header, void *cookie); +}; + +perf_bundle_event::perf_bundle_event(void) : perf_event() +{ +} + + +void perf_bundle_event::handle_event(struct perf_event_header *header, void *cookie) +{ + unsigned char *buffer; + vector<void *> *vector; + + buffer = (unsigned char *)malloc(header->size); + memcpy(buffer, header, header->size); + +#ifdef USE_DECLTYPE + vector = (decltype(vector))cookie; +#else + vector = (typeof(vector))cookie; +#endif + vector->push_back(buffer); +} + + +void perf_bundle::release(void) +{ + class perf_event *ev; + unsigned int i = 0; + + for (i = 0; i < events.size(); i++) { + ev = events[i]; + if (!ev) + continue; + ev->clear(); + delete ev; + } + events.clear(); + + for (i = 0; i < event_names.size(); i++) { + free((void*)event_names[i]); + } + event_names.clear(); + + for(i = 0; i < records.size(); i++) { + free(records[i]); + } + records.clear(); +} + +static char * read_file(const char *file) +{ + char *buffer = NULL; /* quient gcc */ + char buf[4096]; + int len = 0; + int fd; + int r; + + fd = open(file, O_RDONLY); + if (fd < 0) + exit(-1); + + while((r = read(fd, buf, 4096)) > 0) { + if (len) { + char *tmp = (char *)realloc(buffer, len + r + 1); + if (!tmp) + free(buffer); + buffer = tmp; + } else + buffer = (char *)malloc(r + 1); + if (!buffer) + goto out; + memcpy(buffer + len, buf, r); + len += r; + buffer[len] = '\0'; + } +out: + close(fd); + return buffer; +} + +static void parse_event_format(const char *event_name) +{ + char *tptr; + char *name = strdup(event_name); + char *sys = strtok_r(name, ":", &tptr); + char *event = strtok_r(NULL, ":", &tptr); + char *file; + char *buf; + + file = (char *)malloc(strlen(sys) + strlen(event) + + strlen("/sys/kernel/debug/tracing/events////format") + 2); + sprintf(file, "/sys/kernel/debug/tracing/events/%s/%s/format", sys, event); + + buf = read_file(file); + free(file); + if (!buf) { + free(name); + return; + } + + pevent_parse_event(perf_event::pevent, buf, strlen(buf), sys); + free(name); + free(buf); +} + +bool perf_bundle::add_event(const char *event_name) +{ + unsigned int i; + int event_added = false; + class perf_event *ev; + + + for (i = 0; i < all_cpus.size(); i++) { + + if (!all_cpus[i]) + continue; + + ev = new class perf_bundle_event(); + + ev->set_event_name(event_name); + ev->set_cpu(i); + + if ((int)ev->trace_type >= 0) { + if (event_names.find(ev->trace_type) == event_names.end()) { + event_names[ev->trace_type] = strdup(event_name); + parse_event_format(event_name); + } + events.push_back(ev); + event_added = true; + } else { + delete ev; + } + } + return event_added; +} + +void perf_bundle::start(void) +{ + unsigned int i; + class perf_event *ev; + + for (i = 0; i < events.size(); i++) { + ev = events[i]; + if (!ev) + continue; + ev->start(); + } +} +void perf_bundle::stop(void) +{ + unsigned int i; + class perf_event *ev; + + for (i = 0; i < events.size(); i++) { + ev = events[i]; + if (!ev) + continue; + ev->stop(); + } +} +void perf_bundle::clear(void) +{ + unsigned int i; + + class perf_event *ev; + + for (i = 0; i < events.size(); i++) { + ev = events[i]; + if (!ev) + continue; + ev->clear(); + } + + for (i = 0; i < records.size(); i++) { + free(records[i]); + } + records.resize(0); +} + + +struct trace_entry { + uint64_t time; + uint32_t cpu; + uint32_t res; + __u32 size; +} __attribute__((packed));; + + +struct perf_sample { + struct perf_event_header header; + struct trace_entry trace; + unsigned char data[0]; +} __attribute__((packed)); + +static uint64_t timestamp(perf_event_header *event) +{ + struct perf_sample *sample; + + if (event->type != PERF_RECORD_SAMPLE) + return 0; + + sample = (struct perf_sample *)event; + +#if 0 + int i; + unsigned char *x; + + printf("header:\n"); + printf(" type is %x \n", sample->header.type); + printf(" misc is %x \n", sample->header.misc); + printf(" size is %i \n", sample->header.size); + printf("sample:\n"); + printf(" time is %llx \n", sample->trace.time); + printf(" cpu is %i / %x \n", sample->trace.cpu, sample->trace.cpu); + printf(" res is %i / %x \n", sample->trace.res, sample->trace.res); + printf(" size is %i / %x \n", sample->trace.size, sample->trace.size); + printf(" type is %i / %x \n", sample->trace.type, sample->trace.type); + printf(" flags is %i / %x \n", sample->trace.flags, sample->trace.flags); + printf(" p/c is %i / %x \n", sample->trace.preempt_count, sample->trace.preempt_count); + printf(" pid is %i / %x \n", sample->trace.pid, sample->trace.pid); + printf(" lock dept is %i / %x \n", sample->trace.lock_depth, sample->trace.lock_depth); + + x = (unsigned char *)sample; + for (i = 0; i < sample->header.size; i++) + printf("%02x ", *(x+i)); + printf("\n"); +#endif + return sample->trace.time; + +} + +static bool event_sort_function (void *i, void *j) +{ + struct perf_event_header *I, *J; + + I = (struct perf_event_header *) i; + J = (struct perf_event_header *) j; + return (timestamp(I)<timestamp(J)); +} + +/* + * sample's PERF_SAMPLE_CPU cpu nr is a raw_smp_processor_id() by the + * time of perf_event_output(), which may differ from struct perf_event + * cpu, thus we need to fix sample->trace.cpu. + */ +static void fixup_sample_trace_cpu(struct perf_sample *sample) +{ + struct event_format *event; + struct pevent_record rec; + unsigned long long cpu_nr; + int type; + int ret; + + rec.data = &sample->data; + type = pevent_data_type(perf_event::pevent, &rec); + event = pevent_find_event(perf_event::pevent, type); + if (!event) + return; + /** don't touch trace if event does not contain cpu_id field*/ + ret = pevent_get_field_val(NULL, event, "cpu_id", &rec, &cpu_nr, 0); + if (ret < 0) + return; + sample->trace.cpu = cpu_nr; +} + +void perf_bundle::process(void) +{ + unsigned int i; + class perf_event *ev; + + /* fixme: reserve enough space in the array in one go */ + for (i = 0; i < events.size(); i++) { + ev = events[i]; + if (!ev) + continue; + ev->process(&records); + } + sort(records.begin(), records.end(), event_sort_function); + + for (i = 0; i < records.size(); i++) { + struct perf_sample *sample; + + sample = (struct perf_sample *)records[i]; + if (!sample) + continue; + + if (sample->header.type != PERF_RECORD_SAMPLE) + continue; + + fixup_sample_trace_cpu(sample); + handle_trace_point(&sample->data, sample->trace.cpu, sample->trace.time); + } +} + +void perf_bundle::handle_trace_point(void *trace, int cpu, uint64_t time) +{ + printf("UH OH... abstract handle_trace_point called\n"); +} diff --git a/src/perf/perf_bundle.h b/src/perf/perf_bundle.h new file mode 100644 index 0000000..ec50744 --- /dev/null +++ b/src/perf/perf_bundle.h @@ -0,0 +1,59 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_PERF_BUNDLE_H_ +#define _INCLUDE_GUARD_PERF_BUNDLE_H_ + +#include <iostream> +#include <vector> +#include <map> + +using namespace std; + +#include "perf.h" +class perf_event; + + +class perf_bundle { +protected: + vector<class perf_event *> events; + std::map<int, char*> event_names; +public: + vector<void *> records; + virtual ~perf_bundle() {}; + + virtual void release(void); + bool add_event(const char *event_name); + + void start(void); + void stop(void); + void clear(void); + + void process(void); + + virtual void handle_trace_point(void *trace, int cpu = 0, uint64_t time = 0); +}; + + +#endif diff --git a/src/perf/perf_event.h b/src/perf/perf_event.h new file mode 100644 index 0000000..92a38b8 --- /dev/null +++ b/src/perf/perf_event.h @@ -0,0 +1,910 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +/* + * Performance events: + * + * Copyright (C) 2008-2009, Thomas Gleixner <tglx@linutronix.de> + * Copyright (C) 2008-2009, Red Hat, Inc., Ingo Molnar + * Copyright (C) 2008-2009, Red Hat, Inc., Peter Zijlstra + * + * Data type definitions, declarations, prototypes. + * + * Started by: Thomas Gleixner and Ingo Molnar + * + * For licencing details see kernel-base/COPYING + */ +#ifndef _LINUX_PERF_EVENT_H +#define _LINUX_PERF_EVENT_H + +#include <linux/types.h> +#include <linux/ioctl.h> +#include <asm/byteorder.h> +#include <sys/syscall.h> + + +/* + * User-space ABI bits: + */ + +/* + * attr.type + */ +enum perf_type_id { + PERF_TYPE_HARDWARE = 0, + PERF_TYPE_SOFTWARE = 1, + PERF_TYPE_TRACEPOINT = 2, + PERF_TYPE_HW_CACHE = 3, + PERF_TYPE_RAW = 4, + + PERF_TYPE_MAX, /* non-ABI */ +}; + +/* + * Generalized performance event event_id types, used by the + * attr.event_id parameter of the sys_perf_event_open() + * syscall: + */ +enum perf_hw_id { + /* + * Common hardware events, generalized by the kernel: + */ + PERF_COUNT_HW_CPU_CYCLES = 0, + PERF_COUNT_HW_INSTRUCTIONS = 1, + PERF_COUNT_HW_CACHE_REFERENCES = 2, + PERF_COUNT_HW_CACHE_MISSES = 3, + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4, + PERF_COUNT_HW_BRANCH_MISSES = 5, + PERF_COUNT_HW_BUS_CYCLES = 6, + + PERF_COUNT_HW_MAX, /* non-ABI */ +}; + +/* + * Generalized hardware cache events: + * + * { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x + * { read, write, prefetch } x + * { accesses, misses } + */ +enum perf_hw_cache_id { + PERF_COUNT_HW_CACHE_L1D = 0, + PERF_COUNT_HW_CACHE_L1I = 1, + PERF_COUNT_HW_CACHE_LL = 2, + PERF_COUNT_HW_CACHE_DTLB = 3, + PERF_COUNT_HW_CACHE_ITLB = 4, + PERF_COUNT_HW_CACHE_BPU = 5, + + PERF_COUNT_HW_CACHE_MAX, /* non-ABI */ +}; + +enum perf_hw_cache_op_id { + PERF_COUNT_HW_CACHE_OP_READ = 0, + PERF_COUNT_HW_CACHE_OP_WRITE = 1, + PERF_COUNT_HW_CACHE_OP_PREFETCH = 2, + + PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */ +}; + +enum perf_hw_cache_op_result_id { + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0, + PERF_COUNT_HW_CACHE_RESULT_MISS = 1, + + PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */ +}; + +/* + * Special "software" events provided by the kernel, even if the hardware + * does not support performance events. These events measure various + * physical and sw events of the kernel (and allow the profiling of them as + * well): + */ +enum perf_sw_ids { + PERF_COUNT_SW_CPU_CLOCK = 0, + PERF_COUNT_SW_TASK_CLOCK = 1, + PERF_COUNT_SW_PAGE_FAULTS = 2, + PERF_COUNT_SW_CONTEXT_SWITCHES = 3, + PERF_COUNT_SW_CPU_MIGRATIONS = 4, + PERF_COUNT_SW_PAGE_FAULTS_MIN = 5, + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6, + + PERF_COUNT_SW_MAX, /* non-ABI */ +}; + +/* + * Bits that can be set in attr.sample_type to request information + * in the overflow packets. + */ +enum perf_event_sample_format { + PERF_SAMPLE_IP = 1U << 0, + PERF_SAMPLE_TID = 1U << 1, + PERF_SAMPLE_TIME = 1U << 2, + PERF_SAMPLE_ADDR = 1U << 3, + PERF_SAMPLE_READ = 1U << 4, + PERF_SAMPLE_CALLCHAIN = 1U << 5, + PERF_SAMPLE_ID = 1U << 6, + PERF_SAMPLE_CPU = 1U << 7, + PERF_SAMPLE_PERIOD = 1U << 8, + PERF_SAMPLE_STREAM_ID = 1U << 9, + PERF_SAMPLE_RAW = 1U << 10, + + PERF_SAMPLE_MAX = 1U << 11, /* non-ABI */ +}; + +/* + * The format of the data returned by read() on a perf event fd, + * as specified by attr.read_format: + * + * struct read_format { + * { u64 value; + * { u64 time_enabled; } && PERF_FORMAT_ENABLED + * { u64 time_running; } && PERF_FORMAT_RUNNING + * { u64 id; } && PERF_FORMAT_ID + * } && !PERF_FORMAT_GROUP + * + * { u64 nr; + * { u64 time_enabled; } && PERF_FORMAT_ENABLED + * { u64 time_running; } && PERF_FORMAT_RUNNING + * { u64 value; + * { u64 id; } && PERF_FORMAT_ID + * } cntr[nr]; + * } && PERF_FORMAT_GROUP + * }; + */ +enum perf_event_read_format { + PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0, + PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1, + PERF_FORMAT_ID = 1U << 2, + PERF_FORMAT_GROUP = 1U << 3, + + PERF_FORMAT_MAX = 1U << 4, /* non-ABI */ +}; + +#define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */ + +/* + * Hardware event_id to monitor via a performance monitoring event: + */ +struct perf_event_attr { + + /* + * Major type: hardware/software/tracepoint/etc. + */ + __u32 type; + + /* + * Size of the attr structure, for fwd/bwd compat. + */ + __u32 size; + + /* + * Type specific configuration information. + */ + __u64 config; + + union { + __u64 sample_period; + __u64 sample_freq; + }; + + __u64 sample_type; + __u64 read_format; + + __u64 disabled : 1, /* off by default */ + inherit : 1, /* children inherit it */ + pinned : 1, /* must always be on PMU */ + exclusive : 1, /* only group on PMU */ + exclude_user : 1, /* don't count user */ + exclude_kernel : 1, /* ditto kernel */ + exclude_hv : 1, /* ditto hypervisor */ + exclude_idle : 1, /* don't count when idle */ + mmap : 1, /* include mmap data */ + comm : 1, /* include comm data */ + freq : 1, /* use freq, not period */ + inherit_stat : 1, /* per task counts */ + enable_on_exec : 1, /* next exec enables */ + task : 1, /* trace fork/exit */ + watermark : 1, /* wakeup_watermark */ + + __reserved_1 : 49; + + union { + __u32 wakeup_events; /* wakeup every n events */ + __u32 wakeup_watermark; /* bytes before wakeup */ + }; + __u32 __reserved_2; + + __u64 __reserved_3; +}; + +/* + * Ioctls that can be done on a perf event fd: + */ +#define PERF_EVENT_IOC_ENABLE _IO ('$', 0) +#define PERF_EVENT_IOC_DISABLE _IO ('$', 1) +#define PERF_EVENT_IOC_REFRESH _IO ('$', 2) +#define PERF_EVENT_IOC_RESET _IO ('$', 3) +#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, u64) +#define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5) + +enum perf_event_ioc_flags { + PERF_IOC_FLAG_GROUP = 1U << 0, +}; + +/* + * Structure of the page that can be mapped via mmap + */ +struct perf_event_mmap_page { + __u32 version; /* version number of this structure */ + __u32 compat_version; /* lowest version this is compat with */ + + /* + * Bits needed to read the hw events in user-space. + * + * u32 seq; + * s64 count; + * + * do { + * seq = pc->lock; + * + * barrier() + * if (pc->index) { + * count = pmc_read(pc->index - 1); + * count += pc->offset; + * } else + * goto regular_read; + * + * barrier(); + * } while (pc->lock != seq); + * + * NOTE: for obvious reason this only works on self-monitoring + * processes. + */ + __u32 lock; /* seqlock for synchronization */ + __u32 index; /* hardware event identifier */ + __s64 offset; /* add to hardware event value */ + __u64 time_enabled; /* time event active */ + __u64 time_running; /* time event on cpu */ + + /* + * Hole for extension of the self monitor capabilities + */ + + __u64 __reserved[123]; /* align to 1k */ + + /* + * Control data for the mmap() data buffer. + * + * User-space reading the @data_head value should issue an rmb(), on + * SMP capable platforms, after reading this value -- see + * perf_event_wakeup(). + * + * When the mapping is PROT_WRITE the @data_tail value should be + * written by userspace to reflect the last read data. In this case + * the kernel will not over-write unread data. + */ + __u64 data_head; /* head in the data section */ + __u64 data_tail; /* user-space written tail */ +}; + +#define PERF_RECORD_MISC_CPUMODE_MASK (3 << 0) +#define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0) +#define PERF_RECORD_MISC_KERNEL (1 << 0) +#define PERF_RECORD_MISC_USER (2 << 0) +#define PERF_RECORD_MISC_HYPERVISOR (3 << 0) + +struct perf_event_header { + __u32 type; + __u16 misc; + __u16 size; +}; + +enum perf_event_type { + + /* + * The MMAP events record the PROT_EXEC mappings so that we can + * correlate userspace IPs to code. They have the following structure: + * + * struct { + * struct perf_event_header header; + * + * u32 pid, tid; + * u64 addr; + * u64 len; + * u64 pgoff; + * char filename[]; + * }; + */ + PERF_RECORD_MMAP = 1, + + /* + * struct { + * struct perf_event_header header; + * u64 id; + * u64 lost; + * }; + */ + PERF_RECORD_LOST = 2, + + /* + * struct { + * struct perf_event_header header; + * + * u32 pid, tid; + * char comm[]; + * }; + */ + PERF_RECORD_COMM = 3, + + /* + * struct { + * struct perf_event_header header; + * u32 pid, ppid; + * u32 tid, ptid; + * u64 time; + * }; + */ + PERF_RECORD_EXIT = 4, + + /* + * struct { + * struct perf_event_header header; + * u64 time; + * u64 id; + * u64 stream_id; + * }; + */ + PERF_RECORD_THROTTLE = 5, + PERF_RECORD_UNTHROTTLE = 6, + + /* + * struct { + * struct perf_event_header header; + * u32 pid, ppid; + * u32 tid, ptid; + * u64 time; + * }; + */ + PERF_RECORD_FORK = 7, + + /* + * struct { + * struct perf_event_header header; + * u32 pid, tid; + * + * struct read_format values; + * }; + */ + PERF_RECORD_READ = 8, + + /* + * struct { + * struct perf_event_header header; + * + * { u64 ip; } && PERF_SAMPLE_IP + * { u32 pid, tid; } && PERF_SAMPLE_TID + * { u64 time; } && PERF_SAMPLE_TIME + * { u64 addr; } && PERF_SAMPLE_ADDR + * { u64 id; } && PERF_SAMPLE_ID + * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID + * { u32 cpu, res; } && PERF_SAMPLE_CPU + * { u64 period; } && PERF_SAMPLE_PERIOD + * + * { struct read_format values; } && PERF_SAMPLE_READ + * + * { u64 nr, + * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN + * + * # + * # The RAW record below is opaque data wrt the ABI + * # + * # That is, the ABI doesn't make any promises wrt to + * # the stability of its content, it may vary depending + * # on event, hardware, kernel version and phase of + * # the moon. + * # + * # In other words, PERF_SAMPLE_RAW contents are not an ABI. + * # + * + * { u32 size; + * char data[size];}&& PERF_SAMPLE_RAW + * }; + */ + PERF_RECORD_SAMPLE = 9, + + PERF_RECORD_MAX, /* non-ABI */ +}; + +enum perf_callchain_context { + PERF_CONTEXT_HV = (__u64)-32, + PERF_CONTEXT_KERNEL = (__u64)-128, + PERF_CONTEXT_USER = (__u64)-512, + + PERF_CONTEXT_GUEST = (__u64)-2048, + PERF_CONTEXT_GUEST_KERNEL = (__u64)-2176, + PERF_CONTEXT_GUEST_USER = (__u64)-2560, + + PERF_CONTEXT_MAX = (__u64)-4095, +}; + +#define PERF_FLAG_FD_NO_GROUP (1U << 0) +#define PERF_FLAG_FD_OUTPUT (1U << 1) + +#ifdef __KERNEL__ +/* + * Kernel-internal data types and definitions: + */ + +#ifdef CONFIG_PERF_EVENTS +# include <asm/perf_event.h> +#endif + +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/rculist.h> +#include <linux/rcupdate.h> +#include <linux/spinlock.h> +#include <linux/hrtimer.h> +#include <linux/fs.h> +#include <linux/pid_namespace.h> +#include <linux/workqueue.h> +#include <asm/atomic.h> + +#define PERF_MAX_STACK_DEPTH 255 + +struct perf_callchain_entry { + __u64 nr; + __u64 ip[PERF_MAX_STACK_DEPTH]; +}; + +struct perf_raw_record { + u32 size; + void *data; +}; + +struct task_struct; + +/** + * struct hw_perf_event - performance event hardware details: + */ +struct hw_perf_event { +#ifdef CONFIG_PERF_EVENTS + union { + struct { /* hardware */ + u64 config; + unsigned long config_base; + unsigned long event_base; + int idx; + }; + struct { /* software */ + s64 remaining; + struct hrtimer hrtimer; + }; + }; + atomic64_t prev_count; + u64 sample_period; + u64 last_period; + atomic64_t period_left; + u64 interrupts; + + u64 freq_count; + u64 freq_interrupts; + u64 freq_stamp; +#endif +}; + +struct perf_event; + +/** + * struct pmu - generic performance monitoring unit + */ +struct pmu { + int (*enable) (struct perf_event *event); + void (*disable) (struct perf_event *event); + void (*read) (struct perf_event *event); + void (*unthrottle) (struct perf_event *event); +}; + +/** + * enum perf_event_active_state - the states of a event + */ +enum perf_event_active_state { + PERF_EVENT_STATE_ERROR = -2, + PERF_EVENT_STATE_OFF = -1, + PERF_EVENT_STATE_INACTIVE = 0, + PERF_EVENT_STATE_ACTIVE = 1, +}; + +struct file; + +struct perf_mmap_data { + struct rcu_head rcu_head; +#ifdef CONFIG_PERF_USE_VMALLOC + struct work_struct work; +#endif + int data_order; + int nr_pages; /* nr of data pages */ + int writable; /* are we writable */ + int nr_locked; /* nr pages mlocked */ + + atomic_t poll; /* POLL_ for wakeups */ + atomic_t events; /* event_id limit */ + + atomic_long_t head; /* write position */ + atomic_long_t done_head; /* completed head */ + + atomic_t lock; /* concurrent writes */ + atomic_t wakeup; /* needs a wakeup */ + atomic_t lost; /* nr records lost */ + + long watermark; /* wakeup watermark */ + + struct perf_event_mmap_page *user_page; + void *data_pages[0]; +}; + +struct perf_pending_entry { + struct perf_pending_entry *next; + void (*func)(struct perf_pending_entry *); +}; + +/** + * struct perf_event - performance event kernel representation: + */ +struct perf_event { +#ifdef CONFIG_PERF_EVENTS + struct list_head group_entry; + struct list_head event_entry; + struct list_head sibling_list; + int nr_siblings; + struct perf_event *group_leader; + struct perf_event *output; + const struct pmu *pmu; + + enum perf_event_active_state state; + atomic64_t count; + + /* + * These are the total time in nanoseconds that the event + * has been enabled (i.e. eligible to run, and the task has + * been scheduled in, if this is a per-task event) + * and running (scheduled onto the CPU), respectively. + * + * They are computed from tstamp_enabled, tstamp_running and + * tstamp_stopped when the event is in INACTIVE or ACTIVE state. + */ + u64 total_time_enabled; + u64 total_time_running; + + /* + * These are timestamps used for computing total_time_enabled + * and total_time_running when the event is in INACTIVE or + * ACTIVE state, measured in nanoseconds from an arbitrary point + * in time. + * tstamp_enabled: the notional time when the event was enabled + * tstamp_running: the notional time when the event was scheduled on + * tstamp_stopped: in INACTIVE state, the notional time when the + * event was scheduled off. + */ + u64 tstamp_enabled; + u64 tstamp_running; + u64 tstamp_stopped; + + struct perf_event_attr attr; + struct hw_perf_event hw; + + struct perf_event_context *ctx; + struct file *filp; + + /* + * These accumulate total time (in nanoseconds) that children + * events have been enabled and running, respectively. + */ + atomic64_t child_total_time_enabled; + atomic64_t child_total_time_running; + + /* + * Protect attach/detach and child_list: + */ + struct mutex child_mutex; + struct list_head child_list; + struct perf_event *parent; + + int oncpu; + int cpu; + + struct list_head owner_entry; + struct task_struct *owner; + + /* mmap bits */ + struct mutex mmap_mutex; + atomic_t mmap_count; + struct perf_mmap_data *data; + + /* poll related */ + wait_queue_head_t waitq; + struct fasync_struct *fasync; + + /* delayed work for NMIs and such */ + int pending_wakeup; + int pending_kill; + int pending_disable; + struct perf_pending_entry pending; + + atomic_t event_limit; + + void (*destroy)(struct perf_event *); + struct rcu_head rcu_head; + + struct pid_namespace *ns; + u64 id; +#endif +}; + +/** + * struct perf_event_context - event context structure + * + * Used as a container for task events and CPU events as well: + */ +struct perf_event_context { + /* + * Protect the states of the events in the list, + * nr_active, and the list: + */ + spinlock_t lock; + /* + * Protect the list of events. Locking either mutex or lock + * is sufficient to ensure the list doesn't change; to change + * the list you need to lock both the mutex and the spinlock. + */ + struct mutex mutex; + + struct list_head group_list; + struct list_head event_list; + int nr_events; + int nr_active; + int is_active; + int nr_stat; + atomic_t refcount; + struct task_struct *task; + + /* + * Context clock, runs when context enabled. + */ + u64 time; + u64 timestamp; + + /* + * These fields let us detect when two contexts have both + * been cloned (inherited) from a common ancestor. + */ + struct perf_event_context *parent_ctx; + u64 parent_gen; + u64 generation; + int pin_count; + struct rcu_head rcu_head; +}; + +/** + * struct perf_event_cpu_context - per cpu event context structure + */ +struct perf_cpu_context { + struct perf_event_context ctx; + struct perf_event_context *task_ctx; + int active_oncpu; + int max_pertask; + int exclusive; + + /* + * Recursion avoidance: + * + * task, softirq, irq, nmi context + */ + int recursion[4]; +}; + +struct perf_output_handle { + struct perf_event *event; + struct perf_mmap_data *data; + unsigned long head; + unsigned long offset; + int nmi; + int sample; + int locked; + unsigned long flags; +}; + +#ifdef CONFIG_PERF_EVENTS + +/* + * Set by architecture code: + */ +extern int perf_max_events; + +extern const struct pmu *hw_perf_event_init(struct perf_event *event); + +extern void perf_event_task_sched_in(struct task_struct *task, int cpu); +extern void perf_event_task_sched_out(struct task_struct *task, + struct task_struct *next, int cpu); +extern void perf_event_task_tick(struct task_struct *task, int cpu); +extern int perf_event_init_task(struct task_struct *child); +extern void perf_event_exit_task(struct task_struct *child); +extern void perf_event_free_task(struct task_struct *task); +extern void set_perf_event_pending(void); +extern void perf_event_do_pending(void); +extern void perf_event_print_debug(void); +extern void __perf_disable(void); +extern bool __perf_enable(void); +extern void perf_disable(void); +extern void perf_enable(void); +extern int perf_event_task_disable(void); +extern int perf_event_task_enable(void); +extern int hw_perf_group_sched_in(struct perf_event *group_leader, + struct perf_cpu_context *cpuctx, + struct perf_event_context *ctx, int cpu); +extern void perf_event_update_userpage(struct perf_event *event); + +struct perf_sample_data { + u64 type; + + u64 ip; + struct { + u32 pid; + u32 tid; + } tid_entry; + u64 time; + u64 addr; + u64 id; + u64 stream_id; + struct { + u32 cpu; + u32 reserved; + } cpu_entry; + u64 period; + struct perf_callchain_entry *callchain; + struct perf_raw_record *raw; +}; + +extern void perf_output_sample(struct perf_output_handle *handle, + struct perf_event_header *header, + struct perf_sample_data *data, + struct perf_event *event); +extern void perf_prepare_sample(struct perf_event_header *header, + struct perf_sample_data *data, + struct perf_event *event, + struct pt_regs *regs); + +extern int perf_event_overflow(struct perf_event *event, int nmi, + struct perf_sample_data *data, + struct pt_regs *regs); + +/* + * Return 1 for a software event, 0 for a hardware event + */ +static inline int is_software_event(struct perf_event *event) +{ + return (event->attr.type != PERF_TYPE_RAW) && + (event->attr.type != PERF_TYPE_HARDWARE) && + (event->attr.type != PERF_TYPE_HW_CACHE); +} + +extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX]; + +extern void __perf_sw_event(u32, u64, int, struct pt_regs *, u64); + +static inline void +perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr) +{ + if (atomic_read(&perf_swevent_enabled[event_id])) + __perf_sw_event(event_id, nr, nmi, regs, addr); +} + +extern void __perf_event_mmap(struct vm_area_struct *vma); + +static inline void perf_event_mmap(struct vm_area_struct *vma) +{ + if (vma->vm_flags & VM_EXEC) + __perf_event_mmap(vma); +} + +extern void perf_event_comm(struct task_struct *tsk); +extern void perf_event_fork(struct task_struct *tsk); + +extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs); + +extern int sysctl_perf_event_paranoid; +extern int sysctl_perf_event_mlock; +extern int sysctl_perf_event_sample_rate; + +extern void perf_event_init(void); +extern void perf_tp_event(int event_id, u64 addr, u64 count, + void *record, int entry_size); + +#ifndef perf_misc_flags +#define perf_misc_flags(regs) (user_mode(regs) ? PERF_RECORD_MISC_USER : \ + PERF_RECORD_MISC_KERNEL) +#define perf_instruction_pointer(regs) instruction_pointer(regs) +#endif + +extern int perf_output_begin(struct perf_output_handle *handle, + struct perf_event *event, unsigned int size, + int nmi, int sample); +extern void perf_output_end(struct perf_output_handle *handle); +extern void perf_output_copy(struct perf_output_handle *handle, + const void *buf, unsigned int len); +#else +static inline void +perf_event_task_sched_in(struct task_struct *task, int cpu) { } +static inline void +perf_event_task_sched_out(struct task_struct *task, + struct task_struct *next, int cpu) { } +static inline void +perf_event_task_tick(struct task_struct *task, int cpu) { } +static inline int perf_event_init_task(struct task_struct *child) { return 0; } +static inline void perf_event_exit_task(struct task_struct *child) { } +static inline void perf_event_free_task(struct task_struct *task) { } +static inline void perf_event_do_pending(void) { } +static inline void perf_event_print_debug(void) { } +static inline void perf_disable(void) { } +static inline void perf_enable(void) { } +static inline int perf_event_task_disable(void) { return -EINVAL; } +static inline int perf_event_task_enable(void) { return -EINVAL; } + +static inline void +perf_sw_event(u32 event_id, u64 nr, int nmi, + struct pt_regs *regs, u64 addr) { } + +static inline void perf_event_mmap(struct vm_area_struct *vma) { } +static inline void perf_event_comm(struct task_struct *tsk) { } +static inline void perf_event_fork(struct task_struct *tsk) { } +static inline void perf_event_init(void) { } + +#endif + +#define perf_output_put(handle, x) \ + perf_output_copy((handle), &(x), sizeof(x)) + +#endif /* __KERNEL__ */ + + +#if 0 +/* + * trace_flag_type is an enumeration that holds different + * states when a trace occurs. These are: + * IRQS_OFF - interrupts were disabled + * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags + * NEED_RESCED - reschedule is requested + * HARDIRQ - inside an interrupt handler + * SOFTIRQ - inside a softirq handler + */ +enum trace_flag_type { + TRACE_FLAG_IRQS_OFF = 0x01, + TRACE_FLAG_IRQS_NOSUPPORT = 0x02, + TRACE_FLAG_NEED_RESCHED = 0x04, + TRACE_FLAG_HARDIRQ = 0x08, + TRACE_FLAG_SOFTIRQ = 0x10, +}; +#endif + +#endif /* _LINUX_PERF_EVENT_H */ diff --git a/src/powertop.css b/src/powertop.css new file mode 100644 index 0000000..daa20c5 --- /dev/null +++ b/src/powertop.css @@ -0,0 +1,263 @@ +<!DOCTYPE html> +<html lang='en'> +<head> +<title>PowerTOP report</title> +<meta http-equiv='content-type' content='text/html;charset=utf-8'> + +<script type='text/javascript'> + +var powertop = { + blocks: { + summary: 'Summary', + cpuidle: 'CPU Idle', + cpufreq: 'CPU Frequency', + software: 'Software Info', + devinfo: 'Device Info', + tuning: 'Tuning', + ahci: 'AHCI' + }, + cadd: function(idx, c){ + var el = document.getElementById(idx); + if (el) { + var cn = el.className; + if (cn.indexOf(c) != -1) + return; + cn += ' ' + c; + el.className = cn; + } + }, + crm: function(id, c){ + var el = document.getElementById(id); + if (el) { + var cn = el.className + while (cn.indexOf(' ' + c) != -1) + cn = cn.replace(' ' + c,''); + el.className = cn; + } + }, + newbutton: function(id, txt) { + var x = document.createElement('div'); + x.id = id + '_button'; + x.className = 'nav_button'; + x.textContent = txt; + x.innerText = txt; + x.onclick = function() { powertop.toggle(id); }; + return x; + }, + setupbuttons: function() { + var t = document.getElementById('main_menu'); + if (t) { + for (var b in powertop.blocks) { + t.appendChild(powertop.newbutton(b, powertop.blocks[b])); + } + t.appendChild(powertop.newbutton('all', 'All')); + } + }, + toggle: function(b) { + powertop.baseall(); + if (b == 'all') { + for (var c in powertop.blocks) { + powertop.crm(c, 'hide'); + } + } else { + powertop.crm(b, 'hide'); + } + powertop.cadd(b + '_button', 'pressed'); + }, + baseall: function() { + for (var b in powertop.blocks) { + powertop.cadd(b, 'hide'); + powertop.crm(b + '_button', 'pressed'); + } + powertop.cadd('all', 'hide'); + powertop.crm('all_button', 'pressed'); + }, + onload: function() { + powertop.setupbuttons(); + powertop.toggle('summary'); + } +} +</script> + +<style type='text/css'> +/* General CSS */ +*{ + margin:0px; + padding:0px; + width: auto; +} + +body { + background-color: #eee; /* Background color */ + color: #222; /* Font color */ + font-family: Helvetica; + font-size: 14px; +} + +#main_container{ + margin: 2px auto; +} + +/* Top logo & system table css */ +#main_header{ + min-width: 960px; +} + +img.pwtop_logo{ + float:left; + height:40%; + width: 40%; + padding:20px; +} + +.sys_info +{ + float: right; + height:116px; + width:450px; + font-size: 12px; + text-align: left; +} + +th{ + text-align: left; +} + +/* CSS Main Content */ + +.content_title +{ + color: #296629; + padding:0px; + margin:2px; +} + +#chart_div{ + float: left; +} + +.small +{ + font-size: 10px; +} + +table.emphasis2 +{ + font-size: 13px; + max-width:95%; +} + + +th.emph_title { + padding:5px; +} + +tr.emph1:nth-child(odd) { + background: #ffffff; +} + +tr.emph1:nth-child(even) { + background: #ebebeb; +} + +tr.tune:nth-child(odd) { + background: #fffcfc; +} +tr.tune:nth-child(even) { + background: #fff0f0; +} + +td.no_wrap:first-child { + white-space:nowrap; +} + +.side_by_side_left{ + float:left; +} +.side_by_side_right{ + float:right; +} + +#device{ + display: inline-block; +} +.clear_block{ + clear:both; +} + +td.package{ + background-color: #e0ddfa; /*purple*/ +} + +td.core{ + background-color: #d1ddff; /*ccebff; /*blue*/ +} + +td.cpu{ + background-color: #ffffeb; /* yellow */ +} + +th.title{ + text-align: center; + /*border-bottom: 1px solid #666;*/ +} + + +li.summary_list +{ + display: inline; + padding: 5px; + background-color: #f6f6f9; + font-size: 12px; +} + + + +/* main menu css*/ +#main_menu { + clear:both; + font-weight: bold; + padding: 5px 0; + text-align: left; + background-image: -webkit-gradient(linear, left top, left bottom, + from(#aaa), to(#eee)); + background: -moz-linear-gradient(top, #aaa, #eee); +} + + +#main_menu div { + font-size: 12px; + font-weight: bold; + color: white; +} + +#main_menu div.nav_button { + margin: 0 0.2em; + display: inline; + cursor: pointer; + color: #223232; + font-size: 13px; + font-weight: bold; + padding: 5px; + text-align: center; + text-decoration: none; +} + +div.pressed { + border: -webkit-gradient(linear, left top, left bottom, + from(#b2ffb2), to(#e0ffe0)); + border-width:0px 8px 0px 8px; + background: #999; + background-image: -webkit-gradient(linear, left top, left bottom, + from(#b2ffb2), to(#e0ffe0)); + background: -moz-linear-gradient(top, #b2ffb2, #e0ffe0); +} + +div.hide { + display: none; +} +</style> +</head> + +<body onload='powertop.onload();'> +<div id=\"main_container\"> diff --git a/src/process/do_process.cpp b/src/process/do_process.cpp new file mode 100644 index 0000000..be8d3bd --- /dev/null +++ b/src/process/do_process.cpp @@ -0,0 +1,1230 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "process.h" +#include "interrupt.h" +#include "timer.h" +#include "work.h" +#include "processdevice.h" +#include "../lib.h" +#include "../report/report.h" +#include "../report/report-data-html.h" +#include "../report/report-maker.h" +#include "../devlist.h" + +#include <vector> +#include <algorithm> +#include <stack> + +#include <stdio.h> +#include <string.h> +#include <ncurses.h> + +#include "../perf/perf_bundle.h" +#include "../perf/perf_event.h" +#include "../parameters/parameters.h" +#include "../display.h" +#include "../measurement/measurement.h" + +static class perf_bundle * perf_events; + +vector <class power_consumer *> all_power; + +vector< vector<class power_consumer *> > cpu_stack; + +vector<int> cpu_level; +vector<int> cpu_credit; +vector<class power_consumer *> cpu_blame; + +#define LEVEL_HARDIRQ 1 +#define LEVEL_SOFTIRQ 2 +#define LEVEL_TIMER 3 +#define LEVEL_WAKEUP 4 +#define LEVEL_PROCESS 5 +#define LEVEL_WORK 6 + +static uint64_t first_stamp, last_stamp; + +double measurement_time; + +static void push_consumer(unsigned int cpu, class power_consumer *consumer) +{ + if (cpu_stack.size() <= cpu) + cpu_stack.resize(cpu + 1); + cpu_stack[cpu].push_back(consumer); +} + +static void pop_consumer(unsigned int cpu) +{ + if (cpu_stack.size() <= cpu) + cpu_stack.resize(cpu + 1); + + if (cpu_stack[cpu].size()) + cpu_stack[cpu].resize(cpu_stack[cpu].size()-1); +} + +static int consumer_depth(unsigned int cpu) +{ + if (cpu_stack.size() <= cpu) + cpu_stack.resize(cpu + 1); + return cpu_stack[cpu].size(); +} + +static class power_consumer *current_consumer(unsigned int cpu) +{ + if (cpu_stack.size() <= cpu) + cpu_stack.resize(cpu + 1); + if (cpu_stack[cpu].size()) + + return cpu_stack[cpu][cpu_stack[cpu].size()-1]; + + return NULL; +} + +static void clear_consumers(void) +{ + unsigned int i; + for (i = 0; i < cpu_stack.size(); i++) + cpu_stack[i].resize(0); +} + +static void consumer_child_time(unsigned int cpu, uint64_t time) +{ + unsigned int i; + if (cpu_stack.size() <= cpu) + cpu_stack.resize(cpu + 1); + for (i = 0; i < cpu_stack[cpu].size(); i++) + cpu_stack[cpu][i]->child_runtime += time; +} + +static void set_wakeup_pending(unsigned int cpu) +{ + if (cpu_credit.size() <= cpu) + cpu_credit.resize(cpu + 1); + + cpu_credit[cpu] = 1; +} + +static void clear_wakeup_pending(unsigned int cpu) +{ + if (cpu_credit.size() <= cpu) + cpu_credit.resize(cpu + 1); + + cpu_credit[cpu] = 0; +} + +static int get_wakeup_pending(unsigned int cpu) +{ + if (cpu_credit.size() <= cpu) + cpu_credit.resize(cpu + 1); + return cpu_credit[cpu]; +} + +static void change_blame(unsigned int cpu, class power_consumer *consumer, int level) +{ + if (cpu_level[cpu] >= level) + return; + cpu_blame[cpu] = consumer; + cpu_level[cpu] = level; +} + +static void consume_blame(unsigned int cpu) +{ + if (!get_wakeup_pending(cpu)) + return; + if (cpu_level.size() <= cpu) + return; + if (cpu_blame.size() <= cpu) + return; + if (!cpu_blame[cpu]) + return; + + cpu_blame[cpu]->wake_ups++; + cpu_blame[cpu] = NULL; + cpu_level[cpu] = 0; + clear_wakeup_pending(cpu); +} + + +class perf_process_bundle: public perf_bundle +{ + virtual void handle_trace_point(void *trace, int cpu, uint64_t time); +}; + +static bool comm_is_xorg(char *comm) +{ + return strcmp(comm, "Xorg") == 0 || strcmp(comm, "X") == 0; +} + +/* some processes shouldn't be blamed for the wakeup if they wake a process up... for now this is a hardcoded list */ +int dont_blame_me(char *comm) +{ + if (comm_is_xorg(comm)) + return 1; + if (strcmp(comm, "dbus-daemon") == 0) + return 1; + + return 0; +} + +static char * get_pevent_field_str(void *trace, struct event_format *event, struct format_field *field) +{ + unsigned long long offset, len; + if (field->flags & FIELD_IS_DYNAMIC) { + offset = field->offset; + len = field->size; + offset = pevent_read_number(event->pevent, (char *)trace + offset, len); + offset &= 0xffff; + return (char *)trace + offset; + } + /** no __data_loc field type*/ + return (char *)trace + field->offset; +} + +void perf_process_bundle::handle_trace_point(void *trace, int cpu, uint64_t time) +{ + struct event_format *event; + struct pevent_record rec; /* holder */ + struct format_field *field; + unsigned long long val; + int type; + int ret; + + rec.data = trace; + + type = pevent_data_type(perf_event::pevent, &rec); + event = pevent_find_event(perf_event::pevent, type); + if (!event) + return; + + if (time < first_stamp) + first_stamp = time; + + if (time > last_stamp) { + last_stamp = time; + measurement_time = (0.0001 + last_stamp - first_stamp) / 1000000000 ; + } + + if (strcmp(event->name, "sched_switch") == 0) { + class process *old_proc = NULL; + class process *new_proc = NULL; + const char *next_comm; + int next_pid; + int prev_pid; + + field = pevent_find_any_field(event, "next_comm"); + if (!field || !(field->flags & FIELD_IS_STRING)) + return; /* ?? */ + + next_comm = get_pevent_field_str(trace, event, field); + + ret = pevent_get_field_val(NULL, event, "next_pid", &rec, &val, 0); + if (ret < 0) + return; + next_pid = (int)val; + + ret = pevent_get_field_val(NULL, event, "prev_pid", &rec, &val, 0); + if (ret < 0) + return; + prev_pid = (int)val; + + /* find new process pointer */ + new_proc = find_create_process(next_comm, next_pid); + + /* find the old process pointer */ + + while (consumer_depth(cpu) > 1) { + pop_consumer(cpu); + } + + if (consumer_depth(cpu) == 1) + old_proc = (class process *)current_consumer(cpu); + + if (old_proc && strcmp(old_proc->name(), "process")) + old_proc = NULL; + + /* retire the old process */ + + if (old_proc) { + old_proc->deschedule_thread(time, prev_pid); + old_proc->waker = NULL; + } + + if (consumer_depth(cpu)) + pop_consumer(cpu); + + push_consumer(cpu, new_proc); + + /* start new process */ + new_proc->schedule_thread(time, next_pid); + + if (strncmp(next_comm,"migration/", 10) && strncmp(next_comm,"kworker/", 8) && strncmp(next_comm, "kondemand/",10)) { + if (next_pid) { + /* If someone woke us up.. blame him instead */ + if (new_proc->waker) { + change_blame(cpu, new_proc->waker, LEVEL_PROCESS); + } else { + change_blame(cpu, new_proc, LEVEL_PROCESS); + } + } + + consume_blame(cpu); + } + new_proc->waker = NULL; + } + else if (strcmp(event->name, "sched_wakeup") == 0) { + class power_consumer *from = NULL; + class process *dest_proc = NULL; + class process *from_proc = NULL; + const char *comm; + int flags; + int pid; + + ret = pevent_get_common_field_val(NULL, event, "common_flags", &rec, &val, 0); + if (ret < 0) + return; + flags = (int)val; + + if ( (flags & TRACE_FLAG_HARDIRQ) || (flags & TRACE_FLAG_SOFTIRQ)) { + class timer *timer; + timer = (class timer *) current_consumer(cpu); + if (timer && strcmp(timer->name(), "timer")==0) { + if (strcmp(timer->handler, "delayed_work_timer_fn") && + strcmp(timer->handler, "hrtimer_wakeup") && + strcmp(timer->handler, "it_real_fn")) + from = timer; + } + /* woken from interrupt */ + /* TODO: find the current irq handler and set "from" to that */ + } else { + from = current_consumer(cpu); + } + + + field = pevent_find_any_field(event, "comm"); + + if (!field || !(field->flags & FIELD_IS_STRING)) + return; + + comm = get_pevent_field_str(trace, event, field); + + ret = pevent_get_field_val(NULL, event, "pid", &rec, &val, 0); + if (ret < 0) + return; + pid = (int)val; + + dest_proc = find_create_process(comm, pid); + + if (from && strcmp(from->name(), "process")!=0){ + /* not a process doing the wakeup */ + from = NULL; + from_proc = NULL; + } else { + from_proc = (class process *) from; + } + + if (from_proc && (dest_proc->running == 0) && (dest_proc->waker == NULL) && (pid != 0) && !dont_blame_me(from_proc->comm)) + dest_proc->waker = from; + if (from) + dest_proc->last_waker = from; + + /* Account processes that wake up X specially */ + if (from && dest_proc && comm_is_xorg(dest_proc->comm)) + from->xwakes ++ ; + + } + else if (strcmp(event->name, "irq_handler_entry") == 0) { + class interrupt *irq = NULL; + const char *handler; + int nr; + + field = pevent_find_any_field(event, "name"); + if (!field || !(field->flags & FIELD_IS_STRING)) + return; /* ?? */ + + handler = get_pevent_field_str(trace, event, field); + + ret = pevent_get_field_val(NULL, event, "irq", &rec, &val, 0); + if (ret < 0) + return; + nr = (int)val; + + irq = find_create_interrupt(handler, nr, cpu); + + + push_consumer(cpu, irq); + + irq->start_interrupt(time); + + if (strstr(irq->handler, "timer") ==NULL) + change_blame(cpu, irq, LEVEL_HARDIRQ); + + } + + else if (strcmp(event->name, "irq_handler_exit") == 0) { + class interrupt *irq = NULL; + uint64_t t; + + /* find interrupt (top of stack) */ + irq = (class interrupt *)current_consumer(cpu); + if (!irq || strcmp(irq->name(), "interrupt")) + return; + pop_consumer(cpu); + /* retire interrupt */ + t = irq->end_interrupt(time); + consumer_child_time(cpu, t); + } + + else if (strcmp(event->name, "softirq_entry") == 0) { + class interrupt *irq = NULL; + const char *handler = NULL; + int vec; + + ret = pevent_get_field_val(NULL, event, "vec", &rec, &val, 0); + if (ret < 0) { + fprintf(stderr, "softirq_entry event returned no vector number?\n"); + return; + } + vec = (int)val; + + if (vec <= 9) + handler = softirqs[vec]; + + if (!handler) + return; + + irq = find_create_interrupt(handler, vec, cpu); + + push_consumer(cpu, irq); + + irq->start_interrupt(time); + change_blame(cpu, irq, LEVEL_SOFTIRQ); + } + else if (strcmp(event->name, "softirq_exit") == 0) { + class interrupt *irq = NULL; + uint64_t t; + + irq = (class interrupt *) current_consumer(cpu); + if (!irq || strcmp(irq->name(), "interrupt")) + return; + pop_consumer(cpu); + /* pop irq */ + t = irq->end_interrupt(time); + consumer_child_time(cpu, t); + } + else if (strcmp(event->name, "timer_expire_entry") == 0) { + class timer *timer = NULL; + uint64_t function; + uint64_t tmr; + + ret = pevent_get_field_val(NULL, event, "function", &rec, &val, 0); + if (ret < 0) { + fprintf(stderr, "timer_expire_entry event returned no function value?\n"); + return; + } + function = (uint64_t)val; + + timer = find_create_timer(function); + + if (timer->is_deferred()) + return; + + ret = pevent_get_field_val(NULL, event, "timer", &rec, &val, 0); + if (ret < 0) { + fprintf(stderr, "softirq_entry event returned no timer ?\n"); + return; + } + tmr = (uint64_t)val; + + push_consumer(cpu, timer); + timer->fire(time, tmr); + + if (strcmp(timer->handler, "delayed_work_timer_fn")) + change_blame(cpu, timer, LEVEL_TIMER); + } + else if (strcmp(event->name, "timer_expire_exit") == 0) { + class timer *timer = NULL; + uint64_t tmr; + uint64_t t; + + ret = pevent_get_field_val(NULL, event, "timer", &rec, &val, 0); + if (ret < 0) + return; + tmr = (uint64_t)val; + + timer = (class timer *) current_consumer(cpu); + if (!timer || strcmp(timer->name(), "timer")) { + return; + } + pop_consumer(cpu); + t = timer->done(time, tmr); + if (t == ~0ULL) { + timer->fire(first_stamp, tmr); + t = timer->done(time, tmr); + } + consumer_child_time(cpu, t); + } + else if (strcmp(event->name, "hrtimer_expire_entry") == 0) { + class timer *timer = NULL; + uint64_t function; + uint64_t tmr; + + ret = pevent_get_field_val(NULL, event, "function", &rec, &val, 0); + if (ret < 0) + return; + function = (uint64_t)val; + + timer = find_create_timer(function); + + ret = pevent_get_field_val(NULL, event, "hrtimer", &rec, &val, 0); + if (ret < 0) + return; + tmr = (uint64_t)val; + + push_consumer(cpu, timer); + timer->fire(time, tmr); + + if (strcmp(timer->handler, "delayed_work_timer_fn")) + change_blame(cpu, timer, LEVEL_TIMER); + } + else if (strcmp(event->name, "hrtimer_expire_exit") == 0) { + class timer *timer = NULL; + uint64_t tmr; + uint64_t t; + + timer = (class timer *) current_consumer(cpu); + if (!timer || strcmp(timer->name(), "timer")) { + return; + } + + ret = pevent_get_field_val(NULL, event, "hrtimer", &rec, &val, 0); + if (ret < 0) + return; + tmr = (uint64_t)val; + + pop_consumer(cpu); + t = timer->done(time, tmr); + if (t == ~0ULL) { + timer->fire(first_stamp, tmr); + t = timer->done(time, tmr); + } + consumer_child_time(cpu, t); + } + else if (strcmp(event->name, "workqueue_execute_start") == 0) { + class work *work = NULL; + uint64_t function; + uint64_t wk; + + ret = pevent_get_field_val(NULL, event, "function", &rec, &val, 0); + if (ret < 0) + return; + function = (uint64_t)val; + + ret = pevent_get_field_val(NULL, event, "work", &rec, &val, 0); + if (ret < 0) + return; + wk = (uint64_t)val; + + work = find_create_work(function); + + + push_consumer(cpu, work); + work->fire(time, wk); + + + if (strcmp(work->handler, "do_dbs_timer") != 0 && strcmp(work->handler, "vmstat_update") != 0) + change_blame(cpu, work, LEVEL_WORK); + } + else if (strcmp(event->name, "workqueue_execute_end") == 0) { + class work *work = NULL; + uint64_t t; + uint64_t wk; + + ret = pevent_get_field_val(NULL, event, "work", &rec, &val, 0); + if (ret < 0) + return; + wk = (uint64_t)val; + + work = (class work *) current_consumer(cpu); + if (!work || strcmp(work->name(), "work")) { + return; + } + pop_consumer(cpu); + t = work->done(time, wk); + if (t == ~0ULL) { + work->fire(first_stamp, wk); + t = work->done(time, wk); + } + consumer_child_time(cpu, t); + } + else if (strcmp(event->name, "cpu_idle") == 0) { + pevent_get_field_val(NULL, event, "state", &rec, &val, 0); + if (val == (unsigned int)-1) + consume_blame(cpu); + else + set_wakeup_pending(cpu); + } + else if (strcmp(event->name, "power_start") == 0) { + set_wakeup_pending(cpu); + } + else if (strcmp(event->name, "power_end") == 0) { + consume_blame(cpu); + } + else if (strcmp(event->name, "i915_gem_ring_dispatch") == 0 + || strcmp(event->name, "i915_gem_request_submit") == 0) { + /* any kernel contains only one of the these tracepoints, + * the latter one got replaced by the former one */ + class power_consumer *consumer = NULL; + int flags; + + ret = pevent_get_common_field_val(NULL, event, "common_flags", &rec, &val, 0); + if (ret < 0) + return; + flags = (int)val; + + consumer = current_consumer(cpu); + /* currently we don't count graphic requests submitted from irq contect */ + if ( (flags & TRACE_FLAG_HARDIRQ) || (flags & TRACE_FLAG_SOFTIRQ)) { + consumer = NULL; + } + + + /* if we are X, and someone just woke us, account the GPU op to the guy waking us */ + if (consumer && strcmp(consumer->name(), "process")==0) { + class process *proc = NULL; + proc = (class process *) consumer; + if (comm_is_xorg(proc->comm) && proc->last_waker) { + consumer = proc->last_waker; + } + } + + + + if (consumer) { + consumer->gpu_ops++; + } + } + else if (strcmp(event->name, "writeback_inode_dirty") == 0) { + static uint64_t prev_time; + class power_consumer *consumer = NULL; + int dev; + + consumer = current_consumer(cpu); + + ret = pevent_get_field_val(NULL, event, "dev", &rec, &val, 0); + if (ret < 0) + + return; + dev = (int)val; + + if (consumer && strcmp(consumer->name(), + "process")==0 && dev > 0) { + + consumer->disk_hits++; + + /* if the previous inode dirty was > 1 second ago, it becomes a hard hit */ + if ((time - prev_time) > 1000000000) + consumer->hard_disk_hits++; + + prev_time = time; + } + } +} + +void start_process_measurement(void) +{ + if (!perf_events) { + perf_events = new perf_process_bundle(); + perf_events->add_event("sched:sched_switch"); + perf_events->add_event("sched:sched_wakeup"); + perf_events->add_event("irq:irq_handler_entry"); + perf_events->add_event("irq:irq_handler_exit"); + perf_events->add_event("irq:softirq_entry"); + perf_events->add_event("irq:softirq_exit"); + perf_events->add_event("timer:timer_expire_entry"); + perf_events->add_event("timer:timer_expire_exit"); + perf_events->add_event("timer:hrtimer_expire_entry"); + perf_events->add_event("timer:hrtimer_expire_exit"); + if (!perf_events->add_event("power:cpu_idle")){ + perf_events->add_event("power:power_start"); + perf_events->add_event("power:power_end"); + } + perf_events->add_event("workqueue:workqueue_execute_start"); + perf_events->add_event("workqueue:workqueue_execute_end"); + perf_events->add_event("i915:i915_gem_ring_dispatch"); + perf_events->add_event("i915:i915_gem_request_submit"); + perf_events->add_event("writeback:writeback_inode_dirty"); + } + + first_stamp = ~0ULL; + last_stamp = 0; + perf_events->start(); +} + +void end_process_measurement(void) +{ + if (!perf_events) + return; + + perf_events->stop(); +} + + +static bool power_cpu_sort(class power_consumer * i, class power_consumer * j) +{ + double iW, jW; + + iW = i->Witts(); + jW = j->Witts(); + + if (equals(iW, jW)) { + double iR, jR; + + iR = i->accumulated_runtime - i->child_runtime; + jR = j->accumulated_runtime - j->child_runtime; + + if (equals(iR, jR)) + return i->wake_ups > j->wake_ups; + return (iR > jR); + } + + return (iW > jW); +} + +double total_wakeups(void) +{ + double total = 0; + unsigned int i; + for (i = 0; i < all_power.size() ; i++) + total += all_power[i]->wake_ups; + + total = total / measurement_time; + + + return total; +} + +double total_gpu_ops(void) +{ + double total = 0; + unsigned int i; + for (i = 0; i < all_power.size() ; i++) + total += all_power[i]->gpu_ops; + + + total = total / measurement_time; + + + return total; +} + +double total_disk_hits(void) +{ + double total = 0; + unsigned int i; + for (i = 0; i < all_power.size() ; i++) + total += all_power[i]->disk_hits; + + + total = total / measurement_time; + + + return total; +} + + +double total_hard_disk_hits(void) +{ + double total = 0; + unsigned int i; + for (i = 0; i < all_power.size() ; i++) + total += all_power[i]->hard_disk_hits; + + + total = total / measurement_time; + + + return total; +} + +double total_xwakes(void) +{ + double total = 0; + unsigned int i; + for (i = 0; i < all_power.size() ; i++) + total += all_power[i]->xwakes; + + + total = total / measurement_time; + + + return total; +} + +void process_update_display(void) +{ + unsigned int i; + WINDOW *win; + double pw; + double joules; + int tl; + int tlt; + int tlr; + + int show_power; + int need_linebreak = 0; + + sort(all_power.begin(), all_power.end(), power_cpu_sort); + + show_power = global_power_valid(); + + win = get_ncurses_win("Overview"); + if (!win) + return; + + wclear(win); + + wmove(win, 1,0); + +#if 0 + double sum; + calculate_params(); + sum = 0.0; + sum += get_parameter_value("base power"); + for (i = 0; i < all_power.size(); i++) { + sum += all_power[i]->Witts(); + } + + wprintw(win, _("Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n\n"), + all_parameters.guessed_power, global_power(), sum); +#endif + + pw = global_power(); + joules = global_joules(); + tl = global_time_left() / 60; + tlt = (tl /60); + tlr = tl % 60; + + if (pw > 0.0001) { + char buf[32]; + wprintw(win, _("The battery reports a discharge rate of %sW\n"), + fmt_prefix(pw, buf)); + wprintw(win, _("The energy consumed was %sJ\n"), + fmt_prefix(joules, buf)); + need_linebreak = 1; + } + if (tl > 0 && pw > 0.0001) { + wprintw(win, _("The estimated remaining time is %i hours, %i minutes\n"), tlt, tlr); + need_linebreak = 1; + } + + if (need_linebreak) + wprintw(win, "\n"); + + + wprintw(win, "%s: %3.1f %s, %3.1f %s, %3.1f %s %3.1f%% %s\n\n",_("Summary"), total_wakeups(), _("wakeups/second"), total_gpu_ops(), _("GPU ops/seconds"), total_disk_hits(), _("VFS ops/sec and"), total_cpu_time()*100, _("CPU use")); + + + if (show_power) + wprintw(win, "%s %s %s %s %s\n", _("Power est."), _("Usage"), _("Events/s"), _("Category"), _("Description")); + else + wprintw(win, " %s %s %s %s\n", _("Usage"), _("Events/s"), _("Category"), _("Description")); + + for (i = 0; i < all_power.size(); i++) { + char power[16]; + char name[20]; + char usage[20]; + char events[20]; + char descr[128]; + + format_watts(all_power[i]->Witts(), power, 10); + if (!show_power) + strcpy(power, " "); + snprintf(name, sizeof(name), "%s", all_power[i]->type()); + + align_string(name, 14, 20); + + if (all_power[i]->events() == 0 && all_power[i]->usage() == 0 && all_power[i]->Witts() == 0) + break; + + usage[0] = 0; + if (all_power[i]->usage_units()) { + if (all_power[i]->usage() < 1000) + snprintf(usage, sizeof(usage), "%5.1f%s", all_power[i]->usage(), all_power[i]->usage_units()); + else + snprintf(usage, sizeof(usage), "%5i%s", (int)all_power[i]->usage(), all_power[i]->usage_units()); + } + + align_string(usage, 14, 20); + + snprintf(events, sizeof(events), "%5.1f", all_power[i]->events()); + if (!all_power[i]->show_events()) + events[0] = 0; + else if (all_power[i]->events() <= 0.3) + snprintf(events, sizeof(events), "%5.2f", all_power[i]->events()); + + align_string(events, 12, 20); + wprintw(win, "%s %s %s %s %s\n", power, usage, events, name, pretty_print(all_power[i]->description(), descr, 128)); + } +} + +void report_process_update_display(void) +{ + unsigned int i; + unsigned int total; + int show_power, cols, rows, idx; + + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "clear_block", "software"); + + /* Set Table attributes, rows, and cols */ + cols=7; + sort(all_power.begin(), all_power.end(), power_cpu_sort); + show_power = global_power_valid(); + if (show_power) + cols=8; + + idx=cols; + + total = all_power.size(); + if (total > 100) + total = 100; + + rows=total+1; + table_attributes std_table_css; + init_nowarp_table_attr(&std_table_css, rows, cols); + + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Set array of data in row Major order */ + string *software_data = new string[cols * rows]; + software_data[0]=__("Usage"); + software_data[1]=__("Wakeups/s"); + software_data[2]=__("GPU ops/s"); + software_data[3]=__("Disk IO/s"); + software_data[4]=__("GFX Wakeups/s"); + software_data[5]=__("Category"); + software_data[6]=__("Description"); + + if (show_power) + software_data[7]=__("PW Estimate"); + + + for (i = 0; i < total; i++) { + char power[16]; + char name[20]; + char usage[20]; + char wakes[20]; + char gpus[20]; + char disks[20]; + char xwakes[20]; + char descr[128]; + format_watts(all_power[i]->Witts(), power, 10); + + if (!show_power) + strcpy(power, " "); + snprintf(name, sizeof(name), "%s", all_power[i]->type()); + + if (strcmp(name, "Device") == 0) + continue; + + if (all_power[i]->events() == 0 && all_power[i]->usage() == 0 + && all_power[i]->Witts() == 0) + break; + + usage[0] = 0; + if (all_power[i]->usage_units()) { + if (all_power[i]->usage() < 1000) + snprintf(usage, sizeof(usage), "%5.1f%s", all_power[i]->usage(), all_power[i]->usage_units()); + else + snprintf(usage, sizeof(usage), "%5i%s", (int)all_power[i]->usage(), all_power[i]->usage_units()); + } + snprintf(wakes, sizeof(wakes), "%5.1f", all_power[i]->wake_ups / measurement_time); + if (all_power[i]->wake_ups / measurement_time <= 0.3) + snprintf(wakes, sizeof(wakes), "%5.2f", all_power[i]->wake_ups / measurement_time); + snprintf(gpus, sizeof(gpus), "%5.1f", all_power[i]->gpu_ops / measurement_time); + snprintf(disks, sizeof(disks), "%5.1f (%5.1f)", all_power[i]->hard_disk_hits / measurement_time, + all_power[i]->disk_hits / measurement_time); + snprintf(xwakes, sizeof(xwakes), "%5.1f", all_power[i]->xwakes / measurement_time); + if (!all_power[i]->show_events()) { + wakes[0] = 0; + gpus[0] = 0; + disks[0] = 0; + } + + if (all_power[i]->gpu_ops == 0) + gpus[0] = 0; + if (all_power[i]->wake_ups == 0) + wakes[0] = 0; + if (all_power[i]->disk_hits == 0) + disks[0] = 0; + if (all_power[i]->xwakes == 0) + xwakes[0] = 0; + + software_data[idx]=string(usage); + idx+=1; + + software_data[idx]=string(wakes); + idx+=1; + + software_data[idx]=string(gpus); + idx+=1; + + software_data[idx]=string(disks); + idx+=1; + + software_data[idx]=string(xwakes); + idx+=1; + + software_data[idx]=string(name); + idx+=1; + + software_data[idx]=string(pretty_print(all_power[i]->description(), descr, 128)); + idx+=1; + if (show_power) { + software_data[idx]=string(power); + idx+=1; + } + } + + /* Report Output */ + report.add_div(&div_attr); + report.add_title(&title_attr, __("Overview of Software Power Consumers")); + report.add_table(software_data, &std_table_css); + report.end_div(); + delete [] software_data; +} + +void report_summary(void) +{ + unsigned int i; + unsigned int total; + int show_power; + int rows, cols, idx; + + sort(all_power.begin(), all_power.end(), power_cpu_sort); + show_power = global_power_valid(); + + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "clear_block", "summary"); + + + /* Set table attributes, rows, and cols */ + cols=4; + if (show_power) + cols=5; + idx=cols; + total = all_power.size(); + if (total > 10) + total = 10; + rows=total+1; + table_attributes std_table_css; + init_std_table_attr(&std_table_css, rows, cols); + + /* Set title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Set array for summary */ + int summary_size =12; + string *summary = new string [summary_size]; + summary[0]=__("Target:"); + summary[1]=__("1 units/s"); + summary[2]=__("System: "); + summary[3]= double_to_string(total_wakeups()); + summary[3].append(__(" wakeup/s")); + summary[4]=__("CPU: "); + summary[5]= double_to_string(total_cpu_time()*100); + summary[5].append(__("\% usage")); + summary[6]=__("GPU:"); + summary[7]=double_to_string(total_gpu_ops()); + summary[7].append(__(" ops/s")); + summary[8]=__("GFX:"); + summary[9]=double_to_string(total_xwakes()); + summary[9].append(__(" wakeups/s")); + summary[10]=__("VFS:"); + summary[11]= double_to_string(total_disk_hits()); + summary[11].append(__(" ops/s")); + + /* Set array of data in row Major order */ + string *summary_data = new string[cols * (rows + 1)]; + summary_data[0]=__("Usage"); + summary_data[1]=__("Events/s"); + summary_data[2]=__("Category"); + summary_data[3]=__("Description"); + if (show_power) + summary_data[4]=__("PW Estimate"); + + for (i = 0; i < all_power.size(); i++) { + char power[16]; + char name[20]; + char usage[20]; + char events[20]; + char descr[128]; + format_watts(all_power[i]->Witts(), power, 10); + + if (!show_power) + strcpy(power, " "); + snprintf(name, sizeof(name), "%s", all_power[i]->type()); + + if (i > total) + break; + + if (all_power[i]->events() == 0 && all_power[i]->usage() == 0 && + all_power[i]->Witts() == 0) + break; + + usage[0] = 0; + if (all_power[i]->usage_units()) { + if (all_power[i]->usage() < 1000) + snprintf(usage, sizeof(usage), "%5.1f%s", all_power[i]->usage_summary(), + all_power[i]->usage_units_summary()); + else + snprintf(usage, sizeof(usage), "%5i%s", (int)all_power[i]->usage_summary(), + all_power[i]->usage_units_summary()); + } + snprintf(events, sizeof(events), "%5.1f", all_power[i]->events()); + if (!all_power[i]->show_events()) + events[0] = 0; + else if (all_power[i]->events() <= 0.3) + snprintf(events, sizeof(events), "%5.2f", all_power[i]->events()); + + summary_data[idx]=string(usage); + idx+=1; + + summary_data[idx]=string(events); + idx+=1; + + summary_data[idx]=string(name); + idx+=1; + + summary_data[idx]=string(pretty_print(all_power[i]->description(), descr, 128)); + idx+=1; + + if (show_power){ + summary_data[idx]=power; + idx+=1; + } + } + + /* Report Summary for all */ + report.add_summary_list(summary, summary_size); + report.add_div(&div_attr); + report.add_title(&title_attr, __("Top 10 Power Consumers")); + report.add_table(summary_data, &std_table_css); + report.end_div(); + delete [] summary; + delete [] summary_data; +} + + +void process_process_data(void) +{ + if (!perf_events) + return; + + clear_processes(); + clear_interrupts(); + + all_power.erase(all_power.begin(), all_power.end()); + clear_consumers(); + + + cpu_credit.resize(0, 0); + cpu_credit.resize(get_max_cpu()+1, 0); + cpu_level.resize(0, 0); + cpu_level.resize(get_max_cpu()+1, 0); + cpu_blame.resize(0, NULL); + cpu_blame.resize(get_max_cpu()+1, NULL); + + + + /* process data */ + perf_events->process(); + perf_events->clear(); + + run_devpower_list(); + + merge_processes(); + + all_processes_to_all_power(); + all_interrupts_to_all_power(); + all_timers_to_all_power(); + all_work_to_all_power(); + all_devices_to_all_power(); + + sort(all_power.begin(), all_power.end(), power_cpu_sort); +} + + +double total_cpu_time(void) +{ + unsigned int i; + double total = 0.0; + for (i = 0; i < all_power.size() ; i++) { + if (all_power[i]->child_runtime > all_power[i]->accumulated_runtime) + all_power[i]->child_runtime = 0; + total += all_power[i]->accumulated_runtime - all_power[i]->child_runtime; + } + + total = (total / (0.0001 + last_stamp - first_stamp)); + + return total; +} + + + +void end_process_data(void) +{ + report_utilization("cpu-consumption", total_cpu_time()); + report_utilization("cpu-wakeups", total_wakeups()); + report_utilization("gpu-operations", total_gpu_ops()); + report_utilization("disk-operations", total_disk_hits()); + report_utilization("disk-operations-hard", total_hard_disk_hits()); + report_utilization("xwakes", total_xwakes()); + + all_power.erase(all_power.begin(), all_power.end()); + clear_processes(); + clear_proc_devices(); + clear_interrupts(); + clear_timers(); + clear_work(); + clear_consumers(); + + perf_events->clear(); + +} + +void clear_process_data(void) +{ + if (perf_events) + perf_events->release(); + delete perf_events; +} + diff --git a/src/process/interrupt.cpp b/src/process/interrupt.cpp new file mode 100644 index 0000000..a6553b1 --- /dev/null +++ b/src/process/interrupt.cpp @@ -0,0 +1,131 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include "process.h" +#include "interrupt.h" +#include "../lib.h" + +const char* softirqs[] = { + "HI_SOFTIRQ", + "timer(softirq)", + "net tx(softirq)", + "net_rx(softirq)", + "block(softirq)", + "block_iopoll(softirq)", + "tasklet(softirq)", + "sched(softirq)", + "hrtimer(softirq)", + "RCU(softirq)", + NULL +}; + + +interrupt::interrupt(const char *_handler, int _number) : power_consumer() +{ + char buf[128]; + running_since = 0; + number = _number; + pt_strcpy(handler, _handler); + raw_count = 0; + snprintf(desc, sizeof(desc), "[%i] %s", number, pretty_print(handler, buf, 128)); +} + + +vector <class interrupt *> all_interrupts; + +void interrupt::start_interrupt(uint64_t time) +{ + running_since = time; + raw_count ++; +} + +uint64_t interrupt::end_interrupt(uint64_t time) +{ + uint64_t delta; + + delta = time - running_since; + accumulated_runtime += delta; + return delta; +} + +const char * interrupt::description(void) +{ + if (child_runtime > accumulated_runtime) + child_runtime = 0; + return desc; +} + +double interrupt::usage_summary(void) +{ + double t; + t = (accumulated_runtime - child_runtime) / 1000000.0 / measurement_time / 10; + return t; +} + +const char * interrupt::usage_units_summary(void) +{ + return "%"; +} + + +class interrupt * find_create_interrupt(const char *_handler, int nr, int cpu) +{ + char handler[64]; + unsigned int i; + class interrupt *new_irq; + + pt_strcpy(handler, _handler); + if (strcmp(handler, "timer")==0) + sprintf(handler, "timer/%i", cpu); + + + for (i = 0; i < all_interrupts.size(); i++) { + if (all_interrupts[i] && all_interrupts[i]->number == nr && strcmp(handler, all_interrupts[i]->handler) == 0) + return all_interrupts[i]; + } + + new_irq = new class interrupt(handler, nr); + all_interrupts.push_back(new_irq); + return new_irq; +} + +void all_interrupts_to_all_power(void) +{ + unsigned int i; + for (i = 0; i < all_interrupts.size() ; i++) + if (all_interrupts[i]->accumulated_runtime) + all_power.push_back(all_interrupts[i]); +} + +void clear_interrupts(void) +{ + std::vector<class interrupt *>::iterator it = all_interrupts.begin(); + while (it != all_interrupts.end()) { + delete *it; + it = all_interrupts.erase(it); + } +} diff --git a/src/process/interrupt.h b/src/process/interrupt.h new file mode 100644 index 0000000..8d3a4d7 --- /dev/null +++ b/src/process/interrupt.h @@ -0,0 +1,62 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_INTERRUPT_H +#define _INCLUDE_GUARD_INTERRUPT_H + +#include <stdint.h> + +#include "powerconsumer.h" + +class interrupt : public power_consumer { + uint64_t running_since; + char desc[256]; +public: + char handler[32]; + int number; + + int raw_count; + + interrupt(const char *_handler, int _number); + + virtual void start_interrupt(uint64_t time); + virtual uint64_t end_interrupt(uint64_t time); + + virtual const char * description(void); + + virtual const char * name(void) { return "interrupt"; }; + virtual const char * type(void) { return "Interrupt"; }; + virtual double usage_summary(void); + virtual const char * usage_units_summary(void); +}; + +extern vector <class interrupt *> all_interrupts; +extern const char* softirqs[]; + + +extern class interrupt * find_create_interrupt(const char *_handler, int nr, int cpu); +extern void all_interrupts_to_all_power(void); +extern void clear_interrupts(void); + +#endif diff --git a/src/process/powerconsumer.cpp b/src/process/powerconsumer.cpp new file mode 100644 index 0000000..2ff2132 --- /dev/null +++ b/src/process/powerconsumer.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "powerconsumer.h" +#include "process.h" +#include "../parameters/parameters.h" + +double power_consumer::Witts(void) +{ + double cost; + double timecost; + double wakeupcost; + double gpucost; + double disk_cost; + double hard_disk_cost; + double xwake_cost; + + if (child_runtime > accumulated_runtime) + child_runtime = 0; + + timecost = get_parameter_value("cpu-consumption"); + wakeupcost = get_parameter_value("cpu-wakeups"); + gpucost = get_parameter_value("gpu-operations"); + disk_cost = get_parameter_value("disk-operations"); + hard_disk_cost = get_parameter_value("disk-operations-hard"); + xwake_cost = get_parameter_value("xwakes"); + + cost = 0; + + cost += wakeupcost * wake_ups / 10000.0; + cost += ( (accumulated_runtime - child_runtime) / 1000000000.0) * timecost; + cost += gpucost * gpu_ops / 100.0; + cost += hard_disk_cost * hard_disk_hits / 100.0; + cost += disk_cost * disk_hits / 100.0; + cost += xwake_cost * xwakes / 100.0; + + cost = cost / measurement_time; + + cost += power_charge; + + return cost; +} + +power_consumer::power_consumer(void) +{ + accumulated_runtime = 0; + child_runtime = 0; + disk_hits = 0; + wake_ups = 0; + gpu_ops = 0; + hard_disk_hits = 0; + xwakes = 0; + waker = NULL; + last_waker = NULL; + power_charge = 0.0; +} + +double power_consumer::usage(void) +{ + double t; + t = (accumulated_runtime - child_runtime) / 1000000.0 / measurement_time; + if (t < 0.7) + t = t * 1000; + return t; +} + +const char * power_consumer::usage_units(void) +{ + double t; + t = (accumulated_runtime - child_runtime) / 1000000.0 / measurement_time; + if (t < 0.7) { + if (utf_ok) + return " µs/s"; + else + return " us/s"; + } + return " ms/s"; +} diff --git a/src/process/powerconsumer.h b/src/process/powerconsumer.h new file mode 100644 index 0000000..0ae384a --- /dev/null +++ b/src/process/powerconsumer.h @@ -0,0 +1,79 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_POWER_CONSUMER_ +#define __INCLUDE_GUARD_POWER_CONSUMER_ + +#include <stdint.h> +#include <vector> +#include <algorithm> + +using namespace std; + +extern double measurement_time; + +class power_consumer; + +class power_consumer { + +public: + uint64_t accumulated_runtime; + uint64_t child_runtime; + int disk_hits; + int wake_ups; + int gpu_ops; + int hard_disk_hits; /* those which are likely a wakeup of the disk */ + int xwakes; + + double power_charge; /* power consumed by devices opened by this process */ + class power_consumer *waker; + class power_consumer *last_waker; + + power_consumer(void); + virtual ~power_consumer() {}; + + virtual double Witts(void); + virtual const char * description(void) { return ""; }; + + virtual const char * name(void) { return "abstract"; }; + virtual const char * type(void) { return "abstract"; }; + + virtual double usage(void); + virtual const char * usage_units(void); + + virtual double usage_summary(void) { return usage();}; + virtual const char * usage_units_summary(void) { return usage_units(); }; + virtual double events(void) { return (wake_ups + gpu_ops + hard_disk_hits) / measurement_time;}; + virtual int show_events(void) { return 1; }; +}; + +extern vector <class power_consumer *> all_power; + +extern double total_wakeups(void); +extern double total_cpu_time(void); +extern double total_gpu_ops(void); + + + +#endif
\ No newline at end of file diff --git a/src/process/process.cpp b/src/process/process.cpp new file mode 100644 index 0000000..dad90ba --- /dev/null +++ b/src/process/process.cpp @@ -0,0 +1,246 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + + + +#include "process.h" +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> + +#include <iostream> +#include <fstream> +#include <algorithm> +#include <iterator> +#include "../lib.h" + + +vector <class process *> all_processes; + +void process::account_disk_dirty(void) +{ + disk_hits++; +} + +void process::schedule_thread(uint64_t time, int thread_id) +{ + running_since = time; + running = 1; +} + + +uint64_t process::deschedule_thread(uint64_t time, int thread_id) +{ + uint64_t delta; + + if (!running_since) + return 0; + + delta = time - running_since; + + if (time < running_since) + printf("%llu time %llu since \n", (unsigned long long)time, + (unsigned long long)running_since); + + if (thread_id == 0) /* idle thread */ + delta = 0; + accumulated_runtime += delta; + running = 0; + + return delta; +} + +static void cmdline_to_string(std::string& str) +{ + std::replace(str.begin(), str.end(), '\0', ' '); +} + + +process::process(const char *_comm, int _pid, int _tid) : power_consumer() +{ + char line[4097]; + ifstream file; + ssize_t pos; + + pt_strcpy(comm, _comm); + pid = _pid; + is_idle = 0; + running = 0; + last_waker = NULL; + waker = NULL; + is_kernel = 0; + tgid = _tid; + + if (_tid == 0) { + sprintf(line, "/proc/%i/status", _pid); + file.open(line); + while (file) { + file.getline(line, 4096); + line[4096] = '\0'; + if (strstr(line, "Tgid")) { + char *c; + c = strchr(line, ':'); + if (!c) + continue; + c++; + tgid = strtoull(c, NULL, 10); + break; + } + } + file.close(); + } + + if (strncmp(_comm, "kondemand/", 10) == 0) + is_idle = 1; + + pos = snprintf(desc, sizeof(desc), "[PID %d] ", pid); + + if (pos < 0) + pos = 0; + if ((size_t)pos > sizeof(desc)) + return; + + strncpy(desc + pos, comm, sizeof(desc) - pos - 1); + desc[sizeof(desc) - 1] = '\0'; + + sprintf(line, "/proc/%i/cmdline", _pid); + file.open(line, ios::binary); + if (file) { + std::string cmdline(std::istreambuf_iterator<char>(file), (std::istreambuf_iterator<char>())); + file.close(); + if (cmdline.size() < 1) { + is_kernel = 1; + snprintf(desc + pos, sizeof(desc) - pos, "[%s]", comm); + } else { + cmdline_to_string(cmdline); + strncpy(desc + pos, cmdline.c_str(), sizeof(desc) - pos - 1); + desc[sizeof(desc) - 1] = '\0'; + } + } +} + +const char * process::description(void) +{ + + if (child_runtime > accumulated_runtime) + child_runtime = 0; + + return desc; +} + +double process::usage_summary(void) +{ + double t; + t = (accumulated_runtime - child_runtime) / 1000000.0 / measurement_time / 10; + return t; +} + +const char * process::usage_units_summary(void) +{ + return "%"; +} + +class process * find_create_process(const char *comm, int pid) +{ + unsigned int i; + class process *new_proc; + + for (i = 0; i < all_processes.size(); i++) { + if (all_processes[i]->pid == pid && strcmp(comm, all_processes[i]->comm) == 0) + return all_processes[i]; + } + + new_proc = new class process(comm, pid); + all_processes.push_back(new_proc); + return new_proc; +} + +class process * find_create_process(char *comm, int pid) +{ + return find_create_process((const char*)comm, pid); +} + +static void merge_process(class process *one, class process *two) +{ + one->accumulated_runtime += two->accumulated_runtime; + one->child_runtime += two->child_runtime; + one->wake_ups += two->wake_ups; + one->disk_hits += two->disk_hits; + one->hard_disk_hits += two->hard_disk_hits; + one->xwakes += two->xwakes; + one->gpu_ops += two->gpu_ops; + one->power_charge += two->power_charge; +} + + +void merge_processes(void) +{ + std::vector<class process*>::iterator it1, it2; + class process *one, *two; + + it1 = all_processes.begin(); + while (it1 != all_processes.end()) { + it2 = it1 + 1; + one = *it1; + while (it2 != all_processes.end()) { + two = *it2; + /* fold threads */ + if (one->pid == two->tgid && two->tgid != 0) { + merge_process(one, two); + delete *it2; + it2 = all_processes.erase(it2); + continue; + } + /* find dupes and add up */ + if (!strcmp(one->desc, two->desc)) { + merge_process(one, two); + delete *it2; + it2 = all_processes.erase(it2); + continue; + } + ++it2; + } + ++it1; + } +} + +void all_processes_to_all_power(void) +{ + unsigned int i; + for (i = 0; i < all_processes.size() ; i++) + if (all_processes[i]->accumulated_runtime || + all_processes[i]->power_charge) + all_power.push_back(all_processes[i]); +} + +void clear_processes(void) +{ + std::vector <class process *>::iterator it = all_processes.begin(); + while (it != all_processes.end()) { + delete *it; + it = all_processes.erase(it); + } +} diff --git a/src/process/process.h b/src/process/process.h new file mode 100644 index 0000000..66293f7 --- /dev/null +++ b/src/process/process.h @@ -0,0 +1,96 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_PROCESS_H +#define _INCLUDE_GUARD_PROCESS_H + +#include <stdint.h> + +#include "powerconsumer.h" + +#ifdef __x86_64__ +#define BIT64 1 +#endif + +/* +Need to collect + * CPU time consumed by each application + * Number of wakeups out of idle -- received and wakeups sent + * Number of disk dirties (inode for now) + */ +class process : public power_consumer { + uint64_t running_since; +public: + char desc[256]; + int tgid; + char comm[16]; + int pid; + + + int is_idle; /* count this as if the cpu was idle */ + int running; + int is_kernel; /* kernel thread */ + + process(const char *_comm, int _pid, int _tid = 0); + + virtual void schedule_thread(uint64_t time, int thread_id); + virtual uint64_t deschedule_thread(uint64_t time, int thread_id = 0); + + virtual void account_disk_dirty(void); + + virtual const char * description(void); + virtual const char * name(void) { return "process"; }; + virtual const char * type(void) { return "Process"; }; + + virtual double usage_summary(void); + virtual const char * usage_units_summary(void); + +}; + +extern vector <class process *> all_processes; + +extern double measurement_time; + + +extern void start_process_measurement(void); +extern void end_process_measurement(void); +extern void process_process_data(void); +extern void end_process_data(void); +extern void clear_process_data(void); +extern void merge_processes(void); + +extern class process * find_create_process(const char *comm, int pid); +extern class process * find_create_process(char *comm, int pid); +extern void all_processes_to_all_power(void); + +extern void clear_processes(void); +extern void process_update_display(void); +extern void report_process_update_display(void); +extern void report_summary(void); + + + +extern void clear_timers(void); + +#endif diff --git a/src/process/processdevice.cpp b/src/process/processdevice.cpp new file mode 100644 index 0000000..00f48c8 --- /dev/null +++ b/src/process/processdevice.cpp @@ -0,0 +1,99 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "processdevice.h" +#include "../parameters/parameters.h" +#include <stdio.h> + +vector<class device_consumer *> all_proc_devices; + + +device_consumer::device_consumer(class device *dev) : power_consumer() +{ + device = dev; + power = device->power_usage(&all_results, &all_parameters); + prio = dev->grouping_prio(); +} + + +const char * device_consumer::description(void) +{ + snprintf(str, sizeof(str), "%s", device->human_name()); + return str; +} + +double device_consumer::Witts(void) +{ + return power; +} + +static void add_device(class device *device) +{ + class device_consumer *dev; + unsigned int i; + + /* first check if we want to be shown at all */ + + if (device->show_in_list() == 0) + return; + + /* then check if a device with the same underlying object is already registered */ + for (i = 0; i < all_proc_devices.size(); i++) { + class device_consumer *cdev; + cdev = all_proc_devices[i]; + if (device->real_path[0] != 0 && strcmp(cdev->device->real_path, device->real_path) == 0) { + /* we have a device with the same underlying object */ + + /* aggregate the power */ + cdev->power += device->power_usage(&all_results, &all_parameters); + + if (cdev->prio < device->grouping_prio()) { + cdev->device = device; + cdev->prio = device->grouping_prio(); + } + + return; + } + } + + dev = new class device_consumer(device); + all_power.push_back(dev); + all_proc_devices.push_back(dev); +} + +void all_devices_to_all_power(void) +{ + unsigned int i; + for (i = 0; i < all_devices.size(); i++) + add_device(all_devices[i]); +} + +void clear_proc_devices(void) +{ + std::vector<class device_consumer *>::iterator it = all_proc_devices.begin(); + while (it != all_proc_devices.end()) { + delete *it; + it = all_proc_devices.erase(it); + } +} diff --git a/src/process/processdevice.h b/src/process/processdevice.h new file mode 100644 index 0000000..3392d3e --- /dev/null +++ b/src/process/processdevice.h @@ -0,0 +1,55 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_DEVICE2_H +#define _INCLUDE_GUARD_DEVICE2_H + +#include <stdint.h> + +#include "powerconsumer.h" +#include "../devices/device.h" + +class device_consumer : public power_consumer { + char str[4096]; +public: + int prio; + double power; + class device *device; + device_consumer(class device *dev); + + virtual const char * description(void); + virtual const char * name(void) { return "device"; }; + virtual const char * type(void) { return "Device"; }; + virtual double Witts(void); + virtual double usage(void) { return device->utilization();}; + virtual const char * usage_units(void) {return device->util_units();}; + virtual int show_events(void) { return 0; }; +}; + +extern void all_devices_to_all_power(void); +extern vector<class device_consumer *> all_proc_devices; + +extern void clear_proc_devices(void); + +#endif diff --git a/src/process/timer.cpp b/src/process/timer.cpp new file mode 100644 index 0000000..5d9d2f8 --- /dev/null +++ b/src/process/timer.cpp @@ -0,0 +1,159 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <map> +#include <utility> + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include "timer.h" +#include "../lib.h" +#include "process.h" + +using namespace std; + +static bool timer_is_deferred(const char *handler) +{ + FILE *file; + bool ret = false; + char line[4096]; + + file = fopen("/proc/timer_stats", "r"); + if (!file) { + return ret; + } + + while (!feof(file)) { + if (fgets(line, 4096, file) == NULL) + break; + if (strstr(line, handler)) { + ret = (strstr(line, "D,") != NULL); + if (ret == true) + break; + } + } + fclose(file); + return ret; +} + +timer::timer(unsigned long address) : power_consumer() +{ + pt_strcpy(handler, kernel_function(address)); + raw_count = 0; + deferred = timer_is_deferred(handler); +} + + +static map<unsigned long, class timer *> all_timers; +static map<unsigned long, uint64_t> running_since; + +void timer::fire(uint64_t time, uint64_t timer_struct) +{ + running_since[timer_struct] = time; +} + +uint64_t timer::done(uint64_t time, uint64_t timer_struct) +{ + int64_t delta; + + if (running_since.find(timer_struct) == running_since.end()) + return ~0ULL; + + if (running_since[timer_struct] > time) + return 0; + + delta = time - running_since[timer_struct]; + + accumulated_runtime += delta; + + raw_count++; + + return delta; +} + +double timer::usage_summary(void) +{ + double t; + t = (accumulated_runtime - child_runtime) / 1000000.0 / measurement_time / 10; + return t; +} + +const char * timer::usage_units_summary(void) +{ + return "%"; +} + + + +static void add_timer(const pair<unsigned long, class timer*>& elem) +{ + all_power.push_back(elem.second); +} + +void all_timers_to_all_power(void) +{ + for_each(all_timers.begin(), all_timers.end(), add_timer); + +} + + +const char * timer::description(void) +{ + if (child_runtime > accumulated_runtime) + child_runtime = 0; + + snprintf(desc, sizeof(desc), "%s", handler); + return desc; +} + + +class timer * find_create_timer(uint64_t func) +{ + class timer * timer; + if (all_timers.find(func) != all_timers.end()) + return all_timers[func]; + + timer = new class timer(func); + all_timers[func] = timer; + return timer; + +} + +void clear_timers(void) +{ + std::map<unsigned long, class timer *>::iterator it = all_timers.begin(); + while (it != all_timers.end()) { + delete it->second; + all_timers.erase(it); + it = all_timers.begin(); + } + running_since.clear(); +} + +bool timer::is_deferred(void) +{ + return deferred; +} diff --git a/src/process/timer.h b/src/process/timer.h new file mode 100644 index 0000000..7718c3b --- /dev/null +++ b/src/process/timer.h @@ -0,0 +1,64 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_TIMER_H +#define _INCLUDE_GUARD_TIMER_H + +#include <stdint.h> + +#include "powerconsumer.h" + +class timer : public power_consumer { + char desc[256]; +public: + char handler[32]; + int raw_count; + bool deferred; + + timer(unsigned long timer_func); + + void fire(uint64_t time, uint64_t timer_struct); + uint64_t done(uint64_t time, uint64_t timer_struct); + bool is_deferred(void); + + virtual const char * description(void); + virtual const char * name(void) { return "timer"; }; + virtual const char * type(void) { return "Timer"; }; + virtual double usage_summary(void); + virtual const char * usage_units_summary(void); + +}; + +class timer_list { +public: + uint64_t timer_address; + uint64_t timer_func; +}; + + +extern void all_timers_to_all_power(void); +extern class timer * find_create_timer(uint64_t func); +extern void clear_timers(void); + +#endif diff --git a/src/process/work.cpp b/src/process/work.cpp new file mode 100644 index 0000000..1b5c71d --- /dev/null +++ b/src/process/work.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <map> +#include <utility> + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include "work.h" +#include "../lib.h" +#include "process.h" + +using namespace std; + + +work::work(unsigned long address) : power_consumer() +{ + pt_strcpy(handler, kernel_function(address)); + raw_count = 0; + snprintf(desc, sizeof(desc), "%s", handler); +} + + +static map<unsigned long, class work *> all_work; +static map<unsigned long, uint64_t> running_since; + +void work::fire(uint64_t time, uint64_t work_struct) +{ + running_since[work_struct] = time; +} + +uint64_t work::done(uint64_t time, uint64_t work_struct) +{ + int64_t delta; + + if (running_since.find(work_struct) == running_since.end()) + return ~0ULL; + + if (running_since[work_struct] > time) + return 0; + + delta = time - running_since[work_struct]; + + accumulated_runtime += delta; + + raw_count++; + + return delta; +} + +double work::usage_summary(void) +{ + double t; + t = (accumulated_runtime - child_runtime) / 1000000.0 / measurement_time / 10; + return t; +} + +const char * work::usage_units_summary(void) +{ + return "%"; +} + + + + +static void add_work(const pair<unsigned long, class work*>& elem) +{ + all_power.push_back(elem.second); +} + +void all_work_to_all_power(void) +{ + for_each(all_work.begin(), all_work.end(), add_work); + +} + +void clear_work(void) +{ + std::map<unsigned long, class work *>::iterator it = all_work.begin(); + while (it != all_work.end()) { + delete it->second; + all_work.erase(it); + it = all_work.begin(); + } + running_since.clear(); +} + + +const char * work::description(void) +{ + if (child_runtime > accumulated_runtime) + child_runtime = 0; + + return desc; +} + + +class work * find_create_work(uint64_t func) +{ + class work * work; + if (all_work.find(func) != all_work.end()) + return all_work[func]; + + work = new class work(func); + all_work[func] = work; + return work; +} diff --git a/src/process/work.h b/src/process/work.h new file mode 100644 index 0000000..ddd7c87 --- /dev/null +++ b/src/process/work.h @@ -0,0 +1,57 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_WORK_H +#define _INCLUDE_GUARD_WORK_H + +#include <stdint.h> + +#include "powerconsumer.h" + +class work : public power_consumer { + char desc[256]; +public: + char handler[32]; + int raw_count; + + work(unsigned long work_func); + + void fire(uint64_t time, uint64_t work_struct); + uint64_t done(uint64_t time, uint64_t work_struct); + + virtual const char * description(void); + virtual const char * name(void) { return "work"; }; + virtual const char * type(void) { return "kWork"; }; + virtual double usage_summary(void); + virtual const char * usage_units_summary(void); + +}; + + +extern void all_work_to_all_power(void); +extern class work * find_create_work(uint64_t func); + +extern void clear_work(void); + +#endif diff --git a/src/report/report-data-html.cpp b/src/report/report-data-html.cpp new file mode 100644 index 0000000..d9b713e --- /dev/null +++ b/src/report/report-data-html.cpp @@ -0,0 +1,128 @@ +#include "report-data-html.h" + +void init_div(struct tag_attr *div_attr, const char *css_class, const char *css_id) +{ + div_attr->css_class=css_class; + div_attr->css_id=css_id; +} + +void +init_top_table_attr(struct table_attributes *table_css, int rows, int cols){ + table_css->pos_table_title=L; + table_css->table_class="emphasis1"; + table_css->th_class="table_sysinfo"; + table_css->td_class=""; + table_css->tr_class=""; + table_css->title_mod=0; + table_css->rows=rows; + table_css->cols=cols; +} + +void init_title_attr(struct tag_attr *title_attr) +{ + title_attr->css_class="content_title"; + title_attr->css_id=""; +} + +void init_std_table_attr(struct table_attributes *table_css, int rows, int cols){ + table_css->table_class="emphasis2"; + table_css->tr_class="emph1"; + table_css->th_class="emph_title"; + table_css->td_class=""; + table_css->pos_table_title=T; + table_css->title_mod=0; + table_css->rows=rows; + table_css->cols=cols; +} +void init_std_side_table_attr(struct table_attributes *table_css, int rows, int cols){ + table_css->table_class="emphasis2 side_by_side_left"; + table_css->tr_class="emph1"; + table_css->th_class="emph_title"; + table_css->td_class=""; + table_css->pos_table_title=T; + table_css->title_mod=0; + table_css->rows=rows; + table_css->cols=cols; +} + + +void init_pkg_table_attr(struct table_attributes *table_css, int rows, int cols){ + table_css->table_class="emphasis2 side_by_side_left"; + table_css->tr_class=""; + table_css->th_class="title"; + table_css->td_class="package"; + table_css->pos_table_title=T; + table_css->title_mod=0; + table_css->rows=rows; + table_css->cols=cols; +} + +void init_core_table_attr(struct table_attributes *table_css, int title_mod, + int rows, int cols){ + table_css->table_class="emphasis2 side_by_side_left"; + table_css->tr_class=""; + table_css->th_class="title"; + table_css->td_class="core"; + table_css->pos_table_title=TC; + table_css->title_mod=title_mod; + table_css->rows=rows; + table_css->cols=cols; +} + +void init_cpu_table_attr(struct table_attributes *table_css, int title_mod, + int rows, int cols){ + table_css->table_class="emphasis2 side_by_side_left"; + table_css->tr_class=""; + table_css->th_class="title"; + table_css->td_class="cpu"; + table_css->pos_table_title=TLC; + table_css->title_mod=title_mod; + table_css->rows=rows; + table_css->cols=cols; +} + + +void init_nowarp_table_attr(struct table_attributes *table_css, int rows, int cols){ + table_css->table_class="emphasis2"; + table_css->tr_class="emph1"; + table_css->th_class="emph_title"; + table_css->td_class="no_wrap"; + table_css->pos_table_title=T; + table_css->title_mod=0; + table_css->rows=rows; + table_css->cols=cols; +} + +void init_tune_table_attr(struct table_attributes *table_css, int rows, int cols){ + table_css->table_class="emphasis2"; + table_css->tr_class="tune"; + table_css->th_class="emph_title"; + table_css->td_class=""; + table_css->pos_table_title=T; + table_css->rows=rows; + table_css->cols=cols; +} + +void init_wakeup_table_attr(struct table_attributes *table_css, int rows, int cols){ + table_css->table_class="emphasis2"; + table_css->tr_class="tune"; + table_css->th_class="emph_title"; + table_css->td_class=""; + table_css->pos_table_title=T; + table_css->rows=rows; + table_css->cols=cols; +} + +/* Other Helper Functions */ +string +double_to_string(double dval) +{ + ostringstream dtmp; + string str; + dtmp << dval; + str= dtmp.str(); + str = str.substr(0, str.find(".")+2); + return str; +} + + diff --git a/src/report/report-data-html.h b/src/report/report-data-html.h new file mode 100644 index 0000000..e506f5a --- /dev/null +++ b/src/report/report-data-html.h @@ -0,0 +1,76 @@ +#ifndef PowerTop_REPORT_DATA_HTML_H_C58C116411234A34AC2EFB8D23A69713 +#define PowerTop_REPORT_DATA_HTML_H_C58C116411234A34AC2EFB8D23A69713 + +#include <string> +#include <sstream> + +using namespace std; + +struct tag_attr { + const char *css_class; + const char *css_id; +}; +/* T:Top, L:Left, TL:Top-Left, TLC: Top-Left-Center */ +enum position { T, L, TL, TC, TLC }; + +struct table_attributes { + const char *table_class; + const char *td_class; + const char *tr_class; + const char *th_class; + position pos_table_title; + int title_mod; + int rows; + int cols; +}; + +struct table_size { + int rows; + int cols; +}; + + +/* Definition of css attributes for the cases that apply to powertop + * html report + * */ + +void +init_div(struct tag_attr *div_attr, const char *css_class, const char *css_id); + +void +init_top_table_attr(struct table_attributes *table_css, int rows, int cols); + +void +init_title_attr(struct tag_attr *title_attr); + +void +init_std_table_attr(struct table_attributes *table_css, int rows, int cols); + +void +init_std_side_table_attr(struct table_attributes *table_css, int rows, + int cols); + +void +init_pkg_table_attr(struct table_attributes *table_css, int rows, int cols); + +void +init_core_table_attr(struct table_attributes *table_css, int title_mod, + int rows, int cols); + +void +init_cpu_table_attr(struct table_attributes *table_css, int title_mod, + int rows, int cols); +void +init_nowarp_table_attr(struct table_attributes *table_css, int rows, int cols); + +void +init_tune_table_attr(struct table_attributes *table_css, int rows, int cols); + +void +init_wakeup_table_attr(struct table_attributes *table_css, int rows, int cols); + +/* Other helper functions */ +string +double_to_string(double dval); + +#endif diff --git a/src/report/report-formatter-base.cpp b/src/report/report-formatter-base.cpp new file mode 100644 index 0000000..4e10603 --- /dev/null +++ b/src/report/report-formatter-base.cpp @@ -0,0 +1,114 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Common part of report_formatter_csv and report_formatter_html. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +/* Uncomment to disable asserts */ +/*#define NDEBUG*/ + +#include <stdio.h> +#include <assert.h> +#include <stdarg.h> + +#include "report-formatter-base.h" + +/* ************************************************************************ */ + +const char * +report_formatter_string_base::get_result() +{ + return result.c_str(); +} + +/* ************************************************************************ */ + +void +report_formatter_string_base::clear_result() +{ + result.clear(); +} + +/* ************************************************************************ */ + +void +report_formatter_string_base::add(const char *str) +{ + assert(str); + + result += escape_string(str); +} + +/* ************************************************************************ */ + +void +report_formatter_string_base::add_exact(const char *str) +{ + assert(str); + + result += std::string(str); +} + +/* ************************************************************************ */ + +#define LINE_SIZE 8192 + +void +report_formatter_string_base::addv(const char *fmt, va_list ap) +{ + char str[LINE_SIZE]; + + assert(fmt); + + vsnprintf(str, sizeof(str), fmt, ap); + add(str); +} + +/* ************************************************************************ */ + +void +report_formatter_string_base::addf(const char *fmt, ...) +{ + va_list ap; + + assert(fmt); + + va_start(ap, fmt); + addv(fmt, ap); + va_end(ap); +} + +/* ************************************************************************ */ + +void +report_formatter_string_base::addf_exact(const char *fmt, ...) +{ + char str[LINE_SIZE]; + va_list ap; + + assert(fmt); + + va_start(ap, fmt); + vsnprintf(str, sizeof(str), fmt, ap); + add_exact(str); + va_end(ap); +} diff --git a/src/report/report-formatter-base.h b/src/report/report-formatter-base.h new file mode 100644 index 0000000..e35a2ff --- /dev/null +++ b/src/report/report-formatter-base.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Common part of report_formatter_csv and report_formatter_html. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +#ifndef _REPORT_FORMATTER_BASE_H_ +#define _REPORT_FORMATTER_BASE_H_ + +#include "report-formatter.h" + +class report_formatter_string_base: public report_formatter +{ +public: + virtual const char *get_result(); + virtual void clear_result(); + + virtual void add(const char *str); + virtual void addv(const char *fmt, va_list ap); + +protected: + void add_exact(const char *str); + void addf(const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); + void addf_exact(const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); + + virtual std::string escape_string(const char *str) = 0; + + std::string result; +}; + +#endif /* _REPORT_FORMATTER_BASE_H_ */ diff --git a/src/report/report-formatter-csv.cpp b/src/report/report-formatter-csv.cpp new file mode 100644 index 0000000..0360fd8 --- /dev/null +++ b/src/report/report-formatter-csv.cpp @@ -0,0 +1,163 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * CSV report generator. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +/* Uncomment to disable asserts */ +/*#define NDEBUG*/ + +#include <stdio.h> +#include <assert.h> +#include <stdarg.h> + +#include "report-formatter-csv.h" +#include "report-data-html.h" + + +/* ************************************************************************ */ +report_formatter_csv::report_formatter_csv() +{ + /* Do nothing special */ +} + +/* ************************************************************************ */ +void +report_formatter_csv::finish_report() +{ + /* Do nothing special */ +} + + +string +report_formatter_csv::escape_string(const char *str) +{ + string res; + + assert(str); + + for (const char *i = str; *i; i++) { + switch (*i) { + case '"': + res += '"'; +#ifdef REPORT_CSV_SPACE_NEED_QUOTES + case ' ': +#endif /* REPORT_CSV_SPACE_NEED_QUOTES */ + case '\n': + case REPORT_CSV_DELIMITER: + csv_need_quotes = true; + break; + } + + res += *i; + } + + return res; +} + + + + +/* Report Style */ +void +report_formatter_csv::add_header() +{ + add_exact("____________________________________________________________________\n"); +} + +void +report_formatter_csv::end_header() +{ + /* Do nothing */ +} + +void +report_formatter_csv::add_logo() +{ + add_exact("\t\t\tP o w e r T O P\n"); +} + + +void +report_formatter_csv::add_div(struct tag_attr * div_attr) +{ + add_exact("\n"); +} + +void +report_formatter_csv::end_div() +{ + /*Do nothing*/ +} + +void +report_formatter_csv::add_title(struct tag_attr *title_att, const char *title) +{ + add_exact("____________________________________________________________________\n"); + addf_exact(" * * * %s * * *\n", title); +} + +void +report_formatter_csv::add_navigation() +{ + /* No nav in csv - thinking on table of contents */ +} + +void +report_formatter_csv::add_summary_list(string *list, int size) +{ + int i; + add_exact("\n"); + for (i=0; i < size; i+=2){ + addf_exact("%s %s", list[i].c_str(), list[i+1].c_str()); + if(i < (size - 1)) + add_exact(";"); + } + add_exact("\n"); +} + +void +report_formatter_csv::add_table(string *system_data, struct table_attributes* tb_attr) +{ + int i, j; + int offset=0; + string tmp_str=""; + int empty_row=0; + add_exact("\n"); + for (i=0; i < tb_attr->rows; i++){ + for (j=0; j < tb_attr->cols; j++){ + offset = i * (tb_attr->cols) + j; + tmp_str=system_data[offset]; + + if(tmp_str == " ") + empty_row+=1; + else{ + addf_exact("%s", system_data[offset].c_str()); + if(j < (tb_attr->cols - 1)) + add_exact(";"); + } + } + if(empty_row < tb_attr->cols) + add_exact("\n"); + empty_row=0; + } +} diff --git a/src/report/report-formatter-csv.h b/src/report/report-formatter-csv.h new file mode 100644 index 0000000..7edfc01 --- /dev/null +++ b/src/report/report-formatter-csv.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * CSV report generator. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +#ifndef _REPORT_FORMATTER_CSV_H_ +#define _REPORT_FORMATTER_CSV_H_ + +#include <string> + +#include "report-formatter-base.h" + +/* Offices like semicolon separated values instead of comma */ +#define REPORT_CSV_DELIMITER ',' + +/* "a,b,c" vs "a, b, c" */ +/*#define REPORT_CSV_ADD_SPACE*/ + +/* Whether to escape with quotes empty cell values */ +/*#define REPORT_CSV_ESCAPE_EMPTY*/ + +/* Whether to escape with quotes empty cell values with spaces */ +/*#define REPORT_CSV_SPACE_NEED_QUOTES*/ + +using namespace std; + +/* ************************************************************************ */ + +class report_formatter_csv: public report_formatter_string_base +{ +public: + report_formatter_csv(); + void finish_report(); + + /* Report Style */ + void add_logo(); + void add_header(); + void end_header(); + void add_div(struct tag_attr *div_attr); + void end_div(); + void add_title(struct tag_attr *title_att, const char *title); + void add_navigation(); + void add_summary_list(string *list, int size); + void add_table(string *system_data, struct table_attributes *tb_attr); + +private: + void add_quotes(); + string escape_string(const char *str); + bool csv_need_quotes; + size_t text_start; +}; + +#endif /* _REPORT_FORMATTER_CSV_H_ */ diff --git a/src/report/report-formatter-html.cpp b/src/report/report-formatter-html.cpp new file mode 100644 index 0000000..387bd76 --- /dev/null +++ b/src/report/report-formatter-html.cpp @@ -0,0 +1,376 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * HTML report generator. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +/* Uncomment to disable asserts */ +/*#define NDEBUG*/ + +#include <stdio.h> +#include <assert.h> +#include <stdarg.h> + +#include "report-formatter-html.h" +#include "css.h" /* For HTML-report header */ + +/* ************************************************************************ */ + +#ifdef EXTERNAL_CSS_FILE /* Where is it defined? */ +static const char report_html_alternative_head[] = + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" " + "\"http://www.w3.org/TR/html4/loose.dtd\">\n" + "<html>\n" + "<head>\n" + "<title>PowerTOP report</title>\n" + "<link rel=\"stylesheet\" href=\"powertop.css\">\n" + "</head>\n" + "<body>\n"; +#endif /* EXTERNAL_CSS_FILE */ + +/* ************************************************************************ */ + +static const char report_html_footer[] = + "</body>\n" + "</html>\n"; + +/* ************************************************************************ */ + +void +report_formatter_html::init_markup() +{ + /*here all html code*/ +} + +/* ************************************************************************ */ + +report_formatter_html::report_formatter_html() +{ + init_markup(); + add_doc_header(); +} + +/* ************************************************************************ */ + +void +report_formatter_html::finish_report() +{ + add_doc_footer(); +} + +/* ************************************************************************ */ + +void +report_formatter_html::add_doc_header() +{ +#ifdef EXTERNAL_CSS_FILE /* Where is it defined? */ + add_exact(report_html_alternative_head); +#else /* !EXTERNAL_CSS_FILE */ + add_exact(css); +#endif /* !EXTERNAL_CSS_FILE */ +} + +/* ************************************************************************ */ + +void +report_formatter_html::add_doc_footer() +{ + add_exact(report_html_footer); +} + +/* ************************************************************************ */ +string +report_formatter_html::escape_string(const char *str) +{ + string res; + + assert(str); + + for (const char *i = str; *i; i++) { + switch (*i) { + case '<': + res += "<"; + continue; + case '>': + res += ">"; + continue; + case '&': + res += "&"; + continue; +#ifdef REPORT_HTML_ESCAPE_QUOTES + case '"': + res += """; + continue; + case '\'': + res += "'"; + continue; +#endif /* REPORT_HTML_ESCAPE_QUOTES */ + } + + res += *i; + } + + return res; +} + + +/* Report Style */ +void +report_formatter_html::add_logo() +{ + add_exact("<img alt=\"PowerTop\" class=\"pwtop_logo\" src=\"data:image/png;base64," + "iVBORw0KGgoAAAANSUhEUgAAAbQAAABDCAYAAAD01PBTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA" + "GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAGsxJREFUeNrsXQt4FNXZ/nLhmutq" + "VdAKMXJHTMhiLGAuLUEfSg2xSFSUgIkkRPQ3QiHxqcRwswQrRq2EBKjhapvU3yCgtaQ+CRGUSyAB" + "vNDfRhArqEA2FwjksvnPN0xokpnZPWd2dnd297w851kyt3OZ+c4773e+c8aro6MDODg4ODg4XB3e" + "vAk4ODg4ODihcXBwcHBwcELj4ODg4ODQDr68CWxCrPgbTlJwj33l4m81SSbeVBwcHBz2hRcPCqEG" + "ElaCSGKYBldXV4PJZILO325MF3uN68LDwyE4OLheJLjOVM2bk4ODg4MTmqMxB4mMENa08vJyKC0t" + "FQispqaG+gKDBw8WiA1JLiEhAUJCQk6TzXkklZJ0ijcxBwcHByc0e6qxDEyExILy8vJgx44dml08" + "LCwMMjIyBHIj6m0T2ZTDiY2Dwz3xzsEbM3tsWkV5ahVJJV3/fizyQhlvURsJzcvLaw/5iXNQmcrE" + "dP1vUsYqRzUIyQuJLKeoqCho6dKlcPr0abvlFRQUJBDbc88910lsGaStVY23kfMyGQwFcQOpa52K" + "fIrJzwwVRVSbXwH5SdU6Hwc/0ywoIeVP1FHZe3aqNtsj6eDVPkMOvxeEQBJV1A+fVyPjc8uCWpIK" + "8V6Q8mnaN5KyO7Wvt7U+egwKievZoMSAQTQqNPYSe2Ta3t6OgR1FFRUVYcnJyXYlsk7U19cDkiYq" + "wOzs7NmE2HCMbo6Pj0+pyoeDBaFiZwUqzlMDo4oysuZXpYY0dQa9ld8oJi3t0eAi96JWhRJb5YBy" + "hXbmQ/JEG84lRFDigs+6pK8n9bn+bKmpkyuF7eMbXTExpsMkGTUls7b2DFOd6eiC5xeETZo0iZrM" + "vG+6EXxHD4e+UydD34d+DYFD7oDFixZD9pJsiI+Ph+joaGpiW7hwIURERATVVNe8R8pTSlIwo7Ks" + "YuwMbSEmR57HUk53cMfUuqA9xtnxnur+5YJ0wjNIuuggMpOzq2JUViSFgntghlinwyQx9RuuGLaP" + "FUQjSiOdeKGtF2trayuqqamZPX36dKtE5tW/H/SOjIBe946FXqNHgJdf/277J9x4C6yceL/kPKL6" + "hITjcMeOHVO8Pu4zjjPCxo0bpyUlJZWTss3x9fVliYisZSAO5offxhcJNfkZWBWaGxhznQva4x5G" + "ezS4y73QkfsUXyr+TcqT6KJqTbGvJ3VKI3WierZceWJ1ATEi1Q9Sa2trMEnVmzZtmm1NlaEK83sm" + "BQxb3gK/Z1MEUutJZohdsVNRKUkSKrUlS5bA4cOH4dChQzBr1iyLZUtJSYHk5OQwcm45KWO4nRSK" + "GnIKtfHhtHd+tW5gxHUeYI8u73IknawBFQTobyywWCYIxdVRgCrY3QkNsUp8i2fC1atXg81mczkh" + "s7CnnnpKcPnJwSfkdghYthgCl2VCn19OpLo2ua7FNGbMGFi/fj2cPHkSnnjiCcXrbNmyBUkt6MKF" + "CxWkvLSkxqJQ1JCTLQrNqOJesZSxzpHBQ5zQFEnNYEXRhLrJvdhjoz3YtV90Q1LDOlntP1yd0NA4" + "mCOJUPls3rw5bO7cubL70bXY/8nHIOjVpYJrkRY/f2CSrEKTS4MGDRKI7aOPPhL+L4etW7dCampq" + "IJb3ypUrNKRWxth2jlRoas73tPEzV1eZBgp7dHlCIx3rKh2TWVcCMIL7gKqvd4elr7CSubQHNzc3" + "FxH1E5aWlqaoyvyfSQGfOwYxF+TurOeBdV5fVFQUHDhwABYtWiQQWE/s3LkTCPEGFRYWlpKyh/fr" + "189kgajryBtyFaWxGcixoeQclg7UVgOJY1SRLIquyk0M19WjNDOt2KOruBvhscgLtTJkNkOsIyuu" + "h6iT61L1VySvuC42pybgBN2P40h+dW5iG1b7endYnDiUNlih+fLljGM1NbORPGTZffRwwb2ohswQ" + "x1a9hqzCnIICA6GwoABW5+YqKrWVK1YMJseWUhqO5gSlIkDD0QrNHcbPwA2mHRisRD26ekAIK7Gg" + "PSKpTEYioyUzkfjKOs8hCedKZNlD1bhSX29NdWqt0GqJQd6p9mRiCGonJFp987906VJ4fX39a4mP" + "PAINDQ3ShhgxVCAztWg5eAQufvRP2Lxli8WxMUt4ev58CAwKgnnz5kn2rXz5ZbgvKiqGKLocPz+/" + "HI069lA7HauVwjMydhz2gE3PtJPhLHu0NOewhDZiTUG10E78rSX5aHrfxHEpFjtAIsrSKn8kNlIG" + "bNdihnJkknMK7aDSbGpfGyafW+zrdaXQMOyXJPQFTtb6TZ5ctyg1NRW+/fZbyb7ekWMhcOULcHF6" + "Mlx6c6MqMmvK/ZPwfySjlStXUo+l9UyPP/44rFu3TjYfdJOaTKaXmpqaLI2n2SswRAt/vFHr+9pZ" + "ZzdQNnpUi532OE6r++zi7i+WzrdESzLr0n5o34lA75o2gA5VGr7UkKR5X++tU0MqY5TXFivZ2NiY" + "sXfv3rDdu3dL9uGYGYbkC41x041wtXwfM6m1f3Om29+VlZWqCQ3TzJkzIT09XZIPkrFIlnkW2o5l" + "grWjFRr1XDYc39OBOuP47zOV5ehnRU8QFQVtvdBLkmZHMhBWB2E4JZMmQtBJxKZpX6/nMTRNIvYa" + "GhqCiUHmyLnxMJoRA0A655T1eyRB+EVS06ATsCmtWrUK7rrrLsl18/PzcQJ2DKlXggZtx6KYtIqY" + "itPiwe0Brs7sj0KtOh0XBctqKLn2VqLiWBzt8IIB9LluqaZ9va4JjVFpKL59mM3mjK1btwadOXNG" + "sg8JrGsACM41w3lnmNS6HzvJzNp8NJq0bds2CAwMlL5uZWbi/jwLRaB1OxoY5obREFqhLffKhk6R" + "KzT722MdYwfqTuoM60M7gRrbyVErdbCoNN0uBi0qzjotni29RznaVElTXV0wscQMVDs9IazB+Bup" + "+xbnnWFS637s0gPYnAbdfrus63Hfvn1w/NixwaR+sRp08FaJSiQ9a51ULWW+Wis0d5lQ7QqgDjhi" + "dBm7kzordOA4YQlDHxmn8zb2CEKzKRSbcELCrt27FdTZNIvn+o4aDv0DfFW7H63x1enT38LsJ5+A" + "hYueB5OpXvG4zMWZcDshtp7Iz1+H+zM0ULc0HQ+NOquivF+hGpaLRY1ycKgFi7vdYc+jSJy0L68G" + "nU+01mTajbc7P4XmDnPG9u3bZdWZpRVAmtIXQEvFfrjc2Cb83Tx7LpNSE1yOHWbF9Ld3/wbhY8Ph" + "/R0fwJ83boKhw4fA8RPHFY9fvHix1A3yl3egzlQ37cKFCyE2PiCaERolkRooA0M4oXG4IqE52v1d" + "Zad6uCTcltDOnz8fYjKZwj788EPJPjlXYyda8wuh5cfui3FcudTO7H60FPDxcu6ybse2tbbDbx+O" + "Vzx+ypQpsmNpH3zwAe5PsNGwQjU6poohX05oHO5IaFVOmJZg7/VbOaFpCNWDy9jRY4cvqfBNNwqr" + "5cuec+kyNH18QOZa135Z3I+WCO3KlSuS4y/8VA9r89+QPR7JDEmtJ3AaAtkfa+ODbtTomCqGfC0a" + "FuWYnbPeiDk8CGJACO2z6IzVatyF0DQJJNI7oVEHBsgQSiwGT/SEEpkhWt4qgA6zdC3GXgZ/5uhH" + "S4Q2zig/T/WVV/6oeM6jjz4qOX7//v24b5oOFFrXic00BmbU6L7X8gnVurRHWZv0gDo7nNAYFWGo" + "G7RznUsSmjjOYlBbyQ6zOVyO0PDjnEq4cvQL2e39lyy6Hv3YqdQskZpAQmazYtpQ8Db06dtbcl5T" + "YzMc+Owz2XPG/+IXErcjLuF1/Phx+OHcuViZMtTRvr1ZGtMSo9UMDIasBaFRu3gcYWikDTo0Tv92" + "tV6ddS1PN3rRYFEOzqqzS0+nEINVDFq0sZ4VWpzaG3ru7Lng+vqGwd99952U0BSCQVqPHIP2lnYp" + "mYUOBJ/B/40yxFVFOkP6LRu05ZS5SH5y/Btr1yieM2H8BMnxJ46fwH3hdlRpLO5GWiK1FhhC+3Dz" + "8TPHIVWtPXJVqhtC06tCi9OqrrokNHG17lVqK0n0UThGDfYELnOlSEAywSMCAT7TfYURnHwdvO4V" + "q+7HDiv/5qXPIyqtl+S8z/YfVDxn9F2jJcef+e4M7gu244NOYwRlKog0VAPD4+NnLmCPHBwW1Jmm" + "z5avzgxH7QrMtT3cHcFyX6H2uflnihdo/Uaq5nz6+HZTZ3JKD5WaHFHSfBfNeM9Y2F95sNs2dDsq" + "nTtq1CipQjtxQovAEFsVWq2KfPG6JbYQGp9QrVt79NT7wsdz6YlMk77e3oQmjDc4oX26vambzeZw" + "7OilCk35O2ftzS2SbX1uu8lipuh+bP5rKbSfOiMhM1y6yhrGR0ZJCA3x+eefw8iRIyXbAwICJNuQ" + "uJXywg6f3A80MmsuPKMNaklupXtbIx1Zpglw6M8e3aljd6cxNCSSULkPl6p5tsi1nN7X94Q7zEOT" + "Ln3Uwd7ObVdapY1z60CL53S6H/slTpNjE6vp3shI2esKwSwyx1++dElJqqh+ADRQaFUyRFpLYdxx" + "CqqANviAuxv1ixLeBBz26OvFdR/dmtByZTpU2U6+7V/Xgstw7Kvr+JfSOFjTJ0fAGGCAvuu2XD8H" + "/4/buv49sE/fbuc1trVC0rPz4fZBg4R0qOFit7/x/7gNPzYqh+J3C8F09RA8k5F0/Rz8+72dm2S4" + "rM2ae5NGyRjk1t6jXNGjViXhGBTW++MTql0bZeILDQeH3fv6nvB18QqiCiiUIzS5Lv6p8VGQZfwV" + "wKlT3XcU/QoGh4RIjn/44Yfh1WFjAda/Lb1Yl2u8lpcHXZe+P9ncBGeTHoIbSBLyPXkEoMvfNeI2" + "DCxpzF4tufT0+U1w/OJceCQTSLpB2IZ/j/9tO+z43x6kAz7WCI3lUzK1KsilzALhzLBTnpzQXLjT" + "ccE+hhbOCounjl7UyN2om77e3RRamtx8F7O5Q7aT7927t7BPLvn28pEc/58fvlE8vmvq6NDWlezn" + "L39bmhqlY2UdYn2VwLBQcagC4ViEhcAMtUtg0RhnHVcBukSJ+HFeT4WBPwL26+tpJpG7skJDMpP1" + "1ROKMckFUOBEZHntBsJE57bW5m7bTn75teLxWqDtxEnZ7YOH+TBdh6KMtRTkZFBBLlVW8lRDojSd" + "giM7TVyN5E7en1Ap5jTeDBx2IjOqcVlvFzWcyaSTKbSgGqrlQty/+OILxaWlQkJ/Ljn+4vl6IYqQ" + "5gvTatBy8Ihk288GKN+S0/+STvzGaEisrwYEYFSh0Mos3AOaCdZxKhUadzfqT5mNc9NlyFg8AXp3" + "ObqaV0Po6wmZUX8t3ZUIDRk6UTQcix10h9lsuvXWW+UJTWE5qrFh8usrrs1/0+IyVpjURFWafzwv" + "CfdHjDL2YiK0QKJEsb4aEEA38qKMNrTWgdEEhhgYSZQTmn5QJr5cJrpxHd1pDM1VXjiEvp4Q2TiS" + "mLwxenQ5VkH3sN8y1gm0dw4ZUi2nmhobGwGXw7rtttsk+57/n4WwdfM7ku2bijbD4t9lWcyvZ07e" + "fv2tlrH5rztkt4+L6QW+XkHg7dUbWsw/9SC0NsnxkZGRqIbKNVBoArl0ecvWInSe5r7F9bjfXKHp" + "u3PPFRV4rofUmUXVOHxpKfFrAPaoi1P6emth+Y4mNN2MN5ByVJDOPubgwe4Tl/+xZw/MmT1bcjyO" + "ud12+83wnzM/dtve0tIGz2akwxuvrVXMa3ZSEuwh1/3qq6/Aq38/+XlpXdD6+Veya0Giu3FcTG9o" + "66i/zpLeXn2IjO4DZ783wen/kyq0ESNGWHU5IkkRsqoCulXuq7oQjcXOjeJFg2kOnEIYv8QI+Ar7" + "2tgjae/DQL8QdC65VpanNSAGIhDSoFmcwCmEBmwf7dSS0GpJ2+hubNltP/BJBFp5pMzE5bI9ZYpz" + "nRc+L2+vf//gn1BcXKJ4XkBAIOwovaa4DFveAp87lFckEb65tupN2X0xv+kj2WbuuEoIrgEOV7TI" + "khnJu2bosGEmiiZhHUcz2GocIvHUMeTJJ1Q7FolA74bKJASY6aHtRP1tQUbF5MqEpku4LaGZO8zl" + "kyZNkmw/eOigsKAv2S9J+BHNmwfcIHu9l3KyobyiXPa8zmS1gydk1pCdCx2Xm2XV2ZRH+yqeu3fX" + "Vck2JGysp4YPcyiDodASSxmDQYZyo3SoFwPbkiUycRXlZHtPJTQaz4YzCc3tXfVuS2hEvZQPHz68" + "Xi445L333lOMVixc92d0xUjOaW83Q1paGixd/pLiuX1iJyqWB92MpnmLZANBEEkL+kP/AC/ZfV8c" + "aZV1NyYkJGC+RRo+zCyEVqtRvqFdAkMM3CgdTmo4hsEyHlYsE8jDCU0dwdgEUQ3SEmidreNTnNCc" + "b61FD5FOvyc2b94MjQ0Nsv7DYUOHQnJKkuIl/7K9GGIIcVWUl0vO9Xs2RaoUfzwvLK2FK4LIKTNE" + "9NQ+wtiZEt5dLz2PkDWMGD789MiRI6vpmoJqgrVAaGKHZdDIyGmUXBxlZ1DHV9i3C6llAduXGfZ4" + "WBOxuLlTHeh2nAH0kZUe4ar3dnNDzZs1a5ZkO0Y7biKkpqS0FmQsgphfjle87k8/1kH600/DveMj" + "IWPhs1BOyA2jJ3FtR3Qrohq7smsPNOW+Cab0xRY/BjoywhfmZfsp7kd19uURaXRjEqkXgzqjfaiN" + "WhML5XGhMgrRY43SSWAZTzOSl55VntIw4goVtAsuG8D6km9agWVM0yMWjHZrQhs1evQpPz+/imnx" + "8ZJ9a9euFeal4adX5NKfXi+AyPFjLV6/seES/OPvH8PT8+fD/Q88cK2nT3pGUGOX334HWg4etXj+" + "4KG9YOHqAIvHbFlzWbIN3ajx8fH1pJx5WrtOxDESo63XYTzeSElofPzMfi9/rONpGCQyw4OaiOVl" + "KtPeKk38nhjL/DOu0NzDUCEnPf1p2X0vLlli8QsvG9ZtggcT7rdLudDN+IetAeAfoBwIgq5GubGz" + "9HnpWL68u8aMMdnBKEPBtiWv1OQbqrGbk0MdqbGOpxV4SpCIuFoFyxfgC+xIZnh9FoWcS7MOIic0" + "F8CYu8eUDxw4cMe8efMk+06ePAm5q3MtLmm1IucVWJ27Gvr2661Jefr7e8GC1f7X3YxmuCrMM+sJ" + "dDW+u0E6djZw4ABBnaE7VUWHRTuO5gyFRtMxcpej/UmNZTwNX0A8KUiEhexnEOLR3C1Lrol2sgfY" + "ViXxmO/TeXuEkUJHxsyZMxsIsUn2bdu2DXa8v0NY4Ffp3/0P3A+ffXoQ4hN+Db16+6gqAxLZ9Kf6" + "wRulwZIAkJ6k9tNZM6xZ1CR7neXLV2CZcu4Ou9uksjmsvWXOAO1dfzREZG08wFkTqoWvPjswFevA" + "ZFjG0+yqRlxYpQnPNCGgPSIJaUFm6GY8DGwTuLNc+JMxzPD1hEqGhYWdqj569LVlS5e+NDc1VbI/" + "OztbWJMxXmasrSuWZq8QEob9by/eBKe/+R5aW9oskhiS16gIX4iWmTQtR2pNjVcImTXC5Sbp0l2E" + "lMEYEVFB6pNnQ3OUWVFDmkcaiiuV1FoxRGvhx55ilE53DeF4GrlfOJ5GS64zcNK1hyyHlcXQLp3P" + "9WFCRmWdL3aEYKjaSSTCTrtQo/bQZgrBg+DrKRUNHzs2hxhcbFpqakxBofQev5STI6w2Ff/gg1av" + "hfO/ErpMB0CCu9zcDLs/fh0eTu0nbAsZ6qs4r0wJP5xtJmR2SXbcbOiwIfC7hQvR1TjHxqawdRyq" + "zIZ8Q51YbleBLogbx9MISeUCfSQdTrquVfqkkxuptBJCNCzt0pXY4kSiclSEaKKnjJ11wtuTKkuM" + "LSE1NbU+NiZGdn8OITV0QdJ8LqZrQnKb+dhjkL0ukKixXkJiJTNcSf+FJ+oJmbVK9vn794c1f1yD" + "ec0ZGxFxykmEZGuHW+XkcnOFxm4vWYz3rYByPU5XJ7Us0P8LVpYnTKT2aEKLMBpNqNKys7MbcAK1" + "HF5dswYWLFx47WOgjMS2btklVeXCaMYXZtXLuhn9/PtCYcF6GDhw4FJS/lINOqk6G41R7bm2EJIn" + "TajW2xs1y3iaJwWJTNYxqWXRujU5obk4jOPGVfv7B8zOz18HQxVIraKiAh6Mj4f3398JZnMHddq7" + "+ypTWTCSEVWZXDTjNTLrAwX5G2DIkKGbSLlzNGwGW8hFlRFTRlhqrQo5odn+AsQ6Pw3Hfdw+SARd" + "efi9LtBfBGGip5KZRxIa4p7Ie0oDAvyfXJef3xARESF7TFNTEyxbvgymTYuHXbt2wrXvuVhLdED3" + "Iqq5FemNsuNlCH9/P4HMhg0buomUd47GTaCWIOrEDs7R+XpSuL7uyFvF/LQZnrIyPyGPREYVay+g" + "jdyJY3zgwfD21IrfExlZ5O/vH5O/dm391KlTFY87e+4cIbblED9tGhSuXy/MXVNyOW4/cIPidS43" + "dggr5i9PbxDci5bUHCrHrVu24u9SUs45dqi+M9yGtpzvSWMBuhzEVzGehkEicZ5ww5BESELjd8b3" + "4qpEVTbZk8LzleDryZWPvPfe6s8+/TT2xd//vig6Kips+YoVgjKTwzlCbBs2bBDSgAEDAJUdjsN1" + "ui2HDRsGH354RfgEDCqwS01mOP+9GU6R/3+psFq+HB5JTISUlJSGgICA2aR8pfaoN7r/SGdD+9FC" + "LYnFWUTqMtD5x0tRiRxmeG5wPC2R1Mkj7p/o6ssV54uh6zXVjioeQ7XLPDHwwxK8UFl4Oj7dvz+Y" + "/OScPXv2ubzXX4fKykqHlwFJ8sUXX4SIsWNryJ8J4ydMOMUfTw4O1wchuK7uV3wZoHXH9pxHVkUI" + "jK+WwwmNDvv37YslP0VHjx4dvHHjRjhaXW33PP38/SAlOQWVWT2S6oSJE/P4neDg4ODghKYJ9n2y" + "bw6SCxJbcXExVH6ivWJDRZacnAzRUdHg7+//OuY38b6JJt76HBwcHJzQNMcnlZVIbBnnzp0L21tZ" + "Kbgiq21QbbcMuBmi74uGKVOm4NjbaVSDJOXdFxXFiYyDg4ODE5r9Ubl3bwj5QXLD9a7C0BVZffQo" + "NDY1wddffy0c0yT+f8Att8AAcRFkorxg6JAhMIQkDB4hqgxJrJyk0qjo6FLeshwcHByc0JyGvRUV" + "GEASTlIsSSFiQuD2MJJwLKxTxpnE/wspOibmFG9BDg4ODk5oHBwcHBwcivDmTcDBwcHB4Q74fwEG" + "APNNNssrHc8WAAAAAElFTkSuQmCC\">"); +} + +void +report_formatter_html::add_header() +{ + add_exact("<header id=\"main_header\">\n"); +} + +void +report_formatter_html::end_header() +{ + add_exact("</header>\n\n"); +} + +void +report_formatter_html::add_div(struct tag_attr * div_attr) +{ + string empty=""; + string tmp_str; + + if (div_attr->css_class == empty && div_attr->css_id == empty) + add_exact("<div>\n"); + + else if (div_attr->css_class == empty && div_attr->css_id != empty) + addf_exact("<div id=\"%s\">\n", div_attr->css_id); + + else if (div_attr->css_class != empty && div_attr->css_id == empty) + addf_exact("<div class=\"%s\">\n", div_attr->css_class); + + else if (div_attr->css_class != empty && div_attr->css_id != empty) + addf_exact("<div class=\"%s\" id=\"%s\">\n", + div_attr->css_class, div_attr->css_id); +} + +void +report_formatter_html::end_div() +{ + add_exact("</div>\n"); +} + +void +report_formatter_html::add_title(struct tag_attr *title_att, const char *title) +{ + addf_exact("<h2 class=\"%s\"> %s </h2>\n", title_att->css_class, title); +} + +void +report_formatter_html::add_navigation() +{ + add_exact("<br/><div id=\"main_menu\"> </div>\n"); +} + +void +report_formatter_html::add_summary_list(string *list, int size) +{ + int i; + add_exact("<div><br/> <ul>\n"); + for (i=0; i < size; i+=2){ + addf_exact("<li class=\"summary_list\"> <b> %s </b> %s </li>", + list[i].c_str(), list[i+1].c_str()); + } + add_exact("</ul> </div> <br />\n"); +} + + +void +report_formatter_html::add_table(string *system_data, struct table_attributes* tb_attr) +{ + int i, j; + int offset=0; + string empty=""; + + if (tb_attr->table_class == empty) + add_exact("<table>\n"); + else + addf_exact("<table class=\"%s\">\n", tb_attr->table_class); + + for (i=0; i < tb_attr->rows; i++){ + if (tb_attr->tr_class == empty) + add_exact("<tr> "); + else + addf_exact("<tr class=\"%s\"> ", tb_attr->tr_class); + + for (j=0; j < tb_attr->cols; j++){ + offset = i * (tb_attr->cols) + j; + + if (tb_attr->pos_table_title == T && i==0) + addf_exact("<th class=\"%s\"> %s </th> ", + tb_attr->th_class,system_data[offset].c_str()); + else if (tb_attr->pos_table_title == L && j==0) + addf_exact("<th class=\"%s\"> %s </th> ", + tb_attr->th_class, system_data[offset].c_str()); + else if (tb_attr->pos_table_title == TL && ( i==0 || j==0 )) + addf_exact("<th class=\"%s\"> %s </th> ", + tb_attr->th_class, system_data[offset].c_str()); + else if (tb_attr->pos_table_title == TC && ((i % tb_attr->title_mod ) == 0)) + addf_exact("<th class=\"%s\"> %s </th> ", tb_attr->th_class, + system_data[offset].c_str()); + else if (tb_attr->pos_table_title == TLC && ((i % tb_attr->title_mod) == 0 || j==0)) + addf_exact("<th class=\"%s\"> %s </th> ", tb_attr->th_class, + system_data[offset].c_str()); + else + if ( tb_attr->td_class == empty) + addf_exact("<td > %s </td> ", system_data[offset].c_str()); + else + addf_exact("<td class=\"%s\"> %s </td> ", tb_attr->td_class, + system_data[offset].c_str()); + } + add_exact("</tr>\n"); + } + add_exact("</table>\n"); +} + diff --git a/src/report/report-formatter-html.h b/src/report/report-formatter-html.h new file mode 100644 index 0000000..c003fd9 --- /dev/null +++ b/src/report/report-formatter-html.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * HTML report generator. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +#ifndef _REPORT_FORMATTER_HTML_H_ +#define _REPORT_FORMATTER_HTML_H_ + +#include <string> + +#include "report-formatter-base.h" +#include "report-data-html.h" + +using namespace std; + +/* Whether to replace " and ' in HTML by " and ' respectively */ +/*#define REPORT_HTML_ESCAPE_QUOTES*/ + +/* ************************************************************************ */ + +struct html_section { + const char *id; +}; + +/* ************************************************************************ */ + +class report_formatter_html: public report_formatter_string_base +{ +public: + report_formatter_html(); + void finish_report(); + + /* Report Style */ + void add_logo(); + void add_header(); + void end_header(); + void add_div(struct tag_attr *div_attr); + void end_div(); + void add_title(struct tag_attr *title_att, const char *title); + void add_navigation(); + void add_summary_list(string *list, int size); + void add_table(string *system_data, struct table_attributes *tb_attr); + +private: + /* Document structure related functions */ + void init_markup(); + void add_doc_header(); + void add_doc_footer(); + string escape_string(const char *str); + +}; + +#endif /* _REPORT_FORMATTER_HTML_H_ */ diff --git a/src/report/report-formatter.h b/src/report/report-formatter.h new file mode 100644 index 0000000..940b5cf --- /dev/null +++ b/src/report/report-formatter.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * report_formatter interface. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +#ifndef _REPORT_FORMATTER_H_ +#define _REPORT_FORMATTER_H_ + +#include "report-maker.h" +using namespace std; + +class report_formatter +{ +public: + virtual ~report_formatter() {} + + virtual void finish_report() {} + virtual const char *get_result() {return "Basic report_formatter::get_result() call\n";} + virtual void clear_result() {} + + virtual void add(const char *str) {} + virtual void addv(const char *fmt, va_list ap) {} + + /* *** Report Style *** */ + virtual void add_logo() {} + virtual void add_header() {} + virtual void end_header() {} + virtual void add_div(struct tag_attr *div_attr) {} + virtual void end_div() {} + virtual void add_title(struct tag_attr *att_title, const char *title) {} + virtual void add_navigation() {} + virtual void add_summary_list(string *list, int size) {} + virtual void add_table(string *system_data, + struct table_attributes *tb_attr) {} +}; + +#endif /* _REPORT_FORMATTER_H_ */ diff --git a/src/report/report-maker.cpp b/src/report/report-maker.cpp new file mode 100644 index 0000000..4049a54 --- /dev/null +++ b/src/report/report-maker.cpp @@ -0,0 +1,187 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Generic report generator. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +/* Uncomment to disable asserts */ +/*#define NDEBUG*/ + +#include <assert.h> +#include <stdarg.h> + +#include "report-maker.h" +#include "report-formatter-csv.h" +#include "report-formatter-html.h" + +/* ************************************************************************ */ + +report_maker::report_maker(report_type t) +{ + type = t; + formatter = NULL; + setup_report_formatter(); + clear_result(); /* To reset state and add document header */ +} + +/* ************************************************************************ */ + +report_maker::~report_maker() +{ + delete formatter; +} + +/* ************************************************************************ */ + +void +report_maker::finish_report() +{ + formatter->finish_report(); +} + +/* ************************************************************************ */ + +const char * +report_maker::get_result() +{ + return formatter->get_result(); +} + +/* ************************************************************************ */ + +void +report_maker::clear_result() +{ + formatter->clear_result(); +} + +/* ************************************************************************ */ + +report_type +report_maker::get_type() +{ + return type; +} + +/* ************************************************************************ */ + +void +report_maker::set_type(report_type t) +{ + clear_result(); + type = t; + setup_report_formatter(); +} + +/* ************************************************************************ */ + +void +report_maker::setup_report_formatter() +{ + delete formatter; + + if (type == REPORT_HTML) + formatter = new report_formatter_html(); + else if (type == REPORT_CSV) + formatter = new report_formatter_csv(); + else if (type == REPORT_OFF) + formatter = new report_formatter(); + else + assert(false); +} + +/* ************************************************************************ */ + +void +report_maker::add(const char *str) +{ + assert(str); + formatter->add(str); +} + +/* ************************************************************************ */ + +void +report_maker::addf(const char *fmt, ...) +{ + va_list ap; + assert(fmt); + va_start(ap, fmt); + formatter->addv(fmt, ap); + va_end(ap); +} + +/* *** Report Style *** */ +void +report_maker::add_logo() +{ + formatter->add_logo(); +} + +void +report_maker::add_header() +{ + formatter->add_header(); +} + +void +report_maker::end_header() +{ + formatter->end_header(); +} + +void +report_maker::add_title(struct tag_attr *att_title, const char *title) +{ + formatter->add_title(att_title, title); +} + +void +report_maker::add_div(struct tag_attr * div_attr) +{ + formatter->add_div(div_attr); +} + +void +report_maker::end_div() +{ + formatter->end_div(); +} + +void +report_maker::add_navigation() +{ + formatter->add_navigation(); +} + +void +report_maker::add_summary_list(string *list, int size) +{ + formatter->add_summary_list(list, size); +} + +void +report_maker::add_table(string *system_data, struct table_attributes *tb_attr) +{ + formatter->add_table(system_data, tb_attr); +} + diff --git a/src/report/report-maker.h b/src/report/report-maker.h new file mode 100644 index 0000000..bda4cef --- /dev/null +++ b/src/report/report-maker.h @@ -0,0 +1,139 @@ +/* Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Generic report generator. + * Written by Igor Zhbanov <i.zhbanov@samsung.com> + * 2012.10 */ + +#ifndef _REPORT_MAKER_H_ +#define _REPORT_MAKER_H_ + +/* This report generator implements the following document structure: + * body + * \---> section + * |---> Title + * |---> paragraph + * |---> table + * |---> list + * + * The report body consists of a number of sections (a.k.a. <div>s, + * a.k.a. tabs). + * Each section can contain titles (<h2>), paragraphs (<p>) + * and tables (<table>). + * + * A header is a single line of text. + * + * Paragraphs can contain only text. + * + * + * Each section, table, row or cell could have its own formatting. + * + * Example of usage: + * report_maker report(REPORT_OFF); + * + * report.set_type(REPORT_HTML); + * report.add_div + * report.add_title + * report.add_list + * report.add_table + * report.finish_report(); + * const char *result = report.get_result(); + */ + +#include <stdarg.h> + +#include <string> +using namespace std; +/* Conditional gettext. We need original strings for CSV. */ +#ifdef ENABLE_NLS +#define __(STRING) \ + ((report.get_type() == REPORT_CSV) ? (STRING) : gettext(STRING)) +#else +#define __(STRING) (STRING) +#endif + +#ifndef UNUSED +#define UNUSED __attribute__((unused)) +#endif /* UNUSED */ + +/* ************************************************************************ */ + +enum report_type { + REPORT_OFF, + REPORT_HTML, + REPORT_CSV +}; + +/* ************************************************************************ */ + +enum section_type { + SECTION_DEFAULT, + SECTION_SYSINFO, + SECTION_CPUIDLE, + SECTION_CPUFREQ, + SECTION_DEVFREQ, + SECTION_DEVPOWER, + SECTION_SOFTWARE, + SECTION_SUMMARY, + SECTION_TUNING, + SECTION_MAX /* Must be last in this enum */ +}; + + +/* ************************************************************************ */ + +class report_formatter; + +class report_maker +{ +public: + report_maker(report_type t); + ~report_maker(); + + report_type get_type(); + void set_type(report_type t); + + void addf(const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); + + void finish_report(); + const char *get_result(); + void clear_result(); + + void add(const char *str); + + /* *** Report Style *** */ + void add_header(); + void end_header(); + void add_logo(); + void add_div(struct tag_attr *div_attr); + void end_div(); + void add_title(struct tag_attr *att_title, const char *title); + void add_navigation(); + void add_summary_list(string *list, int size); + void add_table(string *system_data, struct table_attributes *tb_attr); + +private: + void setup_report_formatter(); + report_type type; + report_formatter *formatter; +}; +#endif /* _REPORT_MAKER_H_ */ diff --git a/src/report/report.cpp b/src/report/report.cpp new file mode 100644 index 0000000..2efe835 --- /dev/null +++ b/src/report/report.cpp @@ -0,0 +1,217 @@ +/* + * Copyright 2011, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + * Chris Ferron <chris.e.ferron@linux.intel.com> + */ + +#include "lib.h" +#include "report.h" +#include "report-maker.h" +#include <errno.h> +#include <string.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <string.h> +#include <malloc.h> +#include <unistd.h> +#include <limits.h> +#include "report-data-html.h" + +using namespace std; + +struct reportstream reportout; +report_type reporttype = REPORT_OFF; +report_maker report(REPORT_OFF); + +string cpu_model(void) +{ + ifstream file; + + file.open("/proc/cpuinfo", ios::in); + + if (!file) + return ""; + + while (file) { + char line[4096]; + file.getline(line, 4096); + if (strstr(line, "model name")) { + char *c; + c = strchr(line, ':'); + if (c) { + file.close(); + c++; + return c; + } + } + } + file.close(); + return ""; +} + +static string read_os_release(const string &filename) +{ + ifstream file; + char content[4096]; + char *c; + const char *pname = "PRETTY_NAME="; + string os(""); + + file.open(filename.c_str(), ios::in); + if (!file) + return ""; + while (file.getline(content, 4096)) { + if (strncasecmp(pname, content, strlen(pname)) == 0) { + c = strchr(content, '='); + if (!c) + break; + c += 1; + if (*c == '"' || *c == '\'') + c += 1; + *strchrnul(c, '"') = 0; + *strchrnul(c, '\'') = 0; + os = c; + break; + } + } + file.close(); + return os; +} + +static void system_info(void) +{ + string str; + char version_date[64]; + time_t now = time(NULL); + + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "sys_info", ""); + + /* Set Table attributes, rows, and cols */ + table_attributes sys_table; + init_top_table_attr(&sys_table, 5, 2); + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Set array of data in row Major order */ + string *system_data = new string[sys_table.rows * sys_table.cols]; + system_data[0]=__("PowerTOP Version"); + snprintf(version_date, sizeof(version_date), "%s ran at %s", PACKAGE_VERSION, ctime(&now)); + system_data[1]=version_date; + + str = read_sysfs_string("/proc/version"); + size_t found = str.find(" "); + found = str.find(" ", found+1); + found = str.find(" ", found+1); + str = str.substr(0,found); + system_data[2]=__("Kernel Version"); + system_data[3]=str.c_str(); + + str = read_sysfs_string("/sys/devices/virtual/dmi/id/board_vendor"); + system_data[4]=__("System Name"); + system_data[5]= str.c_str(); + str = read_sysfs_string("/sys/devices/virtual/dmi/id/board_name"); + system_data[5].append(str.c_str()); + str = read_sysfs_string("/sys/devices/virtual/dmi/id/product_version"); + system_data[5].append(str.c_str()); + str = cpu_model(); + system_data[6]=__("CPU Information"); + stringstream n_proc; + n_proc << sysconf(_SC_NPROCESSORS_ONLN); + system_data[7]= n_proc.str(); + system_data[7].append(str.c_str()); + + str = read_sysfs_string("/etc/system-release"); + if (str.length() < 1) + str = read_sysfs_string("/etc/redhat-release"); + if (str.length() < 1) + str = read_os_release("/etc/os-release"); + + system_data[8]=__("OS Information"); + system_data[9]=str; + + /* Report Output */ + report.add_header(); + report.add_logo(); + report.add_div(&div_attr); + report.add_title(&title_attr, __("System Information")); + report.add_table(system_data, &sys_table); + report.end_header(); + report.end_div(); + report.add_navigation(); + delete [] system_data; +} + +void init_report_output(char *filename_str, int iterations) +{ + size_t period; + string filename; + time_t stamp; + char datestr[200]; + + if (iterations == 1) + snprintf(reportout.filename, sizeof(reportout.filename), "%s", filename_str); + else + { + filename = string(filename_str); + period = filename.find_last_of("."); + if (period > filename.length()) + period = filename.length(); + memset(&datestr, 0, 200); + memset(&stamp, 0, sizeof(time_t)); + stamp = time(NULL); + strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M%S", localtime(&stamp)); + snprintf(reportout.filename, sizeof(reportout.filename), "%s-%s%s", + filename.substr(0, period).c_str(), datestr, + filename.substr(period).c_str()); + } + + reportout.report_file = fopen(reportout.filename, "wm"); + if (!reportout.report_file) { + fprintf(stderr, _("Cannot open output file %s (%s)\n"), + reportout.filename, strerror(errno)); + } + + report.set_type(reporttype); + system_info(); +} + +void finish_report_output(void) +{ + if (reporttype == REPORT_OFF) + return; + + report.finish_report(); + if (reportout.report_file) + { + fprintf(stderr, _("PowerTOP outputting using base filename %s\n"), reportout.filename); + fputs(report.get_result(), reportout.report_file); + fdatasync(fileno(reportout.report_file)); + fclose(reportout.report_file); + } + report.clear_result(); +} diff --git a/src/report/report.h b/src/report/report.h new file mode 100644 index 0000000..c1aee1b --- /dev/null +++ b/src/report/report.h @@ -0,0 +1,47 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_REPORT_H_ +#define __INCLUDE_GUARD_REPORT_H_ + +#include <string> +#include <stdio.h> +#include <limits.h> + +#include "report-maker.h" + +using namespace std; + +struct reportstream { + FILE *report_file; + char filename[PATH_MAX]; +}; + +extern report_type reporttype; +extern report_maker report; +extern struct reportstream reportout; +extern void init_report_output(char *filename_str, int iterations); +extern void finish_report_output(void); + +#endif diff --git a/src/tuning/bluetooth.cpp b/src/tuning/bluetooth.cpp new file mode 100644 index 0000000..2958849 --- /dev/null +++ b/src/tuning/bluetooth.cpp @@ -0,0 +1,228 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "tuning.h" +#include "tunable.h" +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <unistd.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include "../lib.h" +#include "bluetooth.h" + +bt_tunable::bt_tunable(void) : tunable("", 1.0, _("Good"), _("Bad"), _("Unknown")) +{ + sprintf(desc, _("Bluetooth device interface status")); + pt_strcpy(toggle_bad, "/usr/sbin/hciconfig hci0 up &> /dev/null &"); + pt_strcpy(toggle_good, "/usr/sbin/hciconfig hci0 down &> /dev/null"); +} + + + +/* structure definitions copied from include/net/bluetooth/hci.h from the 2.6.20 kernel */ +#define HCIGETDEVINFO _IOR('H', 211, int) +#define BTPROTO_HCI 1 + +#define __u16 uint16_t +#define __u8 uint8_t +#define __u32 uint32_t + +typedef struct { + __u8 b[6]; +} __attribute__((packed)) bdaddr_t; + +struct hci_dev_stats { + __u32 err_rx; + __u32 err_tx; + __u32 cmd_tx; + __u32 evt_rx; + __u32 acl_tx; + __u32 acl_rx; + __u32 sco_tx; + __u32 sco_rx; + __u32 byte_rx; + __u32 byte_tx; +}; + + +struct hci_dev_info { + __u16 dev_id; + char name[8]; + + bdaddr_t bdaddr; + + __u32 flags; + __u8 type; + + __u8 features[8]; + + __u32 pkt_type; + __u32 link_policy; + __u32 link_mode; + + __u16 acl_mtu; + __u16 acl_pkts; + __u16 sco_mtu; + __u16 sco_pkts; + + struct hci_dev_stats stat; +}; + +static int previous_bytes = -1; +static time_t last_check_time = 0; +static int last_check_result; + +int bt_tunable::good_bad(void) +{ + struct hci_dev_info devinfo; + FILE *file = 0; + int fd; + int thisbytes = 0; + int ret; + int result = TUNE_GOOD; + + fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (fd < 0) + return TUNE_GOOD; + + memset(&devinfo, 0, sizeof(devinfo)); + strcpy(devinfo.name, "hci0"); + ret = ioctl(fd, HCIGETDEVINFO, (void *) &devinfo); + if (ret < 0) + goto out; + + if ( (devinfo.flags & 1) == 0 && + access("/sys/module/hci_usb",F_OK)) /* interface down already */ + goto out; + + thisbytes += devinfo.stat.byte_rx; + thisbytes += devinfo.stat.byte_tx; + + /* device is active... so we need to leave it on */ + if (thisbytes != previous_bytes) + goto out; + + + /* this check is expensive.. only do it once per minute */ + if (time(NULL) - last_check_time > 60) { + last_check_result = TUNE_BAD; + /* now, also check for active connections */ + file = popen("/usr/bin/hcitool con 2> /dev/null", "r"); + if (file) { + char line[2048]; + /* first line is standard header */ + if (fgets(line, 2047, file) == NULL) + goto out; + memset(line, 0, 2048); + if (fgets(line, 2047, file) == NULL) { + result = last_check_result = TUNE_GOOD; + goto out; + } + + if (strlen(line) > 0) { + result = last_check_result = TUNE_GOOD; + goto out; + } + } + last_check_time = time(NULL); + }; + + result = last_check_result; + +out: + previous_bytes = thisbytes; + if (file) + pclose(file); + close(fd); + return result; +} + +void bt_tunable::toggle(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + if(system("/usr/sbin/hciconfig hci0 up &> /dev/null &")) + printf("System is not available\n"); + return; + } + if(system("/usr/sbin/hciconfig hci0 down &> /dev/null")) + printf("System is not available\n"); +} + +const char *bt_tunable::toggle_script(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + return toggle_bad; + } + return toggle_good; +} + + +void add_bt_tunable(void) +{ + struct hci_dev_info devinfo; + class bt_tunable *bt; + int fd; + int ret; + + /* first check if /sys/modules/bluetooth exists, if not, don't probe bluetooth because + it would trigger an autoload */ + +// if (access("/sys/module/bluetooth",F_OK)) +// return; + + + /* check if hci0 exists */ + fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (fd < 0) + return; + + memset(&devinfo, 0, sizeof(devinfo)); + strcpy(devinfo.name, "hci0"); + ret = ioctl(fd, HCIGETDEVINFO, (void *) &devinfo); + close(fd); + if (ret < 0) + return; + + + bt = new class bt_tunable(); + all_tunables.push_back(bt); +} diff --git a/src/tuning/bluetooth.h b/src/tuning/bluetooth.h new file mode 100644 index 0000000..ecb667d --- /dev/null +++ b/src/tuning/bluetooth.h @@ -0,0 +1,49 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_BLUETOOTH_TUNE_H +#define _INCLUDE_GUARD_BLUETOOTH_TUNE_H + +#include <vector> + +#include "tunable.h" + +using namespace std; + +class bt_tunable : public tunable { +public: + bt_tunable(void); + + virtual int good_bad(void); + + virtual void toggle(void); + + virtual const char *toggle_script(void); + +}; + +extern void add_bt_tunable(void); + + +#endif diff --git a/src/tuning/ethernet.cpp b/src/tuning/ethernet.cpp new file mode 100644 index 0000000..5b128d1 --- /dev/null +++ b/src/tuning/ethernet.cpp @@ -0,0 +1,157 @@ +;/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "tuning.h" +#include "tunable.h" +#include <sys/types.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <sys/socket.h> +#include <errno.h> +#include <linux/types.h> +#include <net/if.h> +#include <linux/sockios.h> +#include <sys/ioctl.h> + +#include <linux/ethtool.h> + +#include "../lib.h" +#include "ethernet.h" + +extern void create_all_nics(callback fn); + +ethernet_tunable::ethernet_tunable(const char *iface) : tunable("", 0.3, _("Good"), _("Bad"), _("Unknown")) +{ + memset(interf, 0, sizeof(interf)); + pt_strcpy(interf, iface); + sprintf(desc, _("Wake-on-lan status for device %s"), iface); + snprintf(toggle_good, sizeof(toggle_good), "ethtool -s %s wol d;", iface); + +} + + +int ethernet_tunable::good_bad(void) +{ + int sock; + struct ifreq ifr; + struct ethtool_wolinfo wol; + int ret; + int result = TUNE_GOOD; + + memset(&ifr, 0, sizeof(struct ifreq)); + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock<0) + return result; + + pt_strcpy(ifr.ifr_name, interf); + + /* Check if the interf is up */ + ret = ioctl(sock, SIOCGIFFLAGS, &ifr); + if (ret<0) { + close(sock); + return result; + } + + memset(&wol, 0, sizeof(wol)); + + wol.cmd = ETHTOOL_GWOL; + ifr.ifr_data = (caddr_t)&wol; + ioctl(sock, SIOCETHTOOL, &ifr); + + if (wol.wolopts) + result = TUNE_BAD; + + close(sock); + + return result; +} + +void ethernet_tunable::toggle(void) +{ + int sock; + struct ifreq ifr; + struct ethtool_wolinfo wol; + int ret; + + memset(&ifr, 0, sizeof(struct ifreq)); + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock<0) + return; + + pt_strcpy(ifr.ifr_name, interf); + + /* Check if the interface is up */ + ret = ioctl(sock, SIOCGIFFLAGS, &ifr); + if (ret<0) { + close(sock); + return; + } + + memset(&wol, 0, sizeof(wol)); + + wol.cmd = ETHTOOL_GWOL; + ifr.ifr_data = (caddr_t)&wol; + ioctl(sock, SIOCETHTOOL, &ifr); + wol.cmd = ETHTOOL_SWOL; + wol.wolopts = 0; + ioctl(sock, SIOCETHTOOL, &ifr); + + close(sock); +} + +const char *ethernet_tunable::toggle_script(void) +{ + int good; + good = good_bad(); + + if (good != TUNE_GOOD) { + return toggle_good; + } + + return NULL; +} + + +void ethtunable_callback(const char *d_name) +{ + class ethernet_tunable *eth; + if (strcmp(d_name, "lo") == 0) + return; + eth = new(std::nothrow) class ethernet_tunable(d_name); + if (eth) + all_tunables.push_back(eth); +} + +void add_ethernet_tunable(void) +{ + create_all_nics(ðtunable_callback); +} diff --git a/src/tuning/ethernet.h b/src/tuning/ethernet.h new file mode 100644 index 0000000..85810fb --- /dev/null +++ b/src/tuning/ethernet.h @@ -0,0 +1,49 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_ETHERNET_TUNE_H +#define _INCLUDE_GUARD_ETHERNET_TUNE_H + +#include <vector> + +#include "tunable.h" + +using namespace std; + +class ethernet_tunable : public tunable { +public: + char interf[4096]; + ethernet_tunable(const char *iface); + + virtual int good_bad(void); + + virtual void toggle(void); + + virtual const char *toggle_script(void); + +}; + +extern void add_ethernet_tunable(void); + +#endif diff --git a/src/tuning/iw.c b/src/tuning/iw.c new file mode 100644 index 0000000..68eb6dc --- /dev/null +++ b/src/tuning/iw.c @@ -0,0 +1,303 @@ +/* + * This code has been blatently stolen from + * + * nl80211 userspace tool + * + * Copyright 2007, 2008 Johannes Berg <johannes@sipsolutions.net> + * + * and has been stripped down to just the pieces needed. + */ + +/* + +Copyright (c) 2007, 2008 Johannes Berg +Copyright (c) 2007 Andy Lutomirski +Copyright (c) 2007 Mike Kershaw +Copyright (c) 2008-2009 Luis R. Rodriguez + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +*/ + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <net/if.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdbool.h> + +#include "nl80211.h" +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include <asm/errno.h> +#include <linux/genetlink.h> +#include "iw.h" + + +#ifndef HAVE_LIBNL20 +/* libnl 2.0 compatibility code */ + +static inline struct nl_handle *nl_socket_alloc(void) +{ + return nl_handle_alloc(); +} + +static inline void nl_socket_free(struct nl_sock *h) +{ + nl_handle_destroy(h); +} + +static inline int __genl_ctrl_alloc_cache(struct nl_sock *h, struct nl_cache **cache) +{ + struct nl_cache *tmp = genl_ctrl_alloc_cache(h); + if (!tmp) + return -ENOMEM; + *cache = tmp; + return 0; +} +#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache +#endif /* HAVE_LIBNL20 */ + + +static int nl80211_init(struct nl80211_state *state) +{ + int err; + + state->nl_sock = nl_socket_alloc(); + if (!state->nl_sock) { + fprintf(stderr, "Failed to allocate netlink socket.\n"); + return -ENOMEM; + } + + if (genl_connect(state->nl_sock)) { + fprintf(stderr, "Failed to connect to generic netlink.\n"); + err = -ENOLINK; + goto out_handle_destroy; + } + + if (genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache)) { + fprintf(stderr, "Failed to allocate generic netlink cache.\n"); + err = -ENOMEM; + goto out_handle_destroy; + } + + state->nl80211 = genl_ctrl_search_by_name(state->nl_cache, "nl80211"); + if (!state->nl80211) { + err = -ENOENT; + goto out_cache_free; + } + + return 0; + + out_cache_free: + nl_cache_free(state->nl_cache); + out_handle_destroy: + nl_socket_free(state->nl_sock); + return err; +} + +static void nl80211_cleanup(struct nl80211_state *state) +{ + genl_family_put(state->nl80211); + nl_cache_free(state->nl_cache); + nl_socket_free(state->nl_sock); +} + +static int enable_power_save; + + +static int set_power_save(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg) +{ + enum nl80211_ps_state ps_state; + + ps_state = NL80211_PS_DISABLED; + if (enable_power_save) + ps_state = NL80211_PS_ENABLED; + + NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); + + return 0; + + nla_put_failure: + return -ENOBUFS; +} + +static int print_power_save_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!attrs[NL80211_ATTR_PS_STATE]) + return 0; + + switch (nla_get_u32(attrs[NL80211_ATTR_PS_STATE])) { + case NL80211_PS_ENABLED: + enable_power_save = 1; + break; + case NL80211_PS_DISABLED: + default: + enable_power_save = 0; + break; + } + + return NL_SKIP; +} + +static int get_power_save(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_power_save_handler, NULL); + return 0; +} + +static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *ret = arg; + *ret = err->error; + return NL_STOP; +} + +static int finish_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_SKIP; +} + +static int ack_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_STOP; +} + +static int __handle_cmd(struct nl80211_state *state, const char *iface, int get) +{ + struct nl_cb *cb; + struct nl_msg *msg; + int devidx = 0; + int err; + + devidx = if_nametoindex(iface); + if (devidx == 0) + devidx = -1; + if (devidx < 0) + return -errno; + + msg = nlmsg_alloc(); + if (!msg) { + fprintf(stderr, "failed to allocate netlink message\n"); + return 2; + } + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + fprintf(stderr, "failed to allocate netlink callbacks\n"); + err = 2; + goto out_free_msg; + } + + if (get) + genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, + 0, NL80211_CMD_GET_POWER_SAVE, 0); + else + genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, + 0, NL80211_CMD_SET_POWER_SAVE, 0); + + + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); + + if (get) + err = get_power_save(state, cb, msg); + else + err = set_power_save(state, cb, msg); + + if (err) + goto out; + + err = nl_send_auto_complete(state->nl_sock, msg); + if (err < 0) + goto out; + + err = 1; + + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); + + while (err > 0) + nl_recvmsgs(state->nl_sock, cb); + out: + nl_cb_put(cb); + out_free_msg: + nlmsg_free(msg); + return err; + nla_put_failure: + fprintf(stderr, "building message failed\n"); + return 2; +} + + +int set_wifi_power_saving(const char *iface, int state) +{ + struct nl80211_state nlstate; + int err; + + err = nl80211_init(&nlstate); + if (err) + return 1; + + enable_power_save = state; + err = __handle_cmd(&nlstate, iface, 0); + + nl80211_cleanup(&nlstate); + + return err; +} + + +int get_wifi_power_saving(const char *iface) +{ + struct nl80211_state nlstate; + int err; + + enable_power_save = 0; + + err = nl80211_init(&nlstate); + if (err) + return 1; + + err = __handle_cmd(&nlstate, iface, 1); + + nl80211_cleanup(&nlstate); + + if (err) /* not a wifi interface */ + return 1; + + return enable_power_save; +} diff --git a/src/tuning/iw.h b/src/tuning/iw.h new file mode 100644 index 0000000..6ea5a3d --- /dev/null +++ b/src/tuning/iw.h @@ -0,0 +1,69 @@ +#ifndef __IW_H +#define __IW_H + +/* + * This code has been blatently stolen from + * + * nl80211 userspace tool + * + * Copyright 2007, 2008 Johannes Berg <johannes@sipsolutions.net> + * + * and has been stripped down to just the pieces needed. + */ + +/* + +Copyright (c) 2007, 2008 Johannes Berg +Copyright (c) 2007 Andy Lutomirski +Copyright (c) 2007 Mike Kershaw +Copyright (c) 2008-2009 Luis R. Rodriguez + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +*/ + +#include <stdbool.h> + +#define ETH_ALEN 6 + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_LIBNL20 +#define nl_sock nl_handle +#endif + +struct nl80211_state { + struct nl_sock *nl_sock; + struct nl_cache *nl_cache; + struct genl_family *nl80211; +}; + +enum command_identify_by { + CIB_NONE, + CIB_PHY, + CIB_NETDEV, +}; + +enum id_input { + II_NONE, + II_NETDEV, + II_PHY_NAME, + II_PHY_IDX, +}; + +int get_wifi_power_saving(const char *iface); +int set_wifi_power_saving(const char *iface, int state); + +#endif /* __IW_H */ diff --git a/src/tuning/nl80211.h b/src/tuning/nl80211.h new file mode 100644 index 0000000..83b0514 --- /dev/null +++ b/src/tuning/nl80211.h @@ -0,0 +1,1897 @@ +#ifndef __LINUX_NL80211_H +#define __LINUX_NL80211_H +/* + * 802.11 netlink interface public header + * + * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> + * Copyright 2008 Michael Wu <flamingice@sourmilk.net> + * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com> + * Copyright 2008 Michael Buesch <mb@bu3sch.de> + * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com> + * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com> + * Copyright 2008 Colin McCabe <colin@cozybit.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include <linux/types.h> + +/** + * DOC: Station handling + * + * Stations are added per interface, but a special case exists with VLAN + * interfaces. When a station is bound to an AP interface, it may be moved + * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN). + * The station is still assumed to belong to the AP interface it was added + * to. + * + * TODO: need more info? + */ + +/** + * DOC: Frame transmission/registration support + * + * Frame transmission and registration support exists to allow userspace + * management entities such as wpa_supplicant react to management frames + * that are not being handled by the kernel. This includes, for example, + * certain classes of action frames that cannot be handled in the kernel + * for various reasons. + * + * Frame registration is done on a per-interface basis and registrations + * cannot be removed other than by closing the socket. It is possible to + * specify a registration filter to register, for example, only for a + * certain type of action frame. In particular with action frames, those + * that userspace registers for will not be returned as unhandled by the + * driver, so that the registered application has to take responsibility + * for doing that. + * + * The type of frame that can be registered for is also dependent on the + * driver and interface type. The frame types are advertised in wiphy + * attributes so applications know what to expect. + * + * NOTE: When an interface changes type while registrations are active, + * these registrations are ignored until the interface type is + * changed again. This means that changing the interface type can + * lead to a situation that couldn't otherwise be produced, but + * any such registrations will be dormant in the sense that they + * will not be serviced, i.e. they will not receive any frames. + * + * Frame transmission allows userspace to send for example the required + * responses to action frames. It is subject to some sanity checking, + * but many frames can be transmitted. When a frame was transmitted, its + * status is indicated to the sending socket. + * + * For more technical details, see the corresponding command descriptions + * below. + */ + +/** + * enum nl80211_commands - supported nl80211 commands + * + * @NL80211_CMD_UNSPEC: unspecified command to catch errors + * + * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request + * to get a list of all present wiphys. + * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or + * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, + * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, + * %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT, + * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, + * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. + * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL + * instead, the support here is for backward compatibility only. + * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request + * or rename notification. Has attributes %NL80211_ATTR_WIPHY and + * %NL80211_ATTR_WIPHY_NAME. + * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes + * %NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME. + * + * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration; + * either a dump request on a %NL80211_ATTR_WIPHY or a specific get + * on an %NL80211_ATTR_IFINDEX is supported. + * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires + * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. + * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response + * to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX, + * %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also + * be sent from userspace to request creation of a new virtual interface, + * then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and + * %NL80211_ATTR_IFNAME. + * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes + * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from + * userspace to request deletion of a virtual interface, then requires + * attribute %NL80211_ATTR_IFINDEX. + * + * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified + * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. + * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT, + * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD. + * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA, + * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER, + * and %NL80211_ATTR_KEY_SEQ attributes. + * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX + * or %NL80211_ATTR_MAC. + * + * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a + * %NL80222_CMD_NEW_BEACON message) + * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface + * using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD, + * %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL attributes. + * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface, + * parameters are like for %NL80211_CMD_SET_BEACON. + * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it + * + * @NL80211_CMD_GET_STATION: Get station attributes for station identified by + * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_SET_STATION: Set station attributes for station identified by + * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the + * the interface identified by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC + * or, if no MAC address given, all stations, on the interface identified + * by %NL80211_ATTR_IFINDEX. + * + * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to + * destination %NL80211_ATTR_MAC on the interface identified by + * %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_SET_MPATH: Set mesh path attributes for mesh path to + * destination %NL80211_ATTR_MAC on the interface identified by + * %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the + * the interface identified by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC + * or, if no MAC address given, all mesh paths, on the interface identified + * by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by + * %NL80211_ATTR_IFINDEX. + * + * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set + * regulatory domain. + * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command + * after being queried by the kernel. CRDA replies by sending a regulatory + * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our + * current alpha2 if it found a match. It also provides + * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each + * regulatory rule is a nested set of attributes given by + * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and + * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by + * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and + * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP. + * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain + * to the specified ISO/IEC 3166-1 alpha2 country code. The core will + * store this as a valid request and then query userspace for it. + * + * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the + * interface identified by %NL80211_ATTR_IFINDEX + * + * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the + * interface identified by %NL80211_ATTR_IFINDEX + * + * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The + * interface is identified with %NL80211_ATTR_IFINDEX and the management + * frame subtype with %NL80211_ATTR_MGMT_SUBTYPE. The extra IE data to be + * added to the end of the specified management frame is specified with + * %NL80211_ATTR_IE. If the command succeeds, the requested data will be + * added to all specified management frames generated by + * kernel/firmware/driver. + * Note: This command has been removed and it is only reserved at this + * point to avoid re-using existing command number. The functionality this + * command was planned for has been provided with cleaner design with the + * option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN, + * NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE, + * NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE. + * + * @NL80211_CMD_GET_SCAN: get scan results + * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters + * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to + * NL80211_CMD_GET_SCAN and on the "scan" multicast group) + * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, + * partial scan results may be available + * + * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation + * or noise level + * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to + * NL80211_CMD_GET_SURVEY and on the "scan" multicast group) + * + * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain + * has been changed and provides details of the request information + * that caused the change such as who initiated the regulatory request + * (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx + * (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if + * the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or + * %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain + * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is + * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on + * to (%NL80211_ATTR_REG_ALPHA2). + * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon + * has been found while world roaming thus enabling active scan or + * any mode of operation that initiates TX (beacons) on a channel + * where we would not have been able to do either before. As an example + * if you are world roaming (regulatory domain set to world or if your + * driver is using a custom world roaming regulatory domain) and while + * doing a passive scan on the 5 GHz band you find an AP there (if not + * on a DFS channel) you will now be able to actively scan for that AP + * or use AP mode on your card on that same channel. Note that this will + * never be used for channels 1-11 on the 2 GHz band as they are always + * enabled world wide. This beacon hint is only sent if your device had + * either disabled active scanning or beaconing on a channel. We send to + * userspace the wiphy on which we removed a restriction from + * (%NL80211_ATTR_WIPHY) and the channel on which this occurred + * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER) + * the beacon hint was processed. + * + * @NL80211_CMD_AUTHENTICATE: authentication request and notification. + * This command is used both as a command (request to authenticate) and + * as an event on the "mlme" multicast group indicating completion of the + * authentication process. + * When used as a command, %NL80211_ATTR_IFINDEX is used to identify the + * interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and + * BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify + * the SSID (mainly for association, but is included in authentication + * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used + * to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE + * is used to specify the authentication type. %NL80211_ATTR_IE is used to + * define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs) + * to be added to the frame. + * When used as an event, this reports reception of an Authentication + * frame in station and IBSS modes when the local MLME processed the + * frame, i.e., it was for the local STA and was received in correct + * state. This is similar to MLME-AUTHENTICATE.confirm primitive in the + * MLME SAP interface (kernel providing MLME, userspace SME). The + * included %NL80211_ATTR_FRAME attribute contains the management frame + * (including both the header and frame body, but not FCS). This event is + * also used to indicate if the authentication attempt timed out. In that + * case the %NL80211_ATTR_FRAME attribute is replaced with a + * %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which + * pending authentication timed out). + * @NL80211_CMD_ASSOCIATE: association request and notification; like + * NL80211_CMD_AUTHENTICATE but for Association and Reassociation + * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request, + * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives). + * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like + * NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to + * MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication + * primitives). + * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like + * NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to + * MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives). + * + * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael + * MIC (part of TKIP) failure; sent on the "mlme" multicast group; the + * event includes %NL80211_ATTR_MAC to describe the source MAC address of + * the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key + * type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and + * %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this + * event matches with MLME-MICHAELMICFAILURE.indication() primitive + * + * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a + * FREQ attribute (for the initial frequency if no peer can be found) + * and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those + * should be fixed rather than automatically determined. Can only be + * executed on a network interface that is UP, and fixed BSSID/FREQ + * may be rejected. Another optional parameter is the beacon interval, + * given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not + * given defaults to 100 TU (102.4ms). + * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is + * determined by the network interface. + * + * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute + * to identify the device, and the TESTDATA blob attribute to pass through + * to the driver. + * + * @NL80211_CMD_CONNECT: connection request and notification; this command + * requests to connect to a specified network but without separating + * auth and assoc steps. For this, you need to specify the SSID in a + * %NL80211_ATTR_SSID attribute, and can optionally specify the association + * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC, + * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. + * It is also sent as an event, with the BSSID and response IEs when the + * connection is established or failed to be established. This can be + * determined by the STATUS_CODE attribute. + * @NL80211_CMD_ROAM: request that the card roam (currently not implemented), + * sent as an event when the card/driver roamed by itself. + * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify + * userspace that a connection was dropped by the AP or due to other + * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and + * %NL80211_ATTR_REASON_CODE attributes are used. + * + * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices + * associated with this wiphy must be down and will follow. + * + * @NL80211_CMD_REMAIN_ON_CHANNEL: Request to remain awake on the specified + * channel for the specified amount of time. This can be used to do + * off-channel operations like transmit a Public Action frame and wait for + * a response while being associated to an AP on another channel. + * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus + * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the + * frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be + * optionally used to specify additional channel parameters. + * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds + * to remain on the channel. This command is also used as an event to + * notify when the requested duration starts (it may take a while for the + * driver to schedule this time due to other concurrent needs for the + * radio). + * When called, this operation returns a cookie (%NL80211_ATTR_COOKIE) + * that will be included with any events pertaining to this request; + * the cookie is also used to cancel the request. + * @NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: This command can be used to cancel a + * pending remain-on-channel duration if the desired operation has been + * completed prior to expiration of the originally requested duration. + * %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify the + * radio. The %NL80211_ATTR_COOKIE attribute must be given as well to + * uniquely identify the request. + * This command is also used as an event to notify when a requested + * remain-on-channel duration has expired. + * + * @NL80211_CMD_SET_TX_BITRATE_MASK: Set the mask of rates to be used in TX + * rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface + * and @NL80211_ATTR_TX_RATES the set of allowed rates. + * + * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames + * (via @NL80211_CMD_FRAME) for processing in userspace. This command + * requires an interface index, a frame type attribute (optional for + * backward compatibility reasons, if not given assumes action frames) + * and a match attribute containing the first few bytes of the frame + * that should match, e.g. a single byte for only a category match or + * four bytes for vendor frames including the OUI. The registration + * cannot be dropped, but is removed automatically when the netlink + * socket is closed. Multiple registrations can be made. + * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for + * backward compatibility + * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This + * command is used both as a request to transmit a management frame and + * as an event indicating reception of a frame that was not processed in + * kernel code, but is for us (i.e., which may need to be processed in a + * user space application). %NL80211_ATTR_FRAME is used to specify the + * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and + * optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on + * which channel the frame is to be transmitted or was received. If this + * channel is not the current channel (remain-on-channel or the + * operational channel) the device will switch to the given channel and + * transmit the frame, optionally waiting for a response for the time + * specified using %NL80211_ATTR_DURATION. When called, this operation + * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the + * TX status event pertaining to the TX request. + * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this + * command may be used with the corresponding cookie to cancel the wait + * time if it is known that it is no longer necessary. + * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility. + * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame + * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies + * the TX command and %NL80211_ATTR_FRAME includes the contents of the + * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged + * the frame. + * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for + * backward compatibility. + * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command + * is used to configure connection quality monitoring notification trigger + * levels. + * @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This + * command is used as an event to indicate the that a trigger level was + * reached. + * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ + * and %NL80211_ATTR_WIPHY_CHANNEL_TYPE) the given interface (identifed + * by %NL80211_ATTR_IFINDEX) shall operate on. + * In case multiple channels are supported by the device, the mechanism + * with which it switches channels is implementation-defined. + * When a monitor interface is given, it can only switch channel while + * no other interfaces are operating to avoid disturbing the operation + * of any other interfaces, and other interfaces will again take + * precedence when they are used. + * + * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. + * + * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial + * mesh config parameters may be given. + * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the + * network is determined by the network interface. + * + * @NL80211_CMD_MAX: highest used command number + * @__NL80211_CMD_AFTER_LAST: internal use + */ +enum nl80211_commands { +/* don't change the order or add anything inbetween, this is ABI! */ + NL80211_CMD_UNSPEC, + + NL80211_CMD_GET_WIPHY, /* can dump */ + NL80211_CMD_SET_WIPHY, + NL80211_CMD_NEW_WIPHY, + NL80211_CMD_DEL_WIPHY, + + NL80211_CMD_GET_INTERFACE, /* can dump */ + NL80211_CMD_SET_INTERFACE, + NL80211_CMD_NEW_INTERFACE, + NL80211_CMD_DEL_INTERFACE, + + NL80211_CMD_GET_KEY, + NL80211_CMD_SET_KEY, + NL80211_CMD_NEW_KEY, + NL80211_CMD_DEL_KEY, + + NL80211_CMD_GET_BEACON, + NL80211_CMD_SET_BEACON, + NL80211_CMD_NEW_BEACON, + NL80211_CMD_DEL_BEACON, + + NL80211_CMD_GET_STATION, + NL80211_CMD_SET_STATION, + NL80211_CMD_NEW_STATION, + NL80211_CMD_DEL_STATION, + + NL80211_CMD_GET_MPATH, + NL80211_CMD_SET_MPATH, + NL80211_CMD_NEW_MPATH, + NL80211_CMD_DEL_MPATH, + + NL80211_CMD_SET_BSS, + + NL80211_CMD_SET_REG, + NL80211_CMD_REQ_SET_REG, + + NL80211_CMD_GET_MESH_PARAMS, + NL80211_CMD_SET_MESH_PARAMS, + + NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */, + + NL80211_CMD_GET_REG, + + NL80211_CMD_GET_SCAN, + NL80211_CMD_TRIGGER_SCAN, + NL80211_CMD_NEW_SCAN_RESULTS, + NL80211_CMD_SCAN_ABORTED, + + NL80211_CMD_REG_CHANGE, + + NL80211_CMD_AUTHENTICATE, + NL80211_CMD_ASSOCIATE, + NL80211_CMD_DEAUTHENTICATE, + NL80211_CMD_DISASSOCIATE, + + NL80211_CMD_MICHAEL_MIC_FAILURE, + + NL80211_CMD_REG_BEACON_HINT, + + NL80211_CMD_JOIN_IBSS, + NL80211_CMD_LEAVE_IBSS, + + NL80211_CMD_TESTMODE, + + NL80211_CMD_CONNECT, + NL80211_CMD_ROAM, + NL80211_CMD_DISCONNECT, + + NL80211_CMD_SET_WIPHY_NETNS, + + NL80211_CMD_GET_SURVEY, + NL80211_CMD_NEW_SURVEY_RESULTS, + + NL80211_CMD_SET_PMKSA, + NL80211_CMD_DEL_PMKSA, + NL80211_CMD_FLUSH_PMKSA, + + NL80211_CMD_REMAIN_ON_CHANNEL, + NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, + + NL80211_CMD_SET_TX_BITRATE_MASK, + + NL80211_CMD_REGISTER_FRAME, + NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME, + NL80211_CMD_FRAME, + NL80211_CMD_ACTION = NL80211_CMD_FRAME, + NL80211_CMD_FRAME_TX_STATUS, + NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS, + + NL80211_CMD_SET_POWER_SAVE, + NL80211_CMD_GET_POWER_SAVE, + + NL80211_CMD_SET_CQM, + NL80211_CMD_NOTIFY_CQM, + + NL80211_CMD_SET_CHANNEL, + NL80211_CMD_SET_WDS_PEER, + + NL80211_CMD_FRAME_WAIT_CANCEL, + + NL80211_CMD_JOIN_MESH, + NL80211_CMD_LEAVE_MESH, + + /* add new commands above here */ + + /* used to define NL80211_CMD_MAX below */ + __NL80211_CMD_AFTER_LAST, + NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 +}; + +/* + * Allow user space programs to use #ifdef on new commands by defining them + * here + */ +#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS +#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE +#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE +#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE +#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE +#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE +#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE +#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT + +/** + * enum nl80211_attrs - nl80211 netlink attributes + * + * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors + * + * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf. + * /sys/class/ieee80211/<phyname>/index + * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) + * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters + * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz + * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ + * if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included): + * NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including + * this attribute) + * NL80211_CHAN_HT20 = HT20 only + * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel + * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel + * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is + * less than or equal to the RTS threshold; allowed range: 1..255; + * dot11ShortRetryLimit; u8 + * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is + * greater than the RTS threshold; allowed range: 1..255; + * dot11ShortLongLimit; u8 + * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum + * length in octets for frames; allowed range: 256..8000, disable + * fragmentation with (u32)-1; dot11FragmentationThreshold; u32 + * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length + * larger than or equal to this use RTS/CTS handshake); allowed range: + * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32 + * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11 + * section 7.3.2.9; dot11CoverageClass; u8 + * + * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on + * @NL80211_ATTR_IFNAME: network interface name + * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype + * + * @NL80211_ATTR_MAC: MAC address (various uses) + * + * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of + * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC + * keys + * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3) + * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 + * section 7.3.2.25.1, e.g. 0x000FAC04) + * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and + * CCMP keys, each six bytes in little endian + * + * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU + * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing + * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE + * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE + * + * @NL80211_ATTR_STA_AID: Association ID for the station (u16) + * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of + * &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2) + * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by + * IEEE 802.11 7.3.1.6 (u16). + * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported + * rates as defined by IEEE 802.11 7.3.2.2 but without the length + * restriction (at most %NL80211_MAX_SUPP_RATES). + * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station + * to, or the AP interface the station was originally added to to. + * @NL80211_ATTR_STA_INFO: information about a station, part of station info + * given for %NL80211_CMD_GET_STATION, nested attribute containing + * info as possible, see &enum nl80211_sta_info. + * + * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands, + * consisting of a nested array. + * + * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). + * @NL80211_ATTR_PLINK_ACTION: action to perform on the mesh peer link. + * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. + * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path + * info given for %NL80211_CMD_GET_MPATH, nested attribute described at + * &enum nl80211_mpath_info. + * + * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of + * &enum nl80211_mntr_flags. + * + * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the + * current regulatory domain should be set to or is already set to. + * For example, 'CR', for Costa Rica. This attribute is used by the kernel + * to query the CRDA to retrieve one regulatory domain. This attribute can + * also be used by userspace to query the kernel for the currently set + * regulatory domain. We chose an alpha2 as that is also used by the + * IEEE-802.11d country information element to identify a country. + * Users can also simply ask the wireless core to set regulatory domain + * to a specific alpha2. + * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory + * rules. + * + * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1) + * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled + * (u8, 0 or 1) + * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled + * (u8, 0 or 1) + * @NL80211_ATTR_BSS_BASIC_RATES: basic rates, array of basic + * rates in format defined by IEEE 802.11 7.3.2.2 but without the length + * restriction (at most %NL80211_MAX_SUPP_RATES). + * + * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from + * association request when used with NL80211_CMD_NEW_STATION) + * + * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all + * supported interface types, each a flag attribute with the number + * of the interface mode. + * + * @NL80211_ATTR_MGMT_SUBTYPE: Management frame subtype for + * %NL80211_CMD_SET_MGMT_EXTRA_IE. + * + * @NL80211_ATTR_IE: Information element(s) data (used, e.g., with + * %NL80211_CMD_SET_MGMT_EXTRA_IE). + * + * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with + * a single scan request, a wiphy attribute. + * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements + * that can be added to a scan request + * + * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz) + * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive + * scanning and include a zero-length SSID (wildcard) for wildcard scan + * @NL80211_ATTR_BSS: scan result BSS + * + * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain + * currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_* + * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently + * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*) + * + * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies + * an array of command numbers (i.e. a mapping index to command number) + * that the driver for the given wiphy supports. + * + * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header + * and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and + * NL80211_CMD_ASSOCIATE events + * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets) + * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type, + * represented as a u32 + * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and + * %NL80211_CMD_DISASSOCIATE, u16 + * + * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as + * a u32 + * + * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change + * due to considerations from a beacon hint. This attribute reflects + * the state of the channel _before_ the beacon hint processing. This + * attributes consists of a nested attribute containing + * NL80211_FREQUENCY_ATTR_* + * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change + * due to considerations from a beacon hint. This attribute reflects + * the state of the channel _after_ the beacon hint processing. This + * attributes consists of a nested attribute containing + * NL80211_FREQUENCY_ATTR_* + * + * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported + * cipher suites + * + * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look + * for other networks on different channels + * + * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this + * is used, e.g., with %NL80211_CMD_AUTHENTICATE event + * + * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is + * used for the association (&enum nl80211_mfp, represented as a u32); + * this attribute can be used + * with %NL80211_CMD_ASSOCIATE request + * + * @NL80211_ATTR_STA_FLAGS2: Attribute containing a + * &struct nl80211_sta_flag_update. + * + * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls + * IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in + * station mode. If the flag is included in %NL80211_CMD_ASSOCIATE + * request, the driver will assume that the port is unauthorized until + * authorized by user space. Otherwise, port is marked authorized by + * default in station mode. + * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the + * ethertype that will be used for key negotiation. It can be + * specified with the associate and connect commands. If it is not + * specified, the value defaults to 0x888E (PAE, 802.1X). This + * attribute is also used as a flag in the wiphy information to + * indicate that protocols other than PAE are supported. + * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom + * ethertype frames used for key negotiation must not be encrypted. + * + * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. + * We recommend using nested, driver-specific attributes within this. + * + * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT + * event was due to the AP disconnecting the station, and not due to + * a local disconnect request. + * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT + * event (u16) + * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating + * that protected APs should be used. + * + * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT and ASSOCIATE to + * indicate which unicast key ciphers will be used with the connection + * (an array of u32). + * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT and ASSOCIATE to indicate + * which group key cipher will be used with the connection (a u32). + * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT and ASSOCIATE to indicate + * which WPA version(s) the AP we want to associate with is using + * (a u32 with flags from &enum nl80211_wpa_versions). + * @NL80211_ATTR_AKM_SUITES: Used with CONNECT and ASSOCIATE to indicate + * which key management algorithm(s) to use (an array of u32). + * + * @NL80211_ATTR_REQ_IE: (Re)association request information elements as + * sent out by the card, for ROAM and successful CONNECT events. + * @NL80211_ATTR_RESP_IE: (Re)association response information elements as + * sent by peer, for ROAM and successful CONNECT events. + * + * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE + * commands to specify using a reassociate frame + * + * @NL80211_ATTR_KEY: key information in a nested attribute with + * %NL80211_KEY_* sub-attributes + * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect() + * and join_ibss(), key information is in a nested attribute each + * with %NL80211_KEY_* sub-attributes + * + * @NL80211_ATTR_PID: Process ID of a network namespace. + * + * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for + * dumps. This number increases whenever the object list being + * dumped changes, and as such userspace can verify that it has + * obtained a complete and consistent snapshot by verifying that + * all dump messages contain the same generation number. If it + * changed then the list changed and the dump should be repeated + * completely from scratch. + * + * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface + * + * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of + * the survey response for %NL80211_CMD_GET_SURVEY, nested attribute + * containing info as possible, see &enum survey_info. + * + * @NL80211_ATTR_PMKID: PMK material for PMKSA caching. + * @NL80211_ATTR_MAX_NUM_PMKIDS: maximum number of PMKIDs a firmware can + * cache, a wiphy attribute. + * + * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32. + * + * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects. + * + * @NL80211_ATTR_TX_RATES: Nested set of attributes + * (enum nl80211_tx_rate_attributes) describing TX rates per band. The + * enum nl80211_band value is used as the index (nla_type() of the nested + * data. If a band is not included, it will be configured to allow all + * rates based on negotiated supported rates information. This attribute + * is used with %NL80211_CMD_SET_TX_BITRATE_MASK. + * + * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain + * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. + * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the + * @NL80211_CMD_REGISTER_FRAME command. + * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a + * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing + * information about which frame types can be transmitted with + * %NL80211_CMD_FRAME. + * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a + * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing + * information about which frame types can be registered for RX. + * + * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was + * acknowledged by the recipient. + * + * @NL80211_ATTR_CQM: connection quality monitor configuration in a + * nested attribute with %NL80211_ATTR_CQM_* sub-attributes. + * + * @NL80211_ATTR_LOCAL_STATE_CHANGE: Flag attribute to indicate that a command + * is requesting a local authentication/association state change without + * invoking actual management frame exchange. This can be used with + * NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE, + * NL80211_CMD_DISASSOCIATE. + * + * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations + * connected to this BSS. + * + * @NL80211_ATTR_WIPHY_TX_POWER_SETTING: Transmit power setting type. See + * &enum nl80211_tx_power_setting for possible values. + * @NL80211_ATTR_WIPHY_TX_POWER_LEVEL: Transmit power level in signed mBm units. + * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING + * for non-automatic settings. + * + * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly + * means support for per-station GTKs. + * + * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting. + * This can be used to mask out antennas which are not attached or should + * not be used for transmitting. If an antenna is not selected in this + * bitmap the hardware is not allowed to transmit on this antenna. + * + * Each bit represents one antenna, starting with antenna 1 at the first + * bit. Depending on which antennas are selected in the bitmap, 802.11n + * drivers can derive which chainmasks to use (if all antennas belonging to + * a particular chain are disabled this chain should be disabled) and if + * a chain has diversity antennas whether diversity should be used or not. + * HT capabilities (STBC, TX Beamforming, Antenna selection) can be + * derived from the available chains after applying the antenna mask. + * Non-802.11n drivers can derive wether to use diversity or not. + * Drivers may reject configurations or RX/TX mask combinations they cannot + * support by returning -EINVAL. + * + * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving. + * This can be used to mask out antennas which are not attached or should + * not be used for receiving. If an antenna is not selected in this bitmap + * the hardware should not be configured to receive on this antenna. + * For a more detailed description see @NL80211_ATTR_WIPHY_ANTENNA_TX. + * + * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS + * + * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be + * transmitted on another channel when the channel given doesn't match + * the current channel. If the current channel doesn't match and this + * flag isn't set, the frame will be rejected. This is also used as an + * nl80211 capability flag. + * + * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16) + * + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use + */ +enum nl80211_attrs { +/* don't change the order or add anything between, this is ABI! */ + NL80211_ATTR_UNSPEC, + + NL80211_ATTR_WIPHY, + NL80211_ATTR_WIPHY_NAME, + + NL80211_ATTR_IFINDEX, + NL80211_ATTR_IFNAME, + NL80211_ATTR_IFTYPE, + + NL80211_ATTR_MAC, + + NL80211_ATTR_KEY_DATA, + NL80211_ATTR_KEY_IDX, + NL80211_ATTR_KEY_CIPHER, + NL80211_ATTR_KEY_SEQ, + NL80211_ATTR_KEY_DEFAULT, + + NL80211_ATTR_BEACON_INTERVAL, + NL80211_ATTR_DTIM_PERIOD, + NL80211_ATTR_BEACON_HEAD, + NL80211_ATTR_BEACON_TAIL, + + NL80211_ATTR_STA_AID, + NL80211_ATTR_STA_FLAGS, + NL80211_ATTR_STA_LISTEN_INTERVAL, + NL80211_ATTR_STA_SUPPORTED_RATES, + NL80211_ATTR_STA_VLAN, + NL80211_ATTR_STA_INFO, + + NL80211_ATTR_WIPHY_BANDS, + + NL80211_ATTR_MNTR_FLAGS, + + NL80211_ATTR_MESH_ID, + NL80211_ATTR_STA_PLINK_ACTION, + NL80211_ATTR_MPATH_NEXT_HOP, + NL80211_ATTR_MPATH_INFO, + + NL80211_ATTR_BSS_CTS_PROT, + NL80211_ATTR_BSS_SHORT_PREAMBLE, + NL80211_ATTR_BSS_SHORT_SLOT_TIME, + + NL80211_ATTR_HT_CAPABILITY, + + NL80211_ATTR_SUPPORTED_IFTYPES, + + NL80211_ATTR_REG_ALPHA2, + NL80211_ATTR_REG_RULES, + + NL80211_ATTR_MESH_PARAMS, + + NL80211_ATTR_BSS_BASIC_RATES, + + NL80211_ATTR_WIPHY_TXQ_PARAMS, + NL80211_ATTR_WIPHY_FREQ, + NL80211_ATTR_WIPHY_CHANNEL_TYPE, + + NL80211_ATTR_KEY_DEFAULT_MGMT, + + NL80211_ATTR_MGMT_SUBTYPE, + NL80211_ATTR_IE, + + NL80211_ATTR_MAX_NUM_SCAN_SSIDS, + + NL80211_ATTR_SCAN_FREQUENCIES, + NL80211_ATTR_SCAN_SSIDS, + NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */ + NL80211_ATTR_BSS, + + NL80211_ATTR_REG_INITIATOR, + NL80211_ATTR_REG_TYPE, + + NL80211_ATTR_SUPPORTED_COMMANDS, + + NL80211_ATTR_FRAME, + NL80211_ATTR_SSID, + NL80211_ATTR_AUTH_TYPE, + NL80211_ATTR_REASON_CODE, + + NL80211_ATTR_KEY_TYPE, + + NL80211_ATTR_MAX_SCAN_IE_LEN, + NL80211_ATTR_CIPHER_SUITES, + + NL80211_ATTR_FREQ_BEFORE, + NL80211_ATTR_FREQ_AFTER, + + NL80211_ATTR_FREQ_FIXED, + + + NL80211_ATTR_WIPHY_RETRY_SHORT, + NL80211_ATTR_WIPHY_RETRY_LONG, + NL80211_ATTR_WIPHY_FRAG_THRESHOLD, + NL80211_ATTR_WIPHY_RTS_THRESHOLD, + + NL80211_ATTR_TIMED_OUT, + + NL80211_ATTR_USE_MFP, + + NL80211_ATTR_STA_FLAGS2, + + NL80211_ATTR_CONTROL_PORT, + + NL80211_ATTR_TESTDATA, + + NL80211_ATTR_PRIVACY, + + NL80211_ATTR_DISCONNECTED_BY_AP, + NL80211_ATTR_STATUS_CODE, + + NL80211_ATTR_CIPHER_SUITES_PAIRWISE, + NL80211_ATTR_CIPHER_SUITE_GROUP, + NL80211_ATTR_WPA_VERSIONS, + NL80211_ATTR_AKM_SUITES, + + NL80211_ATTR_REQ_IE, + NL80211_ATTR_RESP_IE, + + NL80211_ATTR_PREV_BSSID, + + NL80211_ATTR_KEY, + NL80211_ATTR_KEYS, + + NL80211_ATTR_PID, + + NL80211_ATTR_4ADDR, + + NL80211_ATTR_SURVEY_INFO, + + NL80211_ATTR_PMKID, + NL80211_ATTR_MAX_NUM_PMKIDS, + + NL80211_ATTR_DURATION, + + NL80211_ATTR_COOKIE, + + NL80211_ATTR_WIPHY_COVERAGE_CLASS, + + NL80211_ATTR_TX_RATES, + + NL80211_ATTR_FRAME_MATCH, + + NL80211_ATTR_ACK, + + NL80211_ATTR_PS_STATE, + + NL80211_ATTR_CQM, + + NL80211_ATTR_LOCAL_STATE_CHANGE, + + NL80211_ATTR_AP_ISOLATE, + + NL80211_ATTR_WIPHY_TX_POWER_SETTING, + NL80211_ATTR_WIPHY_TX_POWER_LEVEL, + + NL80211_ATTR_TX_FRAME_TYPES, + NL80211_ATTR_RX_FRAME_TYPES, + NL80211_ATTR_FRAME_TYPE, + + NL80211_ATTR_CONTROL_PORT_ETHERTYPE, + NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, + + NL80211_ATTR_SUPPORT_IBSS_RSN, + + NL80211_ATTR_WIPHY_ANTENNA_TX, + NL80211_ATTR_WIPHY_ANTENNA_RX, + + NL80211_ATTR_MCAST_RATE, + + NL80211_ATTR_OFFCHANNEL_TX_OK, + + NL80211_ATTR_BSS_HT_OPMODE, + + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, + NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 +}; + +/* source-level API compatibility */ +#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION + +/* + * Allow user space programs to use #ifdef on new attributes by defining them + * here + */ +#define NL80211_CMD_CONNECT NL80211_CMD_CONNECT +#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY +#define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES +#define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS +#define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ +#define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE +#define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE +#define NL80211_ATTR_IE NL80211_ATTR_IE +#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR +#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE +#define NL80211_ATTR_FRAME NL80211_ATTR_FRAME +#define NL80211_ATTR_SSID NL80211_ATTR_SSID +#define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE +#define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE +#define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE +#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP +#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS +#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES +#define NL80211_ATTR_KEY NL80211_ATTR_KEY +#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS + +#define NL80211_MAX_SUPP_RATES 32 +#define NL80211_MAX_SUPP_REG_RULES 32 +#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 +#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 +#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 +#define NL80211_HT_CAPABILITY_LEN 26 + +#define NL80211_MAX_NR_CIPHER_SUITES 5 +#define NL80211_MAX_NR_AKM_SUITES 2 + +/** + * enum nl80211_iftype - (virtual) interface types + * + * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides + * @NL80211_IFTYPE_ADHOC: independent BSS member + * @NL80211_IFTYPE_STATION: managed BSS member + * @NL80211_IFTYPE_AP: access point + * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points + * @NL80211_IFTYPE_WDS: wireless distribution interface + * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames + * @NL80211_IFTYPE_MESH_POINT: mesh point + * @NL80211_IFTYPE_P2P_CLIENT: P2P client + * @NL80211_IFTYPE_P2P_GO: P2P group owner + * @NL80211_IFTYPE_MAX: highest interface type number currently defined + * @NUM_NL80211_IFTYPES: number of defined interface types + * + * These values are used with the %NL80211_ATTR_IFTYPE + * to set the type of an interface. + * + */ +enum nl80211_iftype { + NL80211_IFTYPE_UNSPECIFIED, + NL80211_IFTYPE_ADHOC, + NL80211_IFTYPE_STATION, + NL80211_IFTYPE_AP, + NL80211_IFTYPE_AP_VLAN, + NL80211_IFTYPE_WDS, + NL80211_IFTYPE_MONITOR, + NL80211_IFTYPE_MESH_POINT, + NL80211_IFTYPE_P2P_CLIENT, + NL80211_IFTYPE_P2P_GO, + + /* keep last */ + NUM_NL80211_IFTYPES, + NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 +}; + +/** + * enum nl80211_sta_flags - station flags + * + * Station flags. When a station is added to an AP interface, it is + * assumed to be already associated (and hence authenticated.) + * + * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved + * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X) + * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames + * with short barker preamble + * @NL80211_STA_FLAG_WME: station is WME/QoS capable + * @NL80211_STA_FLAG_MFP: station uses management frame protection + * @NL80211_STA_FLAG_MAX: highest station flag number currently defined + * @__NL80211_STA_FLAG_AFTER_LAST: internal use + */ +enum nl80211_sta_flags { + __NL80211_STA_FLAG_INVALID, + NL80211_STA_FLAG_AUTHORIZED, + NL80211_STA_FLAG_SHORT_PREAMBLE, + NL80211_STA_FLAG_WME, + NL80211_STA_FLAG_MFP, + + /* keep last */ + __NL80211_STA_FLAG_AFTER_LAST, + NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 +}; + +/** + * struct nl80211_sta_flag_update - station flags mask/set + * @mask: mask of station flags to set + * @set: which values to set them to + * + * Both mask and set contain bits as per &enum nl80211_sta_flags. + */ +struct nl80211_sta_flag_update { + __u32 mask; + __u32 set; +} __attribute__((packed)); + +/** + * enum nl80211_rate_info - bitrate information + * + * These attribute types are used with %NL80211_STA_INFO_TXRATE + * when getting information about the bitrate of a station. + * + * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved + * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) + * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) + * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate + * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval + * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined + * @__NL80211_RATE_INFO_AFTER_LAST: internal use + */ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, + NL80211_RATE_INFO_BITRATE, + NL80211_RATE_INFO_MCS, + NL80211_RATE_INFO_40_MHZ_WIDTH, + NL80211_RATE_INFO_SHORT_GI, + + /* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, + NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1 +}; + +/** + * enum nl80211_sta_info - station information + * + * These attribute types are used with %NL80211_ATTR_STA_INFO + * when getting information about a station. + * + * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved + * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) + * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station) + * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) + * @__NL80211_STA_INFO_AFTER_LAST: internal + * @NL80211_STA_INFO_MAX: highest possible station info attribute + * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) + * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute + * containing info as possible, see &enum nl80211_sta_info_txrate. + * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) + * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this + * station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) + * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) + */ +enum nl80211_sta_info { + __NL80211_STA_INFO_INVALID, + NL80211_STA_INFO_INACTIVE_TIME, + NL80211_STA_INFO_RX_BYTES, + NL80211_STA_INFO_TX_BYTES, + NL80211_STA_INFO_LLID, + NL80211_STA_INFO_PLID, + NL80211_STA_INFO_PLINK_STATE, + NL80211_STA_INFO_SIGNAL, + NL80211_STA_INFO_TX_BITRATE, + NL80211_STA_INFO_RX_PACKETS, + NL80211_STA_INFO_TX_PACKETS, + NL80211_STA_INFO_TX_RETRIES, + NL80211_STA_INFO_TX_FAILED, + NL80211_STA_INFO_SIGNAL_AVG, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, + NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1 +}; + +/** + * enum nl80211_mpath_flags - nl80211 mesh path flags + * + * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active + * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running + * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN + * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set + * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded + */ +enum nl80211_mpath_flags { + NL80211_MPATH_FLAG_ACTIVE = 1<<0, + NL80211_MPATH_FLAG_RESOLVING = 1<<1, + NL80211_MPATH_FLAG_SN_VALID = 1<<2, + NL80211_MPATH_FLAG_FIXED = 1<<3, + NL80211_MPATH_FLAG_RESOLVED = 1<<4, +}; + +/** + * enum nl80211_mpath_info - mesh path information + * + * These attribute types are used with %NL80211_ATTR_MPATH_INFO when getting + * information about a mesh path. + * + * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved + * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination + * @NL80211_MPATH_INFO_SN: destination sequence number + * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path + * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now + * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in + * &enum nl80211_mpath_flags; + * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec + * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries + * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number + * currently defind + * @__NL80211_MPATH_INFO_AFTER_LAST: internal use + */ +enum nl80211_mpath_info { + __NL80211_MPATH_INFO_INVALID, + NL80211_MPATH_INFO_FRAME_QLEN, + NL80211_MPATH_INFO_SN, + NL80211_MPATH_INFO_METRIC, + NL80211_MPATH_INFO_EXPTIME, + NL80211_MPATH_INFO_FLAGS, + NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, + NL80211_MPATH_INFO_DISCOVERY_RETRIES, + + /* keep last */ + __NL80211_MPATH_INFO_AFTER_LAST, + NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1 +}; + +/** + * enum nl80211_band_attr - band attributes + * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band, + * an array of nested frequency attributes + * @NL80211_BAND_ATTR_RATES: supported bitrates in this band, + * an array of nested bitrate attributes + * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as + * defined in 802.11n + * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE + * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n + * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n + * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined + * @__NL80211_BAND_ATTR_AFTER_LAST: internal use + */ +enum nl80211_band_attr { + __NL80211_BAND_ATTR_INVALID, + NL80211_BAND_ATTR_FREQS, + NL80211_BAND_ATTR_RATES, + + NL80211_BAND_ATTR_HT_MCS_SET, + NL80211_BAND_ATTR_HT_CAPA, + NL80211_BAND_ATTR_HT_AMPDU_FACTOR, + NL80211_BAND_ATTR_HT_AMPDU_DENSITY, + + /* keep last */ + __NL80211_BAND_ATTR_AFTER_LAST, + NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 +}; + +#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA + +/** + * enum nl80211_frequency_attr - frequency attributes + * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz + * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current + * regulatory domain. + * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is + * permitted on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm + * (100 * dBm). + * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number + * currently defined + * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use + */ +enum nl80211_frequency_attr { + __NL80211_FREQUENCY_ATTR_INVALID, + NL80211_FREQUENCY_ATTR_FREQ, + NL80211_FREQUENCY_ATTR_DISABLED, + NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, + NL80211_FREQUENCY_ATTR_NO_IBSS, + NL80211_FREQUENCY_ATTR_RADAR, + NL80211_FREQUENCY_ATTR_MAX_TX_POWER, + + /* keep last */ + __NL80211_FREQUENCY_ATTR_AFTER_LAST, + NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1 +}; + +#define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER + +/** + * enum nl80211_bitrate_attr - bitrate attributes + * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps + * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported + * in 2.4 GHz band. + * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number + * currently defined + * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use + */ +enum nl80211_bitrate_attr { + __NL80211_BITRATE_ATTR_INVALID, + NL80211_BITRATE_ATTR_RATE, + NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE, + + /* keep last */ + __NL80211_BITRATE_ATTR_AFTER_LAST, + NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_initiator - Indicates the initiator of a reg domain request + * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world + * regulatory domain. + * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the + * regulatory domain. + * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the + * wireless core it thinks its knows the regulatory domain we should be in. + * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an + * 802.11 country information element with regulatory information it + * thinks we should consider. cfg80211 only processes the country + * code from the IE, and relies on the regulatory domain information + * structure passed by userspace (CRDA) from our wireless-regdb. + * If a channel is enabled but the country code indicates it should + * be disabled we disable the channel and re-enable it upon disassociation. + */ +enum nl80211_reg_initiator { + NL80211_REGDOM_SET_BY_CORE, + NL80211_REGDOM_SET_BY_USER, + NL80211_REGDOM_SET_BY_DRIVER, + NL80211_REGDOM_SET_BY_COUNTRY_IE, +}; + +/** + * enum nl80211_reg_type - specifies the type of regulatory domain + * @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains + * to a specific country. When this is set you can count on the + * ISO / IEC 3166 alpha2 country code being valid. + * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory + * domain. + * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom + * driver specific world regulatory domain. These do not apply system-wide + * and are only applicable to the individual devices which have requested + * them to be applied. + * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product + * of an intersection between two regulatory domains -- the previously + * set regulatory domain on the system and the last accepted regulatory + * domain request to be processed. + */ +enum nl80211_reg_type { + NL80211_REGDOM_TYPE_COUNTRY, + NL80211_REGDOM_TYPE_WORLD, + NL80211_REGDOM_TYPE_CUSTOM_WORLD, + NL80211_REGDOM_TYPE_INTERSECTION, +}; + +/** + * enum nl80211_reg_rule_attr - regulatory rule attributes + * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional + * considerations for a given frequency range. These are the + * &enum nl80211_reg_rule_flags. + * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory + * rule in KHz. This is not a center of frequency but an actual regulatory + * band edge. + * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule + * in KHz. This is not a center a frequency but an actual regulatory + * band edge. + * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this + * frequency range, in KHz. + * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain + * for a given frequency range. The value is in mBi (100 * dBi). + * If you don't have one then don't send this. + * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for + * a given frequency range. The value is in mBm (100 * dBm). + * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number + * currently defined + * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use + */ +enum nl80211_reg_rule_attr { + __NL80211_REG_RULE_ATTR_INVALID, + NL80211_ATTR_REG_RULE_FLAGS, + + NL80211_ATTR_FREQ_RANGE_START, + NL80211_ATTR_FREQ_RANGE_END, + NL80211_ATTR_FREQ_RANGE_MAX_BW, + + NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, + NL80211_ATTR_POWER_RULE_MAX_EIRP, + + /* keep last */ + __NL80211_REG_RULE_ATTR_AFTER_LAST, + NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_reg_rule_flags - regulatory rule flags + * + * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed + * @NL80211_RRF_NO_CCK: CCK modulation not allowed + * @NL80211_RRF_NO_INDOOR: indoor operation not allowed + * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed + * @NL80211_RRF_DFS: DFS support is required to be used + * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links + * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links + * @NL80211_RRF_PASSIVE_SCAN: passive scan is required + * @NL80211_RRF_NO_IBSS: no IBSS is allowed + */ +enum nl80211_reg_rule_flags { + NL80211_RRF_NO_OFDM = 1<<0, + NL80211_RRF_NO_CCK = 1<<1, + NL80211_RRF_NO_INDOOR = 1<<2, + NL80211_RRF_NO_OUTDOOR = 1<<3, + NL80211_RRF_DFS = 1<<4, + NL80211_RRF_PTP_ONLY = 1<<5, + NL80211_RRF_PTMP_ONLY = 1<<6, + NL80211_RRF_PASSIVE_SCAN = 1<<7, + NL80211_RRF_NO_IBSS = 1<<8, +}; + +/** + * enum nl80211_survey_info - survey information + * + * These attribute types are used with %NL80211_ATTR_SURVEY_INFO + * when getting information about a survey. + * + * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved + * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel + * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) + * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used + * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio + * spent on this channel + * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary + * channel was sensed busy (either due to activity or energy detect) + * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension + * channel was sensed busy + * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent + * receiving data + * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent + * transmitting data + * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number + * currently defined + * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use + */ +enum nl80211_survey_info { + __NL80211_SURVEY_INFO_INVALID, + NL80211_SURVEY_INFO_FREQUENCY, + NL80211_SURVEY_INFO_NOISE, + NL80211_SURVEY_INFO_IN_USE, + NL80211_SURVEY_INFO_CHANNEL_TIME, + NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + NL80211_SURVEY_INFO_CHANNEL_TIME_TX, + + /* keep last */ + __NL80211_SURVEY_INFO_AFTER_LAST, + NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 +}; + +/** + * enum nl80211_mntr_flags - monitor configuration flags + * + * Monitor configuration flags. + * + * @__NL80211_MNTR_FLAG_INVALID: reserved + * + * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS + * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP + * @NL80211_MNTR_FLAG_CONTROL: pass control frames + * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering + * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing. + * overrides all other flags. + * + * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use + * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag + */ +enum nl80211_mntr_flags { + __NL80211_MNTR_FLAG_INVALID, + NL80211_MNTR_FLAG_FCSFAIL, + NL80211_MNTR_FLAG_PLCPFAIL, + NL80211_MNTR_FLAG_CONTROL, + NL80211_MNTR_FLAG_OTHER_BSS, + NL80211_MNTR_FLAG_COOK_FRAMES, + + /* keep last */ + __NL80211_MNTR_FLAG_AFTER_LAST, + NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1 +}; + +/** + * enum nl80211_meshconf_params - mesh configuration parameters + * + * Mesh configuration parameters + * + * @__NL80211_MESHCONF_INVALID: internal use + * + * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in + * millisecond units, used by the Peer Link Open message + * + * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in + * millisecond units, used by the peer link management to close a peer link + * + * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in + * millisecond units + * + * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed + * on this mesh interface + * + * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link + * open retries that can be sent to establish a new peer link instance in a + * mesh + * + * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh + * point. + * + * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a + * source mesh point for path selection elements. + * + * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically + * open peer links when we detect compatible mesh peers. + * + * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames + * containing a PREQ that an MP can send to a particular destination (path + * target) + * + * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths + * (in milliseconds) + * + * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait + * until giving up on a path discovery (in milliseconds) + * + * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh + * points receiving a PREQ shall consider the forwarding information from the + * root to be valid. (TU = time unit) + * + * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in + * TUs) during which an MP can send only one action frame containing a PREQ + * reference element + * + * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) + * that it takes for an HWMP information element to propagate across the mesh + * + * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not + * + * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute + * + * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use + */ +enum nl80211_meshconf_params { + __NL80211_MESHCONF_INVALID, + NL80211_MESHCONF_RETRY_TIMEOUT, + NL80211_MESHCONF_CONFIRM_TIMEOUT, + NL80211_MESHCONF_HOLDING_TIMEOUT, + NL80211_MESHCONF_MAX_PEER_LINKS, + NL80211_MESHCONF_MAX_RETRIES, + NL80211_MESHCONF_TTL, + NL80211_MESHCONF_AUTO_OPEN_PLINKS, + NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, + NL80211_MESHCONF_PATH_REFRESH_TIME, + NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, + NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, + NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, + NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, + NL80211_MESHCONF_HWMP_ROOTMODE, + NL80211_MESHCONF_ELEMENT_TTL, + + /* keep last */ + __NL80211_MESHCONF_ATTR_AFTER_LAST, + NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_txq_attr - TX queue parameter attributes + * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved + * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*) + * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning + * disabled + * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form + * 2^n-1 in the range 1..32767] + * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form + * 2^n-1 in the range 1..32767] + * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255] + * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal + * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number + */ +enum nl80211_txq_attr { + __NL80211_TXQ_ATTR_INVALID, + NL80211_TXQ_ATTR_QUEUE, + NL80211_TXQ_ATTR_TXOP, + NL80211_TXQ_ATTR_CWMIN, + NL80211_TXQ_ATTR_CWMAX, + NL80211_TXQ_ATTR_AIFS, + + /* keep last */ + __NL80211_TXQ_ATTR_AFTER_LAST, + NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1 +}; + +enum nl80211_txq_q { + NL80211_TXQ_Q_VO, + NL80211_TXQ_Q_VI, + NL80211_TXQ_Q_BE, + NL80211_TXQ_Q_BK +}; + +enum nl80211_channel_type { + NL80211_CHAN_NO_HT, + NL80211_CHAN_HT20, + NL80211_CHAN_HT40MINUS, + NL80211_CHAN_HT40PLUS +}; + +/** + * enum nl80211_bss - netlink attributes for a BSS + * + * @__NL80211_BSS_INVALID: invalid + * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets) + * @NL80211_BSS_FREQUENCY: frequency in MHz (u32) + * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64) + * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) + * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16) + * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the + * raw information elements from the probe response/beacon (bin); + * if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are + * from a Probe Response frame; otherwise they are from a Beacon frame. + * However, if the driver does not indicate the source of the IEs, these + * IEs may be from either frame subtype. + * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon + * in mBm (100 * dBm) (s32) + * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon + * in unspecified units, scaled to 0..100 (u8) + * @NL80211_BSS_STATUS: status, if this BSS is "used" + * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms + * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information + * elements from a Beacon frame (bin); not present if no Beacon frame has + * yet been received + * @__NL80211_BSS_AFTER_LAST: internal + * @NL80211_BSS_MAX: highest BSS attribute + */ +enum nl80211_bss { + __NL80211_BSS_INVALID, + NL80211_BSS_BSSID, + NL80211_BSS_FREQUENCY, + NL80211_BSS_TSF, + NL80211_BSS_BEACON_INTERVAL, + NL80211_BSS_CAPABILITY, + NL80211_BSS_INFORMATION_ELEMENTS, + NL80211_BSS_SIGNAL_MBM, + NL80211_BSS_SIGNAL_UNSPEC, + NL80211_BSS_STATUS, + NL80211_BSS_SEEN_MS_AGO, + NL80211_BSS_BEACON_IES, + + /* keep last */ + __NL80211_BSS_AFTER_LAST, + NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1 +}; + +/** + * enum nl80211_bss_status - BSS "status" + * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. + * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. + * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. + * + * The BSS status is a BSS attribute in scan dumps, which + * indicates the status the interface has wrt. this BSS. + */ +enum nl80211_bss_status { + NL80211_BSS_STATUS_AUTHENTICATED, + NL80211_BSS_STATUS_ASSOCIATED, + NL80211_BSS_STATUS_IBSS_JOINED, +}; + +/** + * enum nl80211_auth_type - AuthenticationType + * + * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication + * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) + * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) + * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) + * @__NL80211_AUTHTYPE_NUM: internal + * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm + * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by + * trying multiple times); this is invalid in netlink -- leave out + * the attribute for this on CONNECT commands. + */ +enum nl80211_auth_type { + NL80211_AUTHTYPE_OPEN_SYSTEM, + NL80211_AUTHTYPE_SHARED_KEY, + NL80211_AUTHTYPE_FT, + NL80211_AUTHTYPE_NETWORK_EAP, + + /* keep last */ + __NL80211_AUTHTYPE_NUM, + NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1, + NL80211_AUTHTYPE_AUTOMATIC +}; + +/** + * enum nl80211_key_type - Key Type + * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key + * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key + * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS) + * @NUM_NL80211_KEYTYPES: number of defined key types + */ +enum nl80211_key_type { + NL80211_KEYTYPE_GROUP, + NL80211_KEYTYPE_PAIRWISE, + NL80211_KEYTYPE_PEERKEY, + + NUM_NL80211_KEYTYPES +}; + +/** + * enum nl80211_mfp - Management frame protection state + * @NL80211_MFP_NO: Management frame protection not used + * @NL80211_MFP_REQUIRED: Management frame protection required + */ +enum nl80211_mfp { + NL80211_MFP_NO, + NL80211_MFP_REQUIRED, +}; + +enum nl80211_wpa_versions { + NL80211_WPA_VERSION_1 = 1 << 0, + NL80211_WPA_VERSION_2 = 1 << 1, +}; + +/** + * enum nl80211_key_attributes - key attributes + * @__NL80211_KEY_INVALID: invalid + * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of + * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC + * keys + * @NL80211_KEY_IDX: key ID (u8, 0-3) + * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 + * section 7.3.2.25.1, e.g. 0x000FAC04) + * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and + * CCMP keys, each six bytes in little endian + * @NL80211_KEY_DEFAULT: flag indicating default key + * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key + * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not + * specified the default depends on whether a MAC address was + * given with the command using the key or not (u32) + * @__NL80211_KEY_AFTER_LAST: internal + * @NL80211_KEY_MAX: highest key attribute + */ +enum nl80211_key_attributes { + __NL80211_KEY_INVALID, + NL80211_KEY_DATA, + NL80211_KEY_IDX, + NL80211_KEY_CIPHER, + NL80211_KEY_SEQ, + NL80211_KEY_DEFAULT, + NL80211_KEY_DEFAULT_MGMT, + NL80211_KEY_TYPE, + + /* keep last */ + __NL80211_KEY_AFTER_LAST, + NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1 +}; + +/** + * enum nl80211_tx_rate_attributes - TX rate set attributes + * @__NL80211_TXRATE_INVALID: invalid + * @NL80211_TXRATE_LEGACY: Legacy (non-MCS) rates allowed for TX rate selection + * in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with + * 1 = 500 kbps) but without the IE length restriction (at most + * %NL80211_MAX_SUPP_RATES in a single array). + * @__NL80211_TXRATE_AFTER_LAST: internal + * @NL80211_TXRATE_MAX: highest TX rate attribute + */ +enum nl80211_tx_rate_attributes { + __NL80211_TXRATE_INVALID, + NL80211_TXRATE_LEGACY, + + /* keep last */ + __NL80211_TXRATE_AFTER_LAST, + NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 +}; + +/** + * enum nl80211_band - Frequency band + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + */ +enum nl80211_band { + NL80211_BAND_2GHZ, + NL80211_BAND_5GHZ, +}; + +enum nl80211_ps_state { + NL80211_PS_DISABLED, + NL80211_PS_ENABLED, +}; + +/** + * enum nl80211_attr_cqm - connection quality monitor attributes + * @__NL80211_ATTR_CQM_INVALID: invalid + * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies + * the threshold for the RSSI level at which an event will be sent. Zero + * to disable. + * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies + * the minimum amount the RSSI level must change after an event before a + * new event may be issued (to reduce effects of RSSI oscillation). + * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event + * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many + * consecutive packets were not acknowledged by the peer + * @__NL80211_ATTR_CQM_AFTER_LAST: internal + * @NL80211_ATTR_CQM_MAX: highest key attribute + */ +enum nl80211_attr_cqm { + __NL80211_ATTR_CQM_INVALID, + NL80211_ATTR_CQM_RSSI_THOLD, + NL80211_ATTR_CQM_RSSI_HYST, + NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, + NL80211_ATTR_CQM_PKT_LOSS_EVENT, + + /* keep last */ + __NL80211_ATTR_CQM_AFTER_LAST, + NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1 +}; + +/** + * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event + * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the + * configured threshold + * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the + * configured threshold + */ +enum nl80211_cqm_rssi_threshold_event { + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, +}; + + +/** + * enum nl80211_tx_power_setting - TX power adjustment + * @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power + * @NL80211_TX_POWER_LIMITED: limit TX power by the mBm parameter + * @NL80211_TX_POWER_FIXED: fix TX power to the mBm parameter + */ +enum nl80211_tx_power_setting { + NL80211_TX_POWER_AUTOMATIC, + NL80211_TX_POWER_LIMITED, + NL80211_TX_POWER_FIXED, +}; + +#endif /* __LINUX_NL80211_H */ diff --git a/src/tuning/runtime.cpp b/src/tuning/runtime.cpp new file mode 100644 index 0000000..cb62533 --- /dev/null +++ b/src/tuning/runtime.cpp @@ -0,0 +1,202 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "tuning.h" +#include "tunable.h" +#include "unistd.h" +#include "runtime.h" +#include <string.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <unistd.h> +#include <sys/types.h> +#include <dirent.h> +#include <limits.h> + +#include "../lib.h" +#include "../devices/runtime_pm.h" + +runtime_tunable::runtime_tunable(const char *path, const char *bus, const char *dev, const char *port) : tunable("", 0.4, _("Good"), _("Bad"), _("Unknown")) +{ + ifstream file; + sprintf(runtime_path, "%s/power/control", path); + + + sprintf(desc, _("Runtime PM for %s device %s"), bus, dev); + if (!device_has_runtime_pm(path)) + sprintf(desc, _("%s device %s has no runtime power management"), bus, dev); + + if (strcmp(bus, "pci") == 0) { + char filename[PATH_MAX]; + uint16_t vendor = 0, device = 0; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/vendor", bus, dev); + + file.open(filename, ios::in); + if (file) { + file >> hex >> vendor; + file.close(); + } + + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/device", bus, dev); + file.open(filename, ios::in); + if (file) { + file >> hex >> device; + file.close(); + } + + if (vendor && device) { + if (!device_has_runtime_pm(path)) + sprintf(desc, _("PCI Device %s has no runtime power management"), pci_id_to_name(vendor, device, filename, 4095)); + else + sprintf(desc, _("Runtime PM for PCI Device %s"), pci_id_to_name(vendor, device, filename, 4095)); + } + + if (string(path).find("ata") != string::npos) + sprintf(desc, _("Runtime PM for port %s of PCI device: %s"), port, pci_id_to_name(vendor, device, filename, 4095)); + + if (string(path).find("block") != string::npos) + sprintf(desc, _("Runtime PM for disk %s"), port); + + } + snprintf(toggle_good, sizeof(toggle_good), "echo 'auto' > '%s';", runtime_path); + snprintf(toggle_bad, sizeof(toggle_bad), "echo 'on' > '%s';", runtime_path); +} + +int runtime_tunable::good_bad(void) +{ + string content; + + content = read_sysfs_string(runtime_path); + + if (strcmp(content.c_str(), "auto") == 0) + return TUNE_GOOD; + + return TUNE_BAD; +} + +void runtime_tunable::toggle(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + write_sysfs(runtime_path, "on"); + return; + } + + write_sysfs(runtime_path, "auto"); +} + +const char *runtime_tunable::toggle_script(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + return toggle_bad; + } + + return toggle_good; +} + + +void add_runtime_tunables(const char *bus) +{ + struct dirent *entry; + DIR *dir; + char filename[PATH_MAX], port[PATH_MAX]; + int max_ports = 32, count=0; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/", bus); + dir = opendir(filename); + if (!dir) + return; + while (1) { + class runtime_tunable *runtime, *runtime_ahci_port, *runtime_ahci_disk; + + entry = readdir(dir); + + if (!entry) + break; + if (entry->d_name[0] == '.') + continue; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/power/control", bus, entry->d_name); + + if (access(filename, R_OK) != 0) + continue; + + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s", bus, entry->d_name); + + runtime = new class runtime_tunable(filename, bus, entry->d_name, NULL); + + if (!device_has_runtime_pm(filename)) + all_untunables.push_back(runtime); + else + all_tunables.push_back(runtime); + + for (int i=0; i < max_ports; i++) { + snprintf(port, sizeof(port), "ata%d", i); + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/%s/power/control", bus, entry->d_name, port); + + if (access(filename, R_OK) != 0) + continue; + + snprintf(filename, sizeof(filename), "/sys/bus/%s/devices/%s/%s", bus, entry->d_name, port); + runtime_ahci_port = new class runtime_tunable(filename, bus, entry->d_name, port); + + if (!device_has_runtime_pm(filename)) + all_untunables.push_back(runtime_ahci_port); + else + all_tunables.push_back(runtime_ahci_port); + } + + for (char blk = 'a'; blk <= 'z'; blk++) + { + if (count != 0) + break; + + snprintf(filename, sizeof(filename), "/sys/block/sd%c/device/power/control", blk); + + if (access(filename, R_OK) != 0) + continue; + + snprintf(port, sizeof(port), "sd%c", blk); + snprintf(filename, sizeof(filename), "/sys/block/%s/device", port); + runtime_ahci_disk = new class runtime_tunable(filename, bus, entry->d_name, port); + if (!device_has_runtime_pm(filename)) + all_untunables.push_back(runtime_ahci_disk); + else + all_tunables.push_back(runtime_ahci_disk); + } + count = 1; + + } + closedir(dir); +} diff --git a/src/tuning/runtime.h b/src/tuning/runtime.h new file mode 100644 index 0000000..84a8ef5 --- /dev/null +++ b/src/tuning/runtime.h @@ -0,0 +1,50 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_RUNTIME_TUNE_H +#define _INCLUDE_GUARD_RUNTIME_TUNE_H + +#include <vector> +#include <limits.h> + +#include "tunable.h" +using namespace std; + +class runtime_tunable : public tunable { + char runtime_path[PATH_MAX]; +public: + runtime_tunable(const char *runtime_path, const char *bus, const char *dev, const char *port); + + virtual int good_bad(void); + + virtual void toggle(void); + + virtual const char *toggle_script(void); + +}; + +extern void add_runtime_tunables(const char *bus); + + +#endif diff --git a/src/tuning/tunable.cpp b/src/tuning/tunable.cpp new file mode 100644 index 0000000..827b913 --- /dev/null +++ b/src/tuning/tunable.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "tuning.h" +#include "tunable.h" +#include <string.h> +#include "../lib.h" + +vector<class tunable *> all_tunables; +vector<class tunable *> all_untunables; + + +tunable::tunable(const char *str, double _score, const char *good, const char *bad, const char *neutral) +{ + score = _score; + pt_strcpy(desc, str); + pt_strcpy(good_string, good); + pt_strcpy(bad_string, bad); + pt_strcpy(neutral_string, neutral); +} + + +tunable::tunable(void) +{ + score = 0; + desc[0] = 0; + pt_strcpy(good_string, _("Good")); + pt_strcpy(bad_string, _("Bad")); + pt_strcpy(neutral_string, _("Unknown")); +} diff --git a/src/tuning/tunable.h b/src/tuning/tunable.h new file mode 100644 index 0000000..3372378 --- /dev/null +++ b/src/tuning/tunable.h @@ -0,0 +1,81 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_TUNABLE_H +#define _INCLUDE_GUARD_TUNABLE_H + +#include <vector> + +#include "../lib.h" + +using namespace std; + +#define TUNE_GOOD 1 +#define TUNE_BAD -1 +#define TUNE_UNFIXABLE -2 +#define TUNE_UNKNOWN 0 +#define TUNE_NEUTRAL 0 + +class tunable { + + char good_string[128]; + char bad_string[128]; + char neutral_string[128]; +protected: + char toggle_good[4096]; + char toggle_bad[4096]; +public: + char desc[4096]; + double score; + + tunable(void); + tunable(const char *str, double _score, const char *good = "", const char *bad = "", const char *neutral =""); + virtual ~tunable() {}; + + virtual int good_bad(void) { return TUNE_NEUTRAL; } + + virtual char *result_string(void) + { + switch (good_bad()) { + case TUNE_GOOD: + return good_string; + case TUNE_BAD: + case TUNE_UNFIXABLE: + return bad_string; + } + return neutral_string; + } + + + virtual const char *description(void) { return desc; }; + + virtual void toggle(void) { }; + + virtual const char *toggle_script(void) { return NULL; } +}; + +extern vector<class tunable *> all_tunables; +extern vector<class tunable *> all_untunables; + +#endif diff --git a/src/tuning/tuning.cpp b/src/tuning/tuning.cpp new file mode 100644 index 0000000..bc34741 --- /dev/null +++ b/src/tuning/tuning.cpp @@ -0,0 +1,332 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include <algorithm> + +#include <stdio.h> +#include <string.h> +#include <ncurses.h> + + +#include "tuning.h" +#include "tuningi2c.h" +#include "tuningsysfs.h" +#include "tuningusb.h" +#include "runtime.h" +#include "bluetooth.h" +#include "ethernet.h" +#include "wifi.h" +#include "../display.h" +#include "../report/report.h" +#include "../report/report-maker.h" +#include "../report/report-data-html.h" +#include "../lib.h" + +static void sort_tunables(void); +static bool should_clear = false; + +class tuning_window *tune_window; + +class tuning_window: public tab_window { +public: + virtual void repaint(void); + virtual void cursor_enter(void); + virtual void expose(void); + virtual void window_refresh(void); +}; + +static void init_tuning(void) +{ + add_sysfs_tunable(_("Enable Audio codec power management"), "/sys/module/snd_hda_intel/parameters/power_save", "1"); + add_sysfs_tunable(_("NMI watchdog should be turned off"), "/proc/sys/kernel/nmi_watchdog", "0"); + add_sysfs_tunable(_("Power Aware CPU scheduler"), "/sys/devices/system/cpu/sched_mc_power_savings", "1"); + add_sysfs_tunable(_("VM writeback timeout"), "/proc/sys/vm/dirty_writeback_centisecs", "1500"); + add_sata_tunables(); + add_usb_tunables(); + add_runtime_tunables("pci"); + add_bt_tunable(); + add_wifi_tunables(); + add_i2c_tunables(); + + sort_tunables(); +} + +void initialize_tuning(void) +{ + class tuning_window *w; + + w = new tuning_window(); + create_tab("Tunables", _("Tunables"), w, _(" <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh")); + + init_tuning(); + + w->cursor_max = all_tunables.size() - 1; + + if (tune_window) + delete tune_window; + + tune_window = w; +} + + + +static void __tuning_update_display(int cursor_pos) +{ + WINDOW *win; + unsigned int i; + + win = get_ncurses_win("Tunables"); + + if (!win) + return; + + if (should_clear) { + should_clear = false; + wclear(win); + } + + wmove(win, 2,0); + + for (i = 0; i < all_tunables.size(); i++) { + char res[128]; + char desc[4096]; + pt_strcpy(res, all_tunables[i]->result_string()); + pt_strcpy(desc, all_tunables[i]->description()); + while (strlen(res) < 12) + strcat(res, " "); + + while (strlen(desc) < 103) + strcat(desc, " "); + if ((int)i != cursor_pos) { + wattrset(win, A_NORMAL); + wprintw(win, " "); + } else { + wattrset(win, A_REVERSE); + wprintw(win, ">> "); + } + wprintw(win, "%s %s\n", _(res), _(desc)); + } +} + +void tuning_update_display(void) +{ + class tab_window *w; + + w = tab_windows["Tunables"]; + if (!w) + return; + w->repaint(); +} + +void tuning_window::repaint(void) +{ + __tuning_update_display(cursor_pos); +} + +void tuning_window::cursor_enter(void) +{ + class tunable *tun; + const char *toggle_script; + tun = all_tunables[cursor_pos]; + if (!tun) + return; + /** device will change its state so need to store toggle script before + * we toggle()*/ + toggle_script = tun->toggle_script(); + tun->toggle(); + ui_notify_user(">> %s\n", toggle_script); +} + +static bool tunables_sort(class tunable * i, class tunable * j) +{ + int i_g, j_g; + double d; + + i_g = i->good_bad(); + j_g = j->good_bad(); + + if (!equals(i_g, j_g)) + return i_g < j_g; + + d = i->score - j->score; + if (d < 0.0) + d = -d; + if (d > 0.0001) + return i->score > j->score; + + if (strcasecmp(i->description(), j->description()) == -1) + return true; + + return false; +} + +void tuning_window::window_refresh() +{ + clear_tuning(); + should_clear = true; + init_tuning(); +} + +static void sort_tunables(void) +{ + sort(all_tunables.begin(), all_tunables.end(), tunables_sort); +} + +void tuning_window::expose(void) +{ + cursor_pos = 0; + sort_tunables(); + repaint(); +} + +void report_show_tunables(void) +{ + unsigned int i; + /* three tables; bad, unfixable, good */ + sort_tunables(); + int idx, rows = 0, cols; + + /* First Table */ + + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "clear_block", "tuning"); + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Set Table attributes, rows, and cols */ + table_attributes tune_table_css; + cols=2; + idx = cols; + + for (i = 0; i < all_tunables.size(); i++) { + int tgb; + tgb = all_tunables[i]->good_bad(); + if (tgb == TUNE_BAD) + rows+=1; + } + /* add section */ + report.add_div(&div_attr); + + if (rows > 0){ + rows= rows + 1; + init_tune_table_attr(&tune_table_css, rows, cols); + + /* Set array of data in row Major order */ + string *tunable_data = new string[cols * rows]; + + tunable_data[0]=__("Description"); + tunable_data[1]=__("Script"); + + for (i = 0; i < all_tunables.size(); i++) { + int gb; + gb = all_tunables[i]->good_bad(); + if (gb != TUNE_BAD) + continue; + tunable_data[idx]=string(all_tunables[i]->description()); + idx+=1; + tunable_data[idx]=string(all_tunables[i]->toggle_script()); + idx+=1; + } + + /* Report Output */ + report.add_title(&title_attr,__("Software Settings in Need of Tuning")); + report.add_table(tunable_data, &tune_table_css); + delete [] tunable_data; + } + + /* Second Table */ + /* Set Table attributes, rows, and cols */ + cols=1; + rows= all_untunables.size() + 1; + init_tune_table_attr(&tune_table_css, rows, cols); + + /* Set array of data in row Major order */ + string *untunable_data = new string[rows]; + untunable_data[0]=__("Description"); + + for (i = 0; i < all_untunables.size(); i++) + untunable_data[i+1]= string(all_untunables[i]->description()); + + /* Report Output */ + report.add_title(&title_attr,__("Untunable Software Issues")); + report.add_table(untunable_data, &tune_table_css); + delete [] untunable_data; + + /* Third Table */ + /* Set Table attributes, rows, and cols */ + rows = 1; + for (i = 0; i < all_tunables.size(); i++) { + int gb; + gb = all_tunables[i]->good_bad(); + if (gb != TUNE_GOOD) + continue; + rows+=1; + } + cols = 1; + init_tune_table_attr(&tune_table_css, rows, cols); + + /* Set array of data in row Major order */ + string *tuned_data = new string[rows]; + tuned_data[0]=__("Description"); + idx=cols; + for (i = 0; i < all_tunables.size(); i++) { + int gb; + gb = all_tunables[i]->good_bad(); + if (gb != TUNE_GOOD) + continue; + + tuned_data[idx]=string(all_tunables[i]->description()); + idx+=1; + } + /* Report Output */ + report.add_title(&title_attr,__("Optimal Tuned Software Settings")); + report.add_table(tuned_data, &tune_table_css); + report.end_div(); + delete [] tuned_data; +} + +void clear_tuning() +{ + for (size_t i = 0; i < all_tunables.size(); i++) { + delete all_tunables[i]; + } + all_tunables.clear(); + + for (size_t i = 0; i < all_untunables.size(); i++) { + delete all_untunables[i]; + } + all_untunables.clear(); +} + +void auto_toggle_tuning() +{ + for (unsigned int i = 0; i < all_tunables.size(); i++) { + if (all_tunables[i]->good_bad() == TUNE_BAD) + all_tunables[i]->toggle(); + } +} diff --git a/src/tuning/tuning.h b/src/tuning/tuning.h new file mode 100644 index 0000000..f70001b --- /dev/null +++ b/src/tuning/tuning.h @@ -0,0 +1,33 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_TUNING_H +#define _INCLUDE_GUARD_TUNING_H + +extern void initialize_tuning(void); +extern void tuning_update_display(void); +extern void report_show_tunables(void); +extern void clear_tuning(void); +extern void auto_toggle_tuning(void); +#endif diff --git a/src/tuning/tuningi2c.cpp b/src/tuning/tuningi2c.cpp new file mode 100644 index 0000000..b75e811 --- /dev/null +++ b/src/tuning/tuningi2c.cpp @@ -0,0 +1,129 @@ +/* + * Copyright 2015, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + * Daniel Leung <daniel.leung@linux.intel.com> + */ + +#include "tuning.h" +#include "tunable.h" +#include "unistd.h" +#include "tuningi2c.h" +#include <string.h> +#include <dirent.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <ctype.h> +#include <limits.h> + +#include "../lib.h" +#include "../devices/runtime_pm.h" + +i2c_tunable::i2c_tunable(const char *path, const char *name, bool is_adapter) : tunable("", 0.9, _("Good"), _("Bad"), _("Unknown")) +{ + ifstream file; + char filename[PATH_MAX]; + string devname; + + snprintf(filename, sizeof(filename), "%s/name", path); + file.open(filename, ios::in); + if (file) { + getline(file, devname); + file.close(); + } + + if (is_adapter) { + snprintf(i2c_path, sizeof(i2c_path), "%s/device/power/control", path); + snprintf(filename, sizeof(filename), "%s/device", path); + } else { + snprintf(i2c_path, sizeof(i2c_path), "%s/power/control", path); + snprintf(filename, sizeof(filename), "%s/device", path); + } + + if (device_has_runtime_pm(filename)) + snprintf(desc, sizeof(desc), _("Runtime PM for I2C %s %s (%s)"), (is_adapter ? _("Adapter") : _("Device")), name, (devname.empty() ? "" : devname.c_str())); + else + snprintf(desc, sizeof(desc), _("I2C %s %s has no runtime power management"), (is_adapter ? _("Adapter") : _("Device")), name); + + snprintf(toggle_good, sizeof(toggle_good), "echo 'auto' > '%s';", i2c_path); + snprintf(toggle_bad, sizeof(toggle_bad), "echo 'on' > '%s';", i2c_path); +} + +int i2c_tunable::good_bad(void) +{ + string content; + + content = read_sysfs_string(i2c_path); + + if (strcmp(content.c_str(), "auto") == 0) + return TUNE_GOOD; + + return TUNE_BAD; +} + +void i2c_tunable::toggle(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + write_sysfs(i2c_path, "on"); + return; + } + + write_sysfs(i2c_path, "auto"); +} + +const char *i2c_tunable::toggle_script(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + return toggle_bad; + } + + return toggle_good; +} + +static void add_i2c_callback(const char *d_name) +{ + class i2c_tunable *i2c; + char filename[PATH_MAX]; + bool is_adapter = false; + + snprintf(filename, PATH_MAX, "/sys/bus/i2c/devices/%s/new_device", d_name); + if (access(filename, W_OK) == 0) + is_adapter = true; + + snprintf(filename, PATH_MAX, "/sys/bus/i2c/devices/%s", d_name); + i2c = new class i2c_tunable(filename, d_name, is_adapter); + + if (is_adapter) + snprintf(filename, PATH_MAX, "/sys/bus/i2c/devices/%s/device", d_name); + else + snprintf(filename, PATH_MAX, "/sys/bus/i2c/devices/%s", d_name); + + if (device_has_runtime_pm(filename)) + all_tunables.push_back(i2c); + else + all_untunables.push_back(i2c); +} + +void add_i2c_tunables(void) +{ + process_directory("/sys/bus/i2c/devices/", add_i2c_callback); +} diff --git a/src/tuning/tuningi2c.h b/src/tuning/tuningi2c.h new file mode 100644 index 0000000..8fd8784 --- /dev/null +++ b/src/tuning/tuningi2c.h @@ -0,0 +1,46 @@ +/* + * Copyright 2015, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + * Daniel Leung <daniel.leung@linux.intel.com> + */ + +#ifndef _INCLUDE_GUARD_I2C_TUNE_H +#define _INCLUDE_GUARD_I2C_TUNE_H + +#include <vector> +#include <limits.h> + +#include "tunable.h" + +using namespace std; + +class i2c_tunable : public tunable { + char i2c_path[PATH_MAX]; +public: + i2c_tunable(const char *path, const char *name, bool is_adapter); + + virtual int good_bad(void); + + virtual void toggle(void); + + virtual const char *toggle_script(void); + +}; + +extern void add_i2c_tunables(void); + + +#endif diff --git a/src/tuning/tuningsysfs.cpp b/src/tuning/tuningsysfs.cpp new file mode 100644 index 0000000..631e9fd --- /dev/null +++ b/src/tuning/tuningsysfs.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "tuning.h" +#include "tunable.h" +#include "unistd.h" +#include "tuningsysfs.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <unistd.h> +#include <sys/types.h> +#include <dirent.h> +#include <limits.h> + + +#include "../lib.h" + +sysfs_tunable::sysfs_tunable(const char *str, const char *_sysfs_path, const char *_target_content) : tunable(str, 1.0, _("Good"), _("Bad"), _("Unknown")) +{ + pt_strcpy(sysfs_path, _sysfs_path); + pt_strcpy(target_value, _target_content); + bad_value[0] = 0; + snprintf(toggle_good, sizeof(toggle_good), "echo '%s' > '%s';", target_value, sysfs_path); + snprintf(toggle_bad, sizeof(toggle_bad), "echo '%s' > '%s';", bad_value, sysfs_path); +} + +int sysfs_tunable::good_bad(void) +{ + char current_value[4096], *c; + ifstream file; + + file.open(sysfs_path, ios::in); + if (!file) + return TUNE_NEUTRAL; + file.getline(current_value, 4096); + file.close(); + + c = strchr(current_value, '\n'); + if (c) + *c = 0; + + if (strcmp(current_value, target_value) == 0) + return TUNE_GOOD; + + pt_strcpy(bad_value, current_value); + return TUNE_BAD; +} + +void sysfs_tunable::toggle(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + if (strlen(bad_value) > 0) + write_sysfs(sysfs_path, bad_value); + return; + } + + write_sysfs(sysfs_path, target_value); +} + +const char *sysfs_tunable::toggle_script(void) { + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + if (strlen(bad_value) > 0) + return toggle_bad; + return NULL; + } + + return toggle_good; +} + + +void add_sysfs_tunable(const char *str, const char *_sysfs_path, const char *_target_content) +{ + class sysfs_tunable *tunable; + + if (access(_sysfs_path, R_OK) != 0) + return; + + tunable = new class sysfs_tunable(str, _sysfs_path, _target_content); + + + all_tunables.push_back(tunable); +} + +static void add_sata_tunables_callback(const char *d_name) +{ + char filename[PATH_MAX]; + char msg[4096]; + + snprintf(filename, sizeof(filename), "/sys/class/scsi_host/%s/link_power_management_policy", d_name); + snprintf(msg, sizeof(msg), _("Enable SATA link power management for %s"), d_name); + add_sysfs_tunable(msg, filename, "med_power_with_dipm"); +} + +void add_sata_tunables(void) +{ + process_directory("/sys/class/scsi_host", add_sata_tunables_callback); +} diff --git a/src/tuning/tuningsysfs.h b/src/tuning/tuningsysfs.h new file mode 100644 index 0000000..57b9de7 --- /dev/null +++ b/src/tuning/tuningsysfs.h @@ -0,0 +1,53 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_SYSFS_TUNE_H +#define _INCLUDE_GUARD_SYSFS_TUNE_H + +#include <vector> +#include <limits.h> + +#include "tunable.h" + +using namespace std; + +class sysfs_tunable : public tunable { + char sysfs_path[PATH_MAX]; + char target_value[4096]; + char bad_value[4096]; +public: + sysfs_tunable(const char *str, const char *sysfs_path, const char *target_content); + + virtual int good_bad(void); + + virtual void toggle(void); + + virtual const char *toggle_script(void); + +}; + +extern void add_sysfs_tunable(const char *str, const char *_sysfs_path, const char *_target_content); +extern void add_sata_tunables(void); + +#endif diff --git a/src/tuning/tuningusb.cpp b/src/tuning/tuningusb.cpp new file mode 100644 index 0000000..3b7b2b1 --- /dev/null +++ b/src/tuning/tuningusb.cpp @@ -0,0 +1,157 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "tuning.h" +#include "tunable.h" +#include "unistd.h" +#include "tuningusb.h" +#include <string.h> +#include <dirent.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <limits.h> + +#include "../lib.h" + +usb_tunable::usb_tunable(const char *path, const char *name) : tunable("", 0.9, _("Good"), _("Bad"), _("Unknown")) +{ + ifstream file; + char filename[PATH_MAX]; + char vendor[2048]; + char product[2048]; + string str1, str2; + snprintf(usb_path, sizeof(usb_path), "%s/power/control", path); + + vendor[0] = 0; + product[0] = 0; + + str1 = read_sysfs_string("%s/idVendor", path); + str2 = read_sysfs_string("%s/idProduct", path); + + snprintf(desc, sizeof(desc), _("Autosuspend for unknown USB device %s (%s:%s)"), name, str1.c_str(), str2.c_str()); + + snprintf(filename, sizeof(filename), "%s/manufacturer", path); + file.open(filename, ios::in); + if (file) { + file.getline(vendor, 2047); + if (strstr(vendor, "Linux ")) + vendor[0] = 0; + file.close(); + }; + snprintf(filename, sizeof(filename), "%s/product", path); + file.open(filename, ios::in); + if (file) { + file.getline(product, 2040); + file.close(); + }; + if (strlen(vendor) && strlen(product)) + snprintf(desc, sizeof(desc), _("Autosuspend for USB device %s [%s]"), product, vendor); + else if (strlen(product)) + snprintf(desc, sizeof(desc), _("Autosuspend for USB device %s [%s]"), product, name); + else if (strlen(vendor)) + snprintf(desc, sizeof(desc), _("Autosuspend for USB device %s [%s]"), vendor, name); + + snprintf(toggle_good, sizeof(toggle_good), "echo 'auto' > '%s';", usb_path); + snprintf(toggle_bad, sizeof(toggle_bad), "echo 'on' > '%s';", usb_path); +} + +int usb_tunable::good_bad(void) +{ + string content; + + content = read_sysfs_string(usb_path); + + if (strcmp(content.c_str(), "auto") == 0) + return TUNE_GOOD; + + return TUNE_BAD; +} + +void usb_tunable::toggle(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + write_sysfs(usb_path, "on"); + return; + } + + write_sysfs(usb_path, "auto"); +} + +const char *usb_tunable::toggle_script(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + return toggle_bad; + } + + return toggle_good; +} + +static void add_usb_callback(const char *d_name) +{ + class usb_tunable *usb; + char filename[PATH_MAX]; + DIR *dir; + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s/power/control", d_name); + if (access(filename, R_OK) != 0) + return; + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s/power/active_duration", d_name); + if (access(filename, R_OK)!=0) + return; + + /* every interface of this device should support autosuspend */ + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s", d_name); + if ((dir = opendir(filename))) { + struct dirent *entry; + while ((entry = readdir(dir))) { + /* dirname: <busnum>-<devnum>...:<config num>-<interface num> */ + if (!isdigit(entry->d_name[0])) + continue; + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s/%s/supports_autosuspend", d_name, entry->d_name); + if (access(filename, R_OK) == 0 && read_sysfs(filename) == 0) + break; + } + closedir(dir); + if (entry) + return; + } + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s", d_name); + usb = new class usb_tunable(filename, d_name); + all_tunables.push_back(usb); +} + +void add_usb_tunables(void) +{ + process_directory("/sys/bus/usb/devices/", add_usb_callback); +} diff --git a/src/tuning/tuningusb.h b/src/tuning/tuningusb.h new file mode 100644 index 0000000..4e27e3a --- /dev/null +++ b/src/tuning/tuningusb.h @@ -0,0 +1,51 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_USB_TUNE_H +#define _INCLUDE_GUARD_USB_TUNE_H + +#include <vector> +#include <limits.h> + +#include "tunable.h" + +using namespace std; + +class usb_tunable : public tunable { + char usb_path[PATH_MAX]; +public: + usb_tunable(const char *usb_path, const char *path); + + virtual int good_bad(void); + + virtual void toggle(void); + + virtual const char *toggle_script(void); + +}; + +extern void add_usb_tunables(void); + + +#endif diff --git a/src/tuning/wifi.cpp b/src/tuning/wifi.cpp new file mode 100644 index 0000000..f7a91ec --- /dev/null +++ b/src/tuning/wifi.cpp @@ -0,0 +1,112 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ + +#include "tuning.h" +#include "tunable.h" +#include "unistd.h" +#include "wifi.h" +#include <string.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <unistd.h> +#include <sys/types.h> +#include <dirent.h> + +#include "../lib.h" + +extern "C" { +#include "iw.h" +} + + +wifi_tunable::wifi_tunable(const char *_iface) : tunable("", 1.5, _("Good"), _("Bad"), _("Unknown")) +{ + pt_strcpy(iface, _iface); + sprintf(desc, _("Wireless Power Saving for interface %s"), iface); + + snprintf(toggle_good, sizeof(toggle_good), "iw dev %s set power_save on", iface); + snprintf(toggle_bad, sizeof(toggle_bad), "iw dev %s set power_save off", iface); +} + +int wifi_tunable::good_bad(void) +{ + if (get_wifi_power_saving(iface)) + return TUNE_GOOD; + + return TUNE_BAD; +} + +void wifi_tunable::toggle(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + set_wifi_power_saving(iface, 0); + return; + } + + set_wifi_power_saving(iface, 1); +} + +const char *wifi_tunable::toggle_script(void) +{ + int good; + good = good_bad(); + + if (good == TUNE_GOOD) { + return toggle_bad; + } + + return toggle_good; +} + +void add_wifi_tunables(void) +{ + struct dirent *entry; + DIR *dir; + char* wlan_name; + class wifi_tunable *wifi; + + + dir = opendir("/sys/class/net/"); + if (!dir) + return; + while (1) { + entry = readdir(dir); + if (!entry) + break; + wlan_name = strstr(entry->d_name, "wlan"); + if (wlan_name) { + wifi = new class wifi_tunable(wlan_name); + all_tunables.push_back(wifi); + } + + } + + closedir(dir); + +} diff --git a/src/tuning/wifi.h b/src/tuning/wifi.h new file mode 100644 index 0000000..50ca68c --- /dev/null +++ b/src/tuning/wifi.h @@ -0,0 +1,50 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef _INCLUDE_GUARD_WIFI_TUNE_H +#define _INCLUDE_GUARD_WIFI_TUNE_H + +#include <vector> + +#include "tunable.h" + +using namespace std; + +class wifi_tunable : public tunable { + char iface[4096]; +public: + wifi_tunable(const char *_iface); + + virtual int good_bad(void); + + virtual void toggle(void); + + virtual const char *toggle_script(void); + +}; + +extern void add_wifi_tunables(void); + + +#endif diff --git a/src/wakeup/waketab.cpp b/src/wakeup/waketab.cpp new file mode 100644 index 0000000..77d7567 --- /dev/null +++ b/src/wakeup/waketab.cpp @@ -0,0 +1,195 @@ +#include <algorithm> +#include <stdio.h> +#include <string.h> +#include <ncurses.h> +#include "wakeup.h" +#include <vector> +#include "../lib.h" +#include "../measurement/sysfs.h" +#include "../display.h" +#include "../report/report.h" +#include "../report/report-maker.h" +#include "../report/report-data-html.h" +#include "wakeup_ethernet.h" +#include "wakeup_usb.h" + +using namespace std; + +static bool should_clear = false; + +class wakeup_window *newtab_window; + +class wakeup_window: public tab_window { +public: + virtual void repaint(void); + virtual void cursor_enter(void); + virtual void expose(void); + virtual void window_refresh(void); +}; + +static void init_wakeup(void) +{ + add_ethernet_wakeup(); + add_usb_wakeup(); +} + +void initialize_wakeup(void) +{ + class wakeup_window *win; + + win = new wakeup_window(); + + create_tab("WakeUp", _("WakeUp"), win, _(" <ESC> Exit | <Enter> Toggle wakeup | <r> Window refresh")); + + init_wakeup(); + + win->cursor_max = wakeup_all.size() - 1; + + if (newtab_window) + delete newtab_window; + + newtab_window = win; +} + +static void __wakeup_update_display(int cursor_pos) +{ + WINDOW *win; + unsigned int i; + + win = get_ncurses_win("WakeUp"); + + if (!win) + return; + + if (should_clear) { + should_clear = false; + wclear(win); + } + + wmove(win, 1,0); + + for (i = 0; i < wakeup_all.size(); i++) { + char res[128]; + char desc[4096]; + pt_strcpy(res, wakeup_all[i]->wakeup_string()); + pt_strcpy(desc, wakeup_all[i]->description()); + while (strlen(res) < 12) + strcat(res, " "); + + while (strlen(desc) < 103) + strcat(desc, " "); + + if ((int)i != cursor_pos) { + wattrset(win, A_NORMAL); + wprintw(win, " "); + } else { + wattrset(win, A_REVERSE); + wprintw(win, ">> "); + } + wprintw(win, "%s %s\n", _(res), _(desc)); + } +} + +void wakeup_update_display(void) +{ + class tab_window *wt; + + wt = tab_windows["WakeUp"]; + if (!wt) + return; + wt->repaint(); +} + +void wakeup_window::repaint(void) +{ + __wakeup_update_display(cursor_pos); +} + +void wakeup_window::cursor_enter(void) +{ + class wakeup *wake; + const char *wakeup_toggle_script; + wake = wakeup_all[cursor_pos]; + if (!wake) + return; + wakeup_toggle_script = wake->wakeup_toggle_script(); + wake->wakeup_toggle(); + ui_notify_user(">> %s\n", wakeup_toggle_script); +} + +void report_show_wakeup(void) +{ + unsigned int i; + int idx, rows = 0, cols; + + /* div attr css_class and css_id */ + tag_attr div_attr; + init_div(&div_attr, "clear_block", "wakeup"); + + /* Set Title attributes */ + tag_attr title_attr; + init_title_attr(&title_attr); + + /* Set Table attributes, rows, and cols */ + table_attributes wakeup_table_css; + cols=2; + idx = cols; + + for (i = 0; i < wakeup_all.size(); i++) { + int tgb; + tgb = wakeup_all[i]->wakeup_value(); + if (tgb == WAKEUP_DISABLE) + rows+=1; + } + + /* add section */ + + report.add_div(&div_attr); + if (rows > 0){ + rows= rows + 1; + init_wakeup_table_attr(&wakeup_table_css, rows, cols); + + /* Set array of data in row Major order */ + string *wakeup_data = new string[cols * rows]; + + wakeup_data[0]=__("Description"); + wakeup_data[1]=__("Script"); + + for (i = 0; i < wakeup_all.size(); i++) { + int gb; + gb = wakeup_all[i]->wakeup_value(); + if (gb != WAKEUP_DISABLE) + continue; + wakeup_data[idx]=string(wakeup_all[i]->description()); + idx+=1; + wakeup_data[idx]=string(wakeup_all[i]->wakeup_toggle_script()); + idx+=1; + } + + /* Report Output */ + report.add_title(&title_attr,__("Wake status of the devices")); + report.add_table(wakeup_data, &wakeup_table_css); + delete [] wakeup_data; + } +} + +void wakeup_window::expose(void) +{ + cursor_pos = 0; + repaint(); +} + +void wakeup_window::window_refresh(void) +{ + clear_wakeup(); + should_clear = true; + init_wakeup(); +} + +void clear_wakeup() +{ + for (size_t i = 0; i < wakeup_all.size(); i++) { + delete wakeup_all[i]; + } + wakeup_all.clear(); +} diff --git a/src/wakeup/wakeup.cpp b/src/wakeup/wakeup.cpp new file mode 100644 index 0000000..9d83a9a --- /dev/null +++ b/src/wakeup/wakeup.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2018, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Gayatri Kammela <gayatri.kammela@intel.com> + */ + +#include <string.h> +#include <ncurses.h> +#include "wakeup.h" +#include <vector> +#include "../lib.h" + +using namespace std; + +vector<class wakeup *> wakeup_all; + +wakeup::wakeup(const char *str, double _score, const char *enable, const char *disable) +{ + score = _score; + pt_strcpy(desc, str); + pt_strcpy(wakeup_enable, enable); + pt_strcpy(wakeup_disable, disable); +} + +wakeup::wakeup(void) +{ + score = 0; + desc[0] = 0; + pt_strcpy(wakeup_enable, _("Enabled")); + pt_strcpy(wakeup_disable, _("Disabled")); + pt_strcpy(wakeup_idle, _("Unknown")); +} + diff --git a/src/wakeup/wakeup.h b/src/wakeup/wakeup.h new file mode 100644 index 0000000..13f99a3 --- /dev/null +++ b/src/wakeup/wakeup.h @@ -0,0 +1,81 @@ +/* + * Copyright 2018, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Gayatri Kammela <gayatri.kammela@intel.com> + */ +#ifndef _INCLUDE_GUARD_WAKEUP_H +#define _INCLUDE_GUARD_WAKEUP_H + +#include<vector> +#include <limits.h> + +using namespace std; + +#define WAKEUP_ENABLE 1 +#define WAKEUP_DISABLE 0 + +class wakeup { + char wakeup_enable[128]; + char wakeup_disable[128]; + char wakeup_idle[128]; +protected: + char toggle_enable[4096]; + char toggle_disable[4096]; +public: + char desc[4096]; + double score; + + wakeup(const char *str, double _score, const char *enable = "", const char *disable = ""); + wakeup(void); + + virtual ~wakeup () {}; + + virtual int wakeup_value(void) { return WAKEUP_DISABLE; } + + virtual char *wakeup_string(void) + { + switch (wakeup_value()) { + case WAKEUP_ENABLE: + return wakeup_enable; + case WAKEUP_DISABLE: + return wakeup_disable; + } + return wakeup_idle; + } + + + virtual const char *description(void) { return desc; }; + + virtual void wakeup_toggle(void) { }; + + virtual const char *wakeup_toggle_script(void) { return toggle_enable; } + +}; + +extern vector<class wakeup *> wakeup_all; + +extern void initialize_wakeup(void); +extern void wakeup_update_display(void); +extern void report_show_wakeup(void); +extern void clear_wakeup(void); + +#endif diff --git a/src/wakeup/wakeup_ethernet.cpp b/src/wakeup/wakeup_ethernet.cpp new file mode 100644 index 0000000..6ce1725 --- /dev/null +++ b/src/wakeup/wakeup_ethernet.cpp @@ -0,0 +1,111 @@ +;/* + * Copyright 2018, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Gayatri Kammela <gayatri.kammela@intel.com> + */ + +#include "wakeup.h" +#include <sys/types.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <sys/socket.h> +#include <errno.h> +#include <linux/types.h> +#include <net/if.h> +#include <linux/sockios.h> +#include <sys/ioctl.h> + +#include <linux/ethtool.h> + +#include "../lib.h" +#include "wakeup_ethernet.h" + +ethernet_wakeup::ethernet_wakeup(const char *path, const char *iface) : wakeup("", 0.5, _("Enabled"), _("Disabled")) +{ + memset(interf, 0, sizeof(interf)); + pt_strcpy(interf, iface); + sprintf(desc, _("Wake-on-lan status for device %s"), iface); + snprintf(eth_path, sizeof(eth_path), "/sys/class/net/%s/device/power/wakeup", iface); + snprintf(toggle_enable, sizeof(toggle_enable), "echo 'enabled' > '%s';", eth_path); + snprintf(toggle_disable, sizeof(toggle_disable), "echo 'disabled' > '%s';", eth_path); +} + +int ethernet_wakeup::wakeup_value(void) +{ + string content; + + content = read_sysfs_string(eth_path); + + if (strcmp(content.c_str(), "enabled") == 0) + return WAKEUP_ENABLE; + + return WAKEUP_DISABLE; +} + +void ethernet_wakeup::wakeup_toggle(void) +{ + int enable; + enable = wakeup_value(); + + if (enable == WAKEUP_ENABLE) { + write_sysfs(eth_path, "disabled"); + return; + } + + write_sysfs(eth_path, "enabled"); +} + +const char *ethernet_wakeup::wakeup_toggle_script(void) +{ + int enable; + enable = wakeup_value(); + + if (enable == WAKEUP_ENABLE) { + return toggle_disable; + } + + return toggle_enable; +} + +void wakeup_eth_callback(const char *d_name) +{ + class ethernet_wakeup *eth; + char filename[PATH_MAX]; + + snprintf(filename, sizeof(filename), "/sys/class/net/%s/device/power/wakeup", d_name); + if (access(filename, R_OK) != 0) + return; + + snprintf(filename, sizeof(filename), "/sys/class/net/%s/device/power/wakeup", d_name); + eth = new class ethernet_wakeup(filename, d_name); + wakeup_all.push_back(eth); +} + +void add_ethernet_wakeup(void) +{ + process_directory("/sys/class/net/", wakeup_eth_callback); +} diff --git a/src/wakeup/wakeup_ethernet.h b/src/wakeup/wakeup_ethernet.h new file mode 100644 index 0000000..682bf95 --- /dev/null +++ b/src/wakeup/wakeup_ethernet.h @@ -0,0 +1,50 @@ +/* + * Copyright 2018, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Gayatri Kammela <gayatri.kammela@intel.com> + */ +#ifndef _INCLUDE_GUARD_ETHERNET_WAKEUP_H +#define _INCLUDE_GUARD_ETHERNET_WAKEUP_H + +#include <vector> + +#include "wakeup.h" + +using namespace std; + +class ethernet_wakeup : public wakeup { + char eth_path[PATH_MAX]; +public: + char interf[4096]; + ethernet_wakeup(const char *eth_path, const char *iface); + + virtual int wakeup_value(void); + + virtual void wakeup_toggle(void); + + virtual const char *wakeup_toggle_script(void); + +}; + +extern void add_ethernet_wakeup(void); + +#endif diff --git a/src/wakeup/wakeup_usb.cpp b/src/wakeup/wakeup_usb.cpp new file mode 100644 index 0000000..e0e4567 --- /dev/null +++ b/src/wakeup/wakeup_usb.cpp @@ -0,0 +1,111 @@ +;/* + * Copyright 2018, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Gayatri Kammela <gayatri.kammela@intel.com> + */ + +#include "wakeup.h" +#include <sys/types.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utility> +#include <iostream> +#include <fstream> +#include <sys/socket.h> +#include <errno.h> +#include <linux/types.h> +#include <net/if.h> +#include <linux/sockios.h> +#include <sys/ioctl.h> + +#include <linux/ethtool.h> + +#include "../lib.h" +#include "wakeup_usb.h" + +usb_wakeup::usb_wakeup(const char *path, const char *iface) : wakeup("", 0.5, _("Enabled"), _("Disabled")) +{ + memset(interf, 0, sizeof(interf)); + pt_strcpy(interf, iface); + sprintf(desc, _("Wake status for USB device %s"), iface); + snprintf(usb_path, sizeof(usb_path), "/sys/bus/usb/devices/%s/power/wakeup", iface); + snprintf(toggle_enable, sizeof(toggle_enable), "echo 'enabled' > '%s';", usb_path); + snprintf(toggle_disable, sizeof(toggle_disable), "echo 'disabled' > '%s';", usb_path); +} + +int usb_wakeup::wakeup_value(void) +{ + string content; + + content = read_sysfs_string(usb_path); + + if (strcmp(content.c_str(), "enabled") == 0) + return WAKEUP_ENABLE; + + return WAKEUP_DISABLE; +} + +void usb_wakeup::wakeup_toggle(void) +{ + int enable; + enable = wakeup_value(); + + if (enable == WAKEUP_ENABLE) { + write_sysfs(usb_path, "disabled"); + return; + } + + write_sysfs(usb_path, "enabled"); +} + +const char *usb_wakeup::wakeup_toggle_script(void) +{ + int enable; + enable = wakeup_value(); + + if (enable == WAKEUP_ENABLE) { + return toggle_disable; + } + + return toggle_enable; +} + +void wakeup_usb_callback(const char *d_name) +{ + class usb_wakeup *usb; + char filename[PATH_MAX]; + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s/power/wakeup", d_name); + if (access(filename, R_OK) != 0) + return; + + snprintf(filename, sizeof(filename), "/sys/bus/usb/devices/%s/power/wakeup", d_name); + usb = new class usb_wakeup(filename, d_name); + wakeup_all.push_back(usb); +} + +void add_usb_wakeup(void) +{ + process_directory("/sys/bus/usb/devices/", wakeup_usb_callback); +} diff --git a/src/wakeup/wakeup_usb.h b/src/wakeup/wakeup_usb.h new file mode 100644 index 0000000..f7a1f7e --- /dev/null +++ b/src/wakeup/wakeup_usb.h @@ -0,0 +1,50 @@ +/* + * Copyright 2018, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Gayatri Kammela <gayatri.kammela@intel.com> + */ +#ifndef _INCLUDE_GUARD_USB_WAKEUP_H +#define _INCLUDE_GUARD_USB_WAKEUP_H + +#include <vector> + +#include "wakeup.h" + +using namespace std; + +class usb_wakeup : public wakeup { + char usb_path[PATH_MAX]; +public: + char interf[4096]; + usb_wakeup(const char *usb_path, const char *iface); + + virtual int wakeup_value(void); + + virtual void wakeup_toggle(void); + + virtual const char *wakeup_toggle_script(void); + +}; + +extern void add_usb_wakeup(void); + +#endif diff --git a/traceevent/Makefile.am b/traceevent/Makefile.am new file mode 100644 index 0000000..d3ee608 --- /dev/null +++ b/traceevent/Makefile.am @@ -0,0 +1,7 @@ +noinst_LTLIBRARIES = libtraceevnet.la +libtraceevnet_la_SOURCES = event-parse.c \ + event-parse.h \ + event-utils.h \ + parse-filter.c\ + parse-utils.c \ + trace-seq.c diff --git a/traceevent/event-parse.c b/traceevent/event-parse.c new file mode 100644 index 0000000..1f7eb80 --- /dev/null +++ b/traceevent/event-parse.c @@ -0,0 +1,5664 @@ +/* + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * The parts for function graph printing was taken and modified from the + * Linux Kernel that were written by + * - Copyright (C) 2009 Frederic Weisbecker, + * Frederic Weisbecker gave his permission to relicense the code to + * the Lesser General Public License. + */ +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <ctype.h> +#include <errno.h> +#include <stdint.h> +#include <limits.h> + +#include "event-parse.h" +#include "event-utils.h" + +static const char *input_buf; +static unsigned long long input_buf_ptr; +static unsigned long long input_buf_siz; + +static int is_flag_field; +static int is_symbolic_field; + +static int show_warning = 1; + +#define do_warning(fmt, ...) \ + do { \ + if (show_warning) \ + warning(fmt, ##__VA_ARGS__); \ + } while (0) + +static void init_input_buf(const char *buf, unsigned long long size) +{ + input_buf = buf; + input_buf_siz = size; + input_buf_ptr = 0; +} + +const char *pevent_get_input_buf(void) +{ + return input_buf; +} + +unsigned long long pevent_get_input_buf_ptr(void) +{ + return input_buf_ptr; +} + +struct event_handler { + struct event_handler *next; + int id; + const char *sys_name; + const char *event_name; + pevent_event_handler_func func; + void *context; +}; + +struct pevent_func_params { + struct pevent_func_params *next; + enum pevent_func_arg_type type; +}; + +struct pevent_function_handler { + struct pevent_function_handler *next; + enum pevent_func_arg_type ret_type; + char *name; + pevent_func_handler func; + struct pevent_func_params *params; + int nr_args; +}; + +static unsigned long long +process_defined_func(struct trace_seq *s, void *data, int size, + struct event_format *event, struct print_arg *arg); + +static void free_func_handle(struct pevent_function_handler *func); + +/** + * pevent_buffer_init - init buffer for parsing + * @buf: buffer to parse + * @size: the size of the buffer + * + * For use with pevent_read_token(), this initializes the internal + * buffer that pevent_read_token() will parse. + */ +void pevent_buffer_init(const char *buf, unsigned long long size) +{ + init_input_buf(buf, size); +} + +void breakpoint(void) +{ + static int x; + x++; +} + +struct print_arg *alloc_arg(void) +{ + return calloc(1, sizeof(struct print_arg)); +} + +struct cmdline { + char *comm; + int pid; +}; + +static int cmdline_cmp(const void *a, const void *b) +{ + const struct cmdline *ca = a; + const struct cmdline *cb = b; + + if (ca->pid < cb->pid) + return -1; + if (ca->pid > cb->pid) + return 1; + + return 0; +} + +struct cmdline_list { + struct cmdline_list *next; + char *comm; + int pid; +}; + +static int cmdline_init(struct pevent *pevent) +{ + struct cmdline_list *cmdlist = pevent->cmdlist; + struct cmdline_list *item; + struct cmdline *cmdlines; + int i; + + cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count); + if (!cmdlines) + return -1; + + i = 0; + while (cmdlist) { + cmdlines[i].pid = cmdlist->pid; + cmdlines[i].comm = cmdlist->comm; + i++; + item = cmdlist; + cmdlist = cmdlist->next; + free(item); + } + + qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp); + + pevent->cmdlines = cmdlines; + pevent->cmdlist = NULL; + + return 0; +} + +static const char *find_cmdline(struct pevent *pevent, int pid) +{ + const struct cmdline *comm; + struct cmdline key; + + if (!pid) + return "<idle>"; + + if (!pevent->cmdlines && cmdline_init(pevent)) + return "<not enough memory for cmdlines!>"; + + key.pid = pid; + + comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, + sizeof(*pevent->cmdlines), cmdline_cmp); + + if (comm) + return comm->comm; + return "<...>"; +} + +/** + * pevent_pid_is_registered - return if a pid has a cmdline registered + * @pevent: handle for the pevent + * @pid: The pid to check if it has a cmdline registered with. + * + * Returns 1 if the pid has a cmdline mapped to it + * 0 otherwise. + */ +int pevent_pid_is_registered(struct pevent *pevent, int pid) +{ + const struct cmdline *comm; + struct cmdline key; + + if (!pid) + return 1; + + if (!pevent->cmdlines && cmdline_init(pevent)) + return 0; + + key.pid = pid; + + comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, + sizeof(*pevent->cmdlines), cmdline_cmp); + + if (comm) + return 1; + return 0; +} + +/* + * If the command lines have been converted to an array, then + * we must add this pid. This is much slower than when cmdlines + * are added before the array is initialized. + */ +static int add_new_comm(struct pevent *pevent, const char *comm, int pid) +{ + struct cmdline *newcmdlines, *cmdlines = pevent->cmdlines; + const struct cmdline *cmdline; + struct cmdline key; + + if (!pid) + return 0; + + /* avoid duplicates */ + key.pid = pid; + + cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, + sizeof(*pevent->cmdlines), cmdline_cmp); + if (cmdline) { + errno = EEXIST; + return -1; + } + + newcmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1)); + if (!newcmdlines) { + free(cmdlines); + errno = ENOMEM; + return -1; + } + cmdlines = newcmdlines; + + cmdlines[pevent->cmdline_count].comm = strdup(comm); + if (!cmdlines[pevent->cmdline_count].comm) { + free(cmdlines); + errno = ENOMEM; + return -1; + } + + cmdlines[pevent->cmdline_count].pid = pid; + + if (cmdlines[pevent->cmdline_count].comm) + pevent->cmdline_count++; + + qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp); + pevent->cmdlines = cmdlines; + + return 0; +} + +/** + * pevent_register_comm - register a pid / comm mapping + * @pevent: handle for the pevent + * @comm: the command line to register + * @pid: the pid to map the command line to + * + * This adds a mapping to search for command line names with + * a given pid. The comm is duplicated. + */ +int pevent_register_comm(struct pevent *pevent, const char *comm, int pid) +{ + struct cmdline_list *item; + + if (pevent->cmdlines) + return add_new_comm(pevent, comm, pid); + + item = malloc(sizeof(*item)); + if (!item) + return -1; + + item->comm = strdup(comm); + if (!item->comm) { + free(item); + return -1; + } + item->pid = pid; + item->next = pevent->cmdlist; + + pevent->cmdlist = item; + pevent->cmdline_count++; + + return 0; +} + +struct func_map { + unsigned long long addr; + char *func; + char *mod; +}; + +struct func_list { + struct func_list *next; + unsigned long long addr; + char *func; + char *mod; +}; + +static int func_cmp(const void *a, const void *b) +{ + const struct func_map *fa = a; + const struct func_map *fb = b; + + if (fa->addr < fb->addr) + return -1; + if (fa->addr > fb->addr) + return 1; + + return 0; +} + +/* + * We are searching for a record in between, not an exact + * match. + */ +static int func_bcmp(const void *a, const void *b) +{ + const struct func_map *fa = a; + const struct func_map *fb = b; + + if ((fa->addr == fb->addr) || + + (fa->addr > fb->addr && + fa->addr < (fb+1)->addr)) + return 0; + + if (fa->addr < fb->addr) + return -1; + + return 1; +} + +static int func_map_init(struct pevent *pevent) +{ + struct func_list *funclist; + struct func_list *item; + struct func_map *func_map; + int i; + + func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1)); + if (!func_map) + return -1; + + funclist = pevent->funclist; + + i = 0; + while (funclist) { + func_map[i].func = funclist->func; + func_map[i].addr = funclist->addr; + func_map[i].mod = funclist->mod; + i++; + item = funclist; + funclist = funclist->next; + free(item); + } + + qsort(func_map, pevent->func_count, sizeof(*func_map), func_cmp); + + /* + * Add a special record at the end. + */ + func_map[pevent->func_count].func = NULL; + func_map[pevent->func_count].addr = 0; + func_map[pevent->func_count].mod = NULL; + + pevent->func_map = func_map; + pevent->funclist = NULL; + + return 0; +} + +static struct func_map * +find_func(struct pevent *pevent, unsigned long long addr) +{ + struct func_map *func; + struct func_map key; + + if (!pevent->func_map) + func_map_init(pevent); + + key.addr = addr; + + func = bsearch(&key, pevent->func_map, pevent->func_count, + sizeof(*pevent->func_map), func_bcmp); + + return func; +} + +/** + * pevent_find_function - find a function by a given address + * @pevent: handle for the pevent + * @addr: the address to find the function with + * + * Returns a pointer to the function stored that has the given + * address. Note, the address does not have to be exact, it + * will select the function that would contain the address. + */ +const char *pevent_find_function(struct pevent *pevent, unsigned long long addr) +{ + struct func_map *map; + + map = find_func(pevent, addr); + if (!map) + return NULL; + + return map->func; +} + +/** + * pevent_find_function_address - find a function address by a given address + * @pevent: handle for the pevent + * @addr: the address to find the function with + * + * Returns the address the function starts at. This can be used in + * conjunction with pevent_find_function to print both the function + * name and the function offset. + */ +unsigned long long +pevent_find_function_address(struct pevent *pevent, unsigned long long addr) +{ + struct func_map *map; + + map = find_func(pevent, addr); + if (!map) + return 0; + + return map->addr; +} + +/** + * pevent_register_function - register a function with a given address + * @pevent: handle for the pevent + * @function: the function name to register + * @addr: the address the function starts at + * @mod: the kernel module the function may be in (NULL for none) + * + * This registers a function name with an address and module. + * The @func passed in is duplicated. + */ +int pevent_register_function(struct pevent *pevent, char *func, + unsigned long long addr, char *mod) +{ + struct func_list *item = malloc(sizeof(*item)); + + if (!item) + return -1; + + item->next = pevent->funclist; + item->func = strdup(func); + if (!item->func) + goto out_free; + + if (mod) { + item->mod = strdup(mod); + if (!item->mod) + goto out_free_func; + } else + item->mod = NULL; + item->addr = addr; + + pevent->funclist = item; + pevent->func_count++; + + return 0; + +out_free_func: + free(item->func); + item->func = NULL; +out_free: + free(item); + errno = ENOMEM; + return -1; +} + +/** + * pevent_print_funcs - print out the stored functions + * @pevent: handle for the pevent + * + * This prints out the stored functions. + */ +void pevent_print_funcs(struct pevent *pevent) +{ + int i; + + if (!pevent->func_map) + func_map_init(pevent); + + for (i = 0; i < (int)pevent->func_count; i++) { + printf("%016llx %s", + pevent->func_map[i].addr, + pevent->func_map[i].func); + if (pevent->func_map[i].mod) + printf(" [%s]\n", pevent->func_map[i].mod); + else + printf("\n"); + } +} + +struct printk_map { + unsigned long long addr; + char *printk; +}; + +struct printk_list { + struct printk_list *next; + unsigned long long addr; + char *printk; +}; + +static int printk_cmp(const void *a, const void *b) +{ + const struct printk_map *pa = a; + const struct printk_map *pb = b; + + if (pa->addr < pb->addr) + return -1; + if (pa->addr > pb->addr) + return 1; + + return 0; +} + +static int printk_map_init(struct pevent *pevent) +{ + struct printk_list *printklist; + struct printk_list *item; + struct printk_map *printk_map; + int i; + + printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1)); + if (!printk_map) + return -1; + + printklist = pevent->printklist; + + i = 0; + while (printklist) { + printk_map[i].printk = printklist->printk; + printk_map[i].addr = printklist->addr; + i++; + item = printklist; + printklist = printklist->next; + free(item); + } + + qsort(printk_map, pevent->printk_count, sizeof(*printk_map), printk_cmp); + + pevent->printk_map = printk_map; + pevent->printklist = NULL; + + return 0; +} + +static struct printk_map * +find_printk(struct pevent *pevent, unsigned long long addr) +{ + struct printk_map *printk; + struct printk_map key; + + if (!pevent->printk_map && printk_map_init(pevent)) + return NULL; + + key.addr = addr; + + printk = bsearch(&key, pevent->printk_map, pevent->printk_count, + sizeof(*pevent->printk_map), printk_cmp); + + return printk; +} + +/** + * pevent_register_print_string - register a string by its address + * @pevent: handle for the pevent + * @fmt: the string format to register + * @addr: the address the string was located at + * + * This registers a string by the address it was stored in the kernel. + * The @fmt passed in is duplicated. + */ +int pevent_register_print_string(struct pevent *pevent, char *fmt, + unsigned long long addr) +{ + struct printk_list *item = malloc(sizeof(*item)); + + if (!item) + return -1; + + item->next = pevent->printklist; + item->addr = addr; + + item->printk = strdup(fmt); + if (!item->printk) + goto out_free; + + pevent->printklist = item; + pevent->printk_count++; + + return 0; + +out_free: + free(item); + errno = ENOMEM; + return -1; +} + +/** + * pevent_print_printk - print out the stored strings + * @pevent: handle for the pevent + * + * This prints the string formats that were stored. + */ +void pevent_print_printk(struct pevent *pevent) +{ + int i; + + if (!pevent->printk_map) + printk_map_init(pevent); + + for (i = 0; i < (int)pevent->printk_count; i++) { + printf("%016llx %s\n", + pevent->printk_map[i].addr, + pevent->printk_map[i].printk); + } +} + +static struct event_format *alloc_event(void) +{ + return calloc(1, sizeof(struct event_format)); +} + +static int add_event(struct pevent *pevent, struct event_format *event) +{ + int i; + struct event_format **events = realloc(pevent->events, sizeof(event) * + (pevent->nr_events + 1)); + if (!events) + return -1; + + pevent->events = events; + + for (i = 0; i < pevent->nr_events; i++) { + if (pevent->events[i]->id > event->id) + break; + } + if (i < pevent->nr_events) + memmove(&pevent->events[i + 1], + &pevent->events[i], + sizeof(event) * (pevent->nr_events - i)); + + pevent->events[i] = event; + pevent->nr_events++; + + event->pevent = pevent; + + return 0; +} + +static int event_item_type(enum event_type type) +{ + switch (type) { + case EVENT_ITEM ... EVENT_SQUOTE: + return 1; + case EVENT_ERROR ... EVENT_DELIM: + default: + return 0; + } +} + +static void free_flag_sym(struct print_flag_sym *fsym) +{ + struct print_flag_sym *next; + + while (fsym) { + next = fsym->next; + free(fsym->value); + free(fsym->str); + free(fsym); + fsym = next; + } +} + +static void free_arg(struct print_arg *arg) +{ + struct print_arg *farg; + + if (!arg) + return; + + switch (arg->type) { + case PRINT_ATOM: + free(arg->atom.atom); + break; + case PRINT_FIELD: + free(arg->field.name); + break; + case PRINT_FLAGS: + free_arg(arg->flags.field); + free(arg->flags.delim); + free_flag_sym(arg->flags.flags); + break; + case PRINT_SYMBOL: + free_arg(arg->symbol.field); + free_flag_sym(arg->symbol.symbols); + break; + case PRINT_HEX: + free_arg(arg->hex.field); + free_arg(arg->hex.size); + break; + case PRINT_TYPE: + free(arg->typecast.type); + free_arg(arg->typecast.item); + break; + case PRINT_STRING: + case PRINT_BSTRING: + free(arg->string.string); + break; + case PRINT_DYNAMIC_ARRAY: + free(arg->dynarray.index); + break; + case PRINT_OP: + free(arg->op.op); + free_arg(arg->op.left); + free_arg(arg->op.right); + break; + case PRINT_FUNC: + while (arg->func.args) { + farg = arg->func.args; + arg->func.args = farg->next; + free_arg(farg); + } + break; + + case PRINT_NULL: + default: + break; + } + + free(arg); +} + +static enum event_type get_type(int ch) +{ + if (ch == '\n') + return EVENT_NEWLINE; + if (isspace(ch)) + return EVENT_SPACE; + if (isalnum(ch) || ch == '_') + return EVENT_ITEM; + if (ch == '\'') + return EVENT_SQUOTE; + if (ch == '"') + return EVENT_DQUOTE; + if (!isprint(ch)) + return EVENT_NONE; + if (ch == '(' || ch == ')' || ch == ',') + return EVENT_DELIM; + + return EVENT_OP; +} + +static int __read_char(void) +{ + if (input_buf_ptr >= input_buf_siz) + return -1; + + return input_buf[input_buf_ptr++]; +} + +static int __peek_char(void) +{ + if (input_buf_ptr >= input_buf_siz) + return -1; + + return input_buf[input_buf_ptr]; +} + +/** + * pevent_peek_char - peek at the next character that will be read + * + * Returns the next character read, or -1 if end of buffer. + */ +int pevent_peek_char(void) +{ + return __peek_char(); +} + +static int extend_token(char **tok, char *buf, int size) +{ + char *newtok = realloc(*tok, size); + + if (!newtok) { + free(*tok); + *tok = NULL; + return -1; + } + + if (!*tok) + strcpy(newtok, buf); + else + strcat(newtok, buf); + *tok = newtok; + + return 0; +} + +static enum event_type force_token(const char *str, char **tok); + +static enum event_type __read_token(char **tok) +{ + char buf[BUFSIZ]; + int ch, last_ch, quote_ch, next_ch; + int i = 0; + int tok_size = 0; + enum event_type type; + + *tok = NULL; + + + ch = __read_char(); + if (ch < 0) + return EVENT_NONE; + + type = get_type(ch); + if (type == EVENT_NONE) + return type; + + buf[i++] = ch; + + switch (type) { + case EVENT_NEWLINE: + case EVENT_DELIM: + if (asprintf(tok, "%c", ch) < 0) + return EVENT_ERROR; + + return type; + + case EVENT_OP: + switch (ch) { + case '-': + next_ch = __peek_char(); + if (next_ch == '>') { + buf[i++] = __read_char(); + break; + } + /* fall through */ + case '+': + case '|': + case '&': + case '>': + case '<': + last_ch = ch; + ch = __peek_char(); + if (ch != last_ch) + goto test_equal; + buf[i++] = __read_char(); + switch (last_ch) { + case '>': + case '<': + goto test_equal; + default: + break; + } + break; + case '!': + case '=': + goto test_equal; + default: /* what should we do instead? */ + break; + } + buf[i] = 0; + *tok = strdup(buf); + return type; + + test_equal: + ch = __peek_char(); + if (ch == '=') + buf[i++] = __read_char(); + goto out; + + case EVENT_DQUOTE: + case EVENT_SQUOTE: + /* don't keep quotes */ + i--; + quote_ch = ch; + last_ch = 0; + concat: + do { + if (i == (BUFSIZ - 1)) { + buf[i] = 0; + tok_size += BUFSIZ; + + if (extend_token(tok, buf, tok_size) < 0) + return EVENT_NONE; + i = 0; + } + last_ch = ch; + ch = __read_char(); + buf[i++] = ch; + /* the '\' '\' will cancel itself */ + if (ch == '\\' && last_ch == '\\') + last_ch = 0; + } while (ch != quote_ch || last_ch == '\\'); + /* remove the last quote */ + i--; + + /* + * For strings (double quotes) check the next token. + * If it is another string, concatinate the two. + */ + if (type == EVENT_DQUOTE) { + unsigned long long save_input_buf_ptr = input_buf_ptr; + + do { + ch = __read_char(); + } while (isspace(ch)); + if (ch == '"') + goto concat; + input_buf_ptr = save_input_buf_ptr; + } + + goto out; + + case EVENT_ERROR ... EVENT_SPACE: + case EVENT_ITEM: + default: + break; + } + + while (get_type(__peek_char()) == type) { + if (i == (BUFSIZ - 1)) { + buf[i] = 0; + tok_size += BUFSIZ; + + if (extend_token(tok, buf, tok_size) < 0) + return EVENT_NONE; + i = 0; + } + ch = __read_char(); + buf[i++] = ch; + } + + out: + buf[i] = 0; + if (extend_token(tok, buf, tok_size + i + 1) < 0) + return EVENT_NONE; + + if (type == EVENT_ITEM) { + /* + * Older versions of the kernel has a bug that + * creates invalid symbols and will break the mac80211 + * parsing. This is a work around to that bug. + * + * See Linux kernel commit: + * 811cb50baf63461ce0bdb234927046131fc7fa8b + */ + if (strcmp(*tok, "LOCAL_PR_FMT") == 0) { + free(*tok); + *tok = NULL; + return force_token("\"\%s\" ", tok); + } else if (strcmp(*tok, "STA_PR_FMT") == 0) { + free(*tok); + *tok = NULL; + return force_token("\" sta:%pM\" ", tok); + } else if (strcmp(*tok, "VIF_PR_FMT") == 0) { + free(*tok); + *tok = NULL; + return force_token("\" vif:%p(%d)\" ", tok); + } + } + + return type; +} + +static enum event_type force_token(const char *str, char **tok) +{ + const char *save_input_buf; + unsigned long long save_input_buf_ptr; + unsigned long long save_input_buf_siz; + enum event_type type; + + /* save off the current input pointers */ + save_input_buf = input_buf; + save_input_buf_ptr = input_buf_ptr; + save_input_buf_siz = input_buf_siz; + + init_input_buf(str, strlen(str)); + + type = __read_token(tok); + + /* reset back to original token */ + input_buf = save_input_buf; + input_buf_ptr = save_input_buf_ptr; + input_buf_siz = save_input_buf_siz; + + return type; +} + +static void free_token(char *tok) +{ + free(tok); +} + +static enum event_type read_token(char **tok) +{ + enum event_type type; + + for (;;) { + type = __read_token(tok); + if (type != EVENT_SPACE) + return type; + + free_token(*tok); + } + + /* not reached */ + *tok = NULL; + return EVENT_NONE; +} + +/** + * pevent_read_token - access to utilites to use the pevent parser + * @tok: The token to return + * + * This will parse tokens from the string given by + * pevent_init_data(). + * + * Returns the token type. + */ +enum event_type pevent_read_token(char **tok) +{ + return read_token(tok); +} + +/** + * pevent_free_token - free a token returned by pevent_read_token + * @token: the token to free + */ +void pevent_free_token(char *token) +{ + free_token(token); +} + +/* no newline */ +static enum event_type read_token_item(char **tok) +{ + enum event_type type; + + for (;;) { + type = __read_token(tok); + if (type != EVENT_SPACE && type != EVENT_NEWLINE) + return type; + free_token(*tok); + *tok = NULL; + } + + /* not reached */ + *tok = NULL; + return EVENT_NONE; +} + +static int test_type(enum event_type type, enum event_type expect) +{ + if (type != expect) { + do_warning("Error: expected type %d but read %d", + expect, type); + return -1; + } + return 0; +} + +static int test_type_token(enum event_type type, const char *token, + enum event_type expect, const char *expect_tok) +{ + if (type != expect) { + do_warning("Error: expected type %d but read %d", + expect, type); + return -1; + } + + if (strcmp(token, expect_tok) != 0) { + do_warning("Error: expected '%s' but read '%s'", + expect_tok, token); + return -1; + } + return 0; +} + +static int __read_expect_type(enum event_type expect, char **tok, int newline_ok) +{ + enum event_type type; + + if (newline_ok) + type = read_token(tok); + else + type = read_token_item(tok); + return test_type(type, expect); +} + +static int read_expect_type(enum event_type expect, char **tok) +{ + return __read_expect_type(expect, tok, 1); +} + +static int __read_expected(enum event_type expect, const char *str, + int newline_ok) +{ + enum event_type type; + char *token; + int ret; + + if (newline_ok) + type = read_token(&token); + else + type = read_token_item(&token); + + ret = test_type_token(type, token, expect, str); + + free_token(token); + + return ret; +} + +static int read_expected(enum event_type expect, const char *str) +{ + return __read_expected(expect, str, 1); +} + +static int read_expected_item(enum event_type expect, const char *str) +{ + return __read_expected(expect, str, 0); +} + +static char *event_read_name(void) +{ + char *token; + + if (read_expected(EVENT_ITEM, "name") < 0) + return NULL; + + if (read_expected(EVENT_OP, ":") < 0) + return NULL; + + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto fail; + + return token; + + fail: + free_token(token); + return NULL; +} + +static int event_read_id(void) +{ + char *token; + int id; + + if (read_expected_item(EVENT_ITEM, "ID") < 0) + return -1; + + if (read_expected(EVENT_OP, ":") < 0) + return -1; + + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto fail; + + id = strtoul(token, NULL, 0); + free_token(token); + return id; + + fail: + free_token(token); + return -1; +} + +static int field_is_string(struct format_field *field) +{ + if ((field->flags & FIELD_IS_ARRAY) && + (strstr(field->type, "char") || strstr(field->type, "u8") || + strstr(field->type, "s8"))) + return 1; + + return 0; +} + +static int field_is_dynamic(struct format_field *field) +{ + if (strncmp(field->type, "__data_loc", 10) == 0) + return 1; + + return 0; +} + +static int field_is_long(struct format_field *field) +{ + /* includes long long */ + if (strstr(field->type, "long")) + return 1; + + return 0; +} + +static unsigned int type_size(const char *name) +{ + /* This covers all FIELD_IS_STRING types. */ + static struct { + const char *type; + unsigned int size; + } table[] = { + { "u8", 1 }, + { "u16", 2 }, + { "u32", 4 }, + { "u64", 8 }, + { "s8", 1 }, + { "s16", 2 }, + { "s32", 4 }, + { "s64", 8 }, + { "char", 1 }, + { }, + }; + int i; + + for (i = 0; table[i].type; i++) { + if (!strcmp(table[i].type, name)) + return table[i].size; + } + + return 0; +} + +static int event_read_fields(struct event_format *event, struct format_field **fields) +{ + struct format_field *field = NULL; + enum event_type type; + char *token; + char *last_token; + int count = 0; + + do { + unsigned int size_dynamic = 0; + + type = read_token(&token); + if (type == EVENT_NEWLINE) { + free_token(token); + return count; + } + + count++; + + if (test_type_token(type, token, EVENT_ITEM, "field")) + goto fail; + free_token(token); + + type = read_token(&token); + /* + * The ftrace fields may still use the "special" name. + * Just ignore it. + */ + if (event->flags & EVENT_FL_ISFTRACE && + type == EVENT_ITEM && strcmp(token, "special") == 0) { + free_token(token); + type = read_token(&token); + } + + if (test_type_token(type, token, EVENT_OP, ":") < 0) + goto fail; + + free_token(token); + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto fail; + + last_token = token; + + field = calloc(1, sizeof(*field)); + if (!field) + goto fail; + + field->event = event; + + /* read the rest of the type */ + for (;;) { + type = read_token(&token); + if (type == EVENT_ITEM || + (type == EVENT_OP && strcmp(token, "*") == 0) || + /* + * Some of the ftrace fields are broken and have + * an illegal "." in them. + */ + (event->flags & EVENT_FL_ISFTRACE && + type == EVENT_OP && strcmp(token, ".") == 0)) { + + if (strcmp(token, "*") == 0) + field->flags |= FIELD_IS_POINTER; + + if (field->type) { + char *new_type; + new_type = realloc(field->type, + strlen(field->type) + + strlen(last_token) + 2); + if (!new_type) { + free(last_token); + goto fail; + } + field->type = new_type; + strcat(field->type, " "); + strcat(field->type, last_token); + free(last_token); + } else + field->type = last_token; + last_token = token; + continue; + } + + break; + } + + if (!field->type) { + do_warning("%s: no type found", __func__); + goto fail; + } + field->name = last_token; + + if (test_type(type, EVENT_OP)) + goto fail; + + if (strcmp(token, "[") == 0) { + enum event_type last_type = type; + char *brackets = token; + char *new_brackets; + int len; + + field->flags |= FIELD_IS_ARRAY; + + type = read_token(&token); + + if (type == EVENT_ITEM) + field->arraylen = strtoul(token, NULL, 0); + else + field->arraylen = 0; + + while (strcmp(token, "]") != 0) { + if (last_type == EVENT_ITEM && + type == EVENT_ITEM) + len = 2; + else + len = 1; + last_type = type; + + new_brackets = realloc(brackets, + strlen(brackets) + + strlen(token) + len); + if (!new_brackets) { + free(brackets); + goto fail; + } + brackets = new_brackets; + if (len == 2) + strcat(brackets, " "); + strcat(brackets, token); + /* We only care about the last token */ + field->arraylen = strtoul(token, NULL, 0); + free_token(token); + type = read_token(&token); + if (type == EVENT_NONE) { + do_warning("failed to find token"); + goto fail; + } + } + + free_token(token); + + new_brackets = realloc(brackets, strlen(brackets) + 2); + if (!new_brackets) { + free(brackets); + goto fail; + } + brackets = new_brackets; + strcat(brackets, "]"); + + /* add brackets to type */ + + type = read_token(&token); + /* + * If the next token is not an OP, then it is of + * the format: type [] item; + */ + if (type == EVENT_ITEM) { + char *new_type; + new_type = realloc(field->type, + strlen(field->type) + + strlen(field->name) + + strlen(brackets) + 2); + if (!new_type) { + free(brackets); + goto fail; + } + field->type = new_type; + strcat(field->type, " "); + strcat(field->type, field->name); + size_dynamic = type_size(field->name); + free_token(field->name); + strcat(field->type, brackets); + field->name = token; + type = read_token(&token); + } else { + char *new_type; + new_type = realloc(field->type, + strlen(field->type) + + strlen(brackets) + 1); + if (!new_type) { + free(brackets); + goto fail; + } + field->type = new_type; + strcat(field->type, brackets); + } + free(brackets); + } + + if (field_is_string(field)) + field->flags |= FIELD_IS_STRING; + if (field_is_dynamic(field)) + field->flags |= FIELD_IS_DYNAMIC; + if (field_is_long(field)) + field->flags |= FIELD_IS_LONG; + + if (test_type_token(type, token, EVENT_OP, ";")) + goto fail; + free_token(token); + + if (read_expected(EVENT_ITEM, "offset") < 0) + goto fail_expect; + + if (read_expected(EVENT_OP, ":") < 0) + goto fail_expect; + + if (read_expect_type(EVENT_ITEM, &token)) + goto fail; + field->offset = strtoul(token, NULL, 0); + free_token(token); + + if (read_expected(EVENT_OP, ";") < 0) + goto fail_expect; + + if (read_expected(EVENT_ITEM, "size") < 0) + goto fail_expect; + + if (read_expected(EVENT_OP, ":") < 0) + goto fail_expect; + + if (read_expect_type(EVENT_ITEM, &token)) + goto fail; + field->size = strtoul(token, NULL, 0); + free_token(token); + + if (read_expected(EVENT_OP, ";") < 0) + goto fail_expect; + + type = read_token(&token); + if (type != EVENT_NEWLINE) { + /* newer versions of the kernel have a "signed" type */ + if (test_type_token(type, token, EVENT_ITEM, "signed")) + goto fail; + + free_token(token); + + if (read_expected(EVENT_OP, ":") < 0) + goto fail_expect; + + if (read_expect_type(EVENT_ITEM, &token)) + goto fail; + + if (strtoul(token, NULL, 0)) + field->flags |= FIELD_IS_SIGNED; + + free_token(token); + if (read_expected(EVENT_OP, ";") < 0) + goto fail_expect; + + if (read_expect_type(EVENT_NEWLINE, &token)) + goto fail; + } + + free_token(token); + + if (field->flags & FIELD_IS_ARRAY) { + if (field->arraylen) + field->elementsize = field->size / field->arraylen; + else if (field->flags & FIELD_IS_DYNAMIC) + field->elementsize = size_dynamic; + else if (field->flags & FIELD_IS_STRING) + field->elementsize = 1; + else if (field->flags & FIELD_IS_LONG) + field->elementsize = event->pevent ? + event->pevent->long_size : + sizeof(long); + } else + field->elementsize = field->size; + + *fields = field; + fields = &field->next; + + } while (1); + + return 0; + +fail: + free_token(token); +fail_expect: + if (field) { + free(field->type); + free(field->name); + free(field); + } + return -1; +} + +static int event_read_format(struct event_format *event) +{ + char *token; + int ret; + + if (read_expected_item(EVENT_ITEM, "format") < 0) + return -1; + + if (read_expected(EVENT_OP, ":") < 0) + return -1; + + if (read_expect_type(EVENT_NEWLINE, &token)) + goto fail; + free_token(token); + + ret = event_read_fields(event, &event->format.common_fields); + if (ret < 0) + return ret; + event->format.nr_common = ret; + + ret = event_read_fields(event, &event->format.fields); + if (ret < 0) + return ret; + event->format.nr_fields = ret; + + return 0; + + fail: + free_token(token); + return -1; +} + +static enum event_type +process_arg_token(struct event_format *event, struct print_arg *arg, + char **tok, enum event_type type); + +static enum event_type +process_arg(struct event_format *event, struct print_arg *arg, char **tok) +{ + enum event_type type; + char *token; + + type = read_token(&token); + *tok = token; + + return process_arg_token(event, arg, tok, type); +} + +static enum event_type +process_op(struct event_format *event, struct print_arg *arg, char **tok); + +static enum event_type +process_cond(struct event_format *event, struct print_arg *top, char **tok) +{ + struct print_arg *arg, *left, *right; + enum event_type type; + char *token = NULL; + + arg = alloc_arg(); + left = alloc_arg(); + right = alloc_arg(); + + if (!arg || !left || !right) { + do_warning("%s: not enough memory!", __func__); + /* arg will be freed at out_free */ + free_arg(left); + free_arg(right); + goto out_free; + } + + arg->type = PRINT_OP; + arg->op.left = left; + arg->op.right = right; + + *tok = NULL; + type = process_arg(event, left, &token); + + again: + /* Handle other operations in the arguments */ + if (type == EVENT_OP && strcmp(token, ":") != 0) { + type = process_op(event, left, &token); + goto again; + } + + if (test_type_token(type, token, EVENT_OP, ":")) + goto out_free; + + arg->op.op = token; + + type = process_arg(event, right, &token); + + top->op.right = arg; + + *tok = token; + return type; + +out_free: + /* Top may point to itself */ + top->op.right = NULL; + free_token(token); + free_arg(arg); + return EVENT_ERROR; +} + +static enum event_type +process_array(struct event_format *event, struct print_arg *top, char **tok) +{ + struct print_arg *arg; + enum event_type type; + char *token = NULL; + + arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + /* '*tok' is set to top->op.op. No need to free. */ + *tok = NULL; + return EVENT_ERROR; + } + + *tok = NULL; + type = process_arg(event, arg, &token); + if (test_type_token(type, token, EVENT_OP, "]")) + goto out_free; + + top->op.right = arg; + + free_token(token); + type = read_token_item(&token); + *tok = token; + + return type; + +out_free: + free_token(token); + free_arg(arg); + return EVENT_ERROR; +} + +static int get_op_prio(char *op) +{ + if (!op[1]) { + switch (op[0]) { + case '~': + case '!': + return 4; + case '*': + case '/': + case '%': + return 6; + case '+': + case '-': + return 7; + /* '>>' and '<<' are 8 */ + case '<': + case '>': + return 9; + /* '==' and '!=' are 10 */ + case '&': + return 11; + case '^': + return 12; + case '|': + return 13; + case '?': + return 16; + default: + do_warning("unknown op '%c'", op[0]); + return -1; + } + } else { + if (strcmp(op, "++") == 0 || + strcmp(op, "--") == 0) { + return 3; + } else if (strcmp(op, ">>") == 0 || + strcmp(op, "<<") == 0) { + return 8; + } else if (strcmp(op, ">=") == 0 || + strcmp(op, "<=") == 0) { + return 9; + } else if (strcmp(op, "==") == 0 || + strcmp(op, "!=") == 0) { + return 10; + } else if (strcmp(op, "&&") == 0) { + return 14; + } else if (strcmp(op, "||") == 0) { + return 15; + } else { + do_warning("unknown op '%s'", op); + return -1; + } + } +} + +static int set_op_prio(struct print_arg *arg) +{ + + /* single ops are the greatest */ + if (!arg->op.left || arg->op.left->type == PRINT_NULL) + arg->op.prio = 0; + else + arg->op.prio = get_op_prio(arg->op.op); + + return arg->op.prio; +} + +/* Note, *tok does not get freed, but will most likely be saved */ +static enum event_type +process_op(struct event_format *event, struct print_arg *arg, char **tok) +{ + struct print_arg *left, *right = NULL; + enum event_type type; + char *token; + + /* the op is passed in via tok */ + token = *tok; + + if (arg->type == PRINT_OP && !arg->op.left) { + /* handle single op */ + if (token[1]) { + do_warning("bad op token %s", token); + goto out_free; + } + switch (token[0]) { + case '~': + case '!': + case '+': + case '-': + break; + default: + do_warning("bad op token %s", token); + goto out_free; + + } + + /* make an empty left */ + left = alloc_arg(); + if (!left) + goto out_warn_free; + + left->type = PRINT_NULL; + arg->op.left = left; + + right = alloc_arg(); + if (!right) + goto out_warn_free; + + arg->op.right = right; + + /* do not free the token, it belongs to an op */ + *tok = NULL; + type = process_arg(event, right, tok); + + } else if (strcmp(token, "?") == 0) { + + left = alloc_arg(); + if (!left) + goto out_warn_free; + + /* copy the top arg to the left */ + *left = *arg; + + arg->type = PRINT_OP; + arg->op.op = token; + arg->op.left = left; + arg->op.prio = 0; + + /* it will set arg->op.right */ + type = process_cond(event, arg, tok); + + } else if (strcmp(token, ">>") == 0 || + strcmp(token, "<<") == 0 || + strcmp(token, "&") == 0 || + strcmp(token, "|") == 0 || + strcmp(token, "&&") == 0 || + strcmp(token, "||") == 0 || + strcmp(token, "-") == 0 || + strcmp(token, "+") == 0 || + strcmp(token, "*") == 0 || + strcmp(token, "^") == 0 || + strcmp(token, "/") == 0 || + strcmp(token, "<") == 0 || + strcmp(token, ">") == 0 || + strcmp(token, "<=") == 0 || + strcmp(token, ">=") == 0 || + strcmp(token, "==") == 0 || + strcmp(token, "!=") == 0) { + + left = alloc_arg(); + if (!left) + goto out_warn_free; + + /* copy the top arg to the left */ + *left = *arg; + + arg->type = PRINT_OP; + arg->op.op = token; + arg->op.left = left; + arg->op.right = NULL; + + if (set_op_prio(arg) == -1) { + event->flags |= EVENT_FL_FAILED; + /* arg->op.op (= token) will be freed at out_free */ + arg->op.op = NULL; + goto out_free; + } + + type = read_token_item(&token); + *tok = token; + + /* could just be a type pointer */ + if ((strcmp(arg->op.op, "*") == 0) && + type == EVENT_DELIM && (strcmp(token, ")") == 0)) { + char *new_atom; + + if (left->type != PRINT_ATOM) { + do_warning("bad pointer type"); + goto out_free; + } + new_atom = realloc(left->atom.atom, + strlen(left->atom.atom) + 3); + if (!new_atom) + goto out_warn_free; + + left->atom.atom = new_atom; + strcat(left->atom.atom, " *"); + free(arg->op.op); + *arg = *left; + free(left); + + return type; + } + + right = alloc_arg(); + if (!right) + goto out_warn_free; + + type = process_arg_token(event, right, tok, type); + arg->op.right = right; + + } else if (strcmp(token, "[") == 0) { + + left = alloc_arg(); + if (!left) + goto out_warn_free; + + *left = *arg; + + arg->type = PRINT_OP; + arg->op.op = token; + arg->op.left = left; + + arg->op.prio = 0; + + /* it will set arg->op.right */ + type = process_array(event, arg, tok); + + } else { + do_warning("unknown op '%s'", token); + event->flags |= EVENT_FL_FAILED; + /* the arg is now the left side */ + goto out_free; + } + + if (type == EVENT_OP && strcmp(*tok, ":") != 0) { + int prio; + + /* higher prios need to be closer to the root */ + prio = get_op_prio(*tok); + + if (prio > arg->op.prio) + return process_op(event, arg, tok); + + return process_op(event, right, tok); + } + + return type; + +out_warn_free: + do_warning("%s: not enough memory!", __func__); +out_free: + free_token(token); + *tok = NULL; + return EVENT_ERROR; +} + +static enum event_type +process_entry(struct event_format *event __maybe_unused, struct print_arg *arg, + char **tok) +{ + enum event_type type; + char *field; + char *token; + + if (read_expected(EVENT_OP, "->") < 0) + goto out_err; + + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto out_free; + field = token; + + arg->type = PRINT_FIELD; + arg->field.name = field; + + if (is_flag_field) { + arg->field.field = pevent_find_any_field(event, arg->field.name); + arg->field.field->flags |= FIELD_IS_FLAG; + is_flag_field = 0; + } else if (is_symbolic_field) { + arg->field.field = pevent_find_any_field(event, arg->field.name); + arg->field.field->flags |= FIELD_IS_SYMBOLIC; + is_symbolic_field = 0; + } + + type = read_token(&token); + *tok = token; + + return type; + + out_free: + free_token(token); + out_err: + *tok = NULL; + return EVENT_ERROR; +} + +static char *arg_eval (struct print_arg *arg); + +static unsigned long long +eval_type_str(unsigned long long val, const char *type, int pointer) +{ + int sign = 0; + char *ref; + int len; + + len = strlen(type); + + if (pointer) { + + if (type[len-1] != '*') { + do_warning("pointer expected with non pointer type"); + return val; + } + + ref = malloc(len); + if (!ref) { + do_warning("%s: not enough memory!", __func__); + return val; + } + memcpy(ref, type, len); + + /* chop off the " *" */ + ref[len - 2] = 0; + + val = eval_type_str(val, ref, 0); + free(ref); + return val; + } + + /* check if this is a pointer */ + if (type[len - 1] == '*') + return val; + + /* Try to figure out the arg size*/ + if (strncmp(type, "struct", 6) == 0) + /* all bets off */ + return val; + + if (strcmp(type, "u8") == 0) + return val & 0xff; + + if (strcmp(type, "u16") == 0) + return val & 0xffff; + + if (strcmp(type, "u32") == 0) + return val & 0xffffffff; + + if (strcmp(type, "u64") == 0 || + strcmp(type, "s64")) + return val; + + if (strcmp(type, "s8") == 0) + return (unsigned long long)(char)val & 0xff; + + if (strcmp(type, "s16") == 0) + return (unsigned long long)(short)val & 0xffff; + + if (strcmp(type, "s32") == 0) + return (unsigned long long)(int)val & 0xffffffff; + + if (strncmp(type, "unsigned ", 9) == 0) { + sign = 0; + type += 9; + } + + if (strcmp(type, "char") == 0) { + if (sign) + return (unsigned long long)(char)val & 0xff; + else + return val & 0xff; + } + + if (strcmp(type, "short") == 0) { + if (sign) + return (unsigned long long)(short)val & 0xffff; + else + return val & 0xffff; + } + + if (strcmp(type, "int") == 0) { + if (sign) + return (unsigned long long)(int)val & 0xffffffff; + else + return val & 0xffffffff; + } + + return val; +} + +/* + * Try to figure out the type. + */ +static unsigned long long +eval_type(unsigned long long val, struct print_arg *arg, int pointer) +{ + if (arg->type != PRINT_TYPE) { + do_warning("expected type argument"); + return 0; + } + + return eval_type_str(val, arg->typecast.type, pointer); +} + +static int arg_num_eval(struct print_arg *arg, long long *val) +{ + long long left, right; + int ret = 1; + + switch (arg->type) { + case PRINT_ATOM: + *val = strtoll(arg->atom.atom, NULL, 0); + break; + case PRINT_TYPE: + ret = arg_num_eval(arg->typecast.item, val); + if (!ret) + break; + *val = eval_type(*val, arg, 0); + break; + case PRINT_OP: + switch (arg->op.op[0]) { + case '|': + ret = arg_num_eval(arg->op.left, &left); + if (!ret) + break; + ret = arg_num_eval(arg->op.right, &right); + if (!ret) + break; + if (arg->op.op[1]) + *val = left || right; + else + *val = left | right; + break; + case '&': + ret = arg_num_eval(arg->op.left, &left); + if (!ret) + break; + ret = arg_num_eval(arg->op.right, &right); + if (!ret) + break; + if (arg->op.op[1]) + *val = left && right; + else + *val = left & right; + break; + case '<': + ret = arg_num_eval(arg->op.left, &left); + if (!ret) + break; + ret = arg_num_eval(arg->op.right, &right); + if (!ret) + break; + switch (arg->op.op[1]) { + case 0: + *val = left < right; + break; + case '<': + *val = left << right; + break; + case '=': + *val = left <= right; + break; + default: + do_warning("unknown op '%s'", arg->op.op); + ret = 0; + } + break; + case '>': + ret = arg_num_eval(arg->op.left, &left); + if (!ret) + break; + ret = arg_num_eval(arg->op.right, &right); + if (!ret) + break; + switch (arg->op.op[1]) { + case 0: + *val = left > right; + break; + case '>': + *val = left >> right; + break; + case '=': + *val = left >= right; + break; + default: + do_warning("unknown op '%s'", arg->op.op); + ret = 0; + } + break; + case '=': + ret = arg_num_eval(arg->op.left, &left); + if (!ret) + break; + ret = arg_num_eval(arg->op.right, &right); + if (!ret) + break; + + if (arg->op.op[1] != '=') { + do_warning("unknown op '%s'", arg->op.op); + ret = 0; + } else + *val = left == right; + break; + case '!': + ret = arg_num_eval(arg->op.left, &left); + if (!ret) + break; + ret = arg_num_eval(arg->op.right, &right); + if (!ret) + break; + + switch (arg->op.op[1]) { + case '=': + *val = left != right; + break; + default: + do_warning("unknown op '%s'", arg->op.op); + ret = 0; + } + break; + case '-': + /* check for negative */ + if (arg->op.left->type == PRINT_NULL) + left = 0; + else + ret = arg_num_eval(arg->op.left, &left); + if (!ret) + break; + ret = arg_num_eval(arg->op.right, &right); + if (!ret) + break; + *val = left - right; + break; + case '+': + if (arg->op.left->type == PRINT_NULL) + left = 0; + else + ret = arg_num_eval(arg->op.left, &left); + if (!ret) + break; + ret = arg_num_eval(arg->op.right, &right); + if (!ret) + break; + *val = left + right; + break; + default: + do_warning("unknown op '%s'", arg->op.op); + ret = 0; + } + break; + + case PRINT_NULL: + case PRINT_FIELD ... PRINT_SYMBOL: + case PRINT_STRING: + case PRINT_BSTRING: + default: + do_warning("invalid eval type %d", arg->type); + ret = 0; + + } + return ret; +} + +static char *arg_eval (struct print_arg *arg) +{ + long long val; + static char buf[20]; + + switch (arg->type) { + case PRINT_ATOM: + return arg->atom.atom; + case PRINT_TYPE: + return arg_eval(arg->typecast.item); + case PRINT_OP: + if (!arg_num_eval(arg, &val)) + break; + sprintf(buf, "%lld", val); + return buf; + + case PRINT_NULL: + case PRINT_FIELD ... PRINT_SYMBOL: + case PRINT_STRING: + case PRINT_BSTRING: + default: + do_warning("invalid eval type %d", arg->type); + break; + } + + return NULL; +} + +static enum event_type +process_fields(struct event_format *event, struct print_flag_sym **list, char **tok) +{ + enum event_type type; + struct print_arg *arg = NULL; + struct print_flag_sym *field; + char *token = *tok; + char *value; + + do { + free_token(token); + type = read_token_item(&token); + if (test_type_token(type, token, EVENT_OP, "{")) + break; + + arg = alloc_arg(); + if (!arg) + goto out_free; + + free_token(token); + type = process_arg(event, arg, &token); + + if (type == EVENT_OP) + type = process_op(event, arg, &token); + + if (type == EVENT_ERROR) + goto out_free; + + if (test_type_token(type, token, EVENT_DELIM, ",")) + goto out_free; + + field = calloc(1, sizeof(*field)); + if (!field) + goto out_free; + + value = arg_eval(arg); + if (value == NULL) + goto out_free_field; + field->value = strdup(value); + if (field->value == NULL) + goto out_free_field; + + free_arg(arg); + arg = alloc_arg(); + if (!arg) + goto out_free; + + free_token(token); + type = process_arg(event, arg, &token); + if (test_type_token(type, token, EVENT_OP, "}")) + goto out_free_field; + + value = arg_eval(arg); + if (value == NULL) + goto out_free_field; + field->str = strdup(value); + if (field->str == NULL) + goto out_free_field; + free_arg(arg); + arg = NULL; + + *list = field; + list = &field->next; + + free_token(token); + type = read_token_item(&token); + } while (type == EVENT_DELIM && strcmp(token, ",") == 0); + + *tok = token; + return type; + +out_free_field: + free_flag_sym(field); +out_free: + free_arg(arg); + free_token(token); + *tok = NULL; + + return EVENT_ERROR; +} + +static enum event_type +process_flags(struct event_format *event, struct print_arg *arg, char **tok) +{ + struct print_arg *field; + enum event_type type; + char *token; + + memset(arg, 0, sizeof(*arg)); + arg->type = PRINT_FLAGS; + + field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out; + } + + type = process_arg(event, field, &token); + + /* Handle operations in the first argument */ + while (type == EVENT_OP) + type = process_op(event, field, &token); + + if (test_type_token(type, token, EVENT_DELIM, ",")) + goto out_free_field; + free_token(token); + + arg->flags.field = field; + + type = read_token_item(&token); + if (event_item_type(type)) { + arg->flags.delim = token; + type = read_token_item(&token); + } + + if (test_type_token(type, token, EVENT_DELIM, ",")) + goto out_free; + + type = process_fields(event, &arg->flags.flags, &token); + if (test_type_token(type, token, EVENT_DELIM, ")")) + goto out_free; + + free_token(token); + type = read_token_item(tok); + return type; + +out_free_field: + free_arg(field); +out_free: + free_token(token); +out: + *tok = NULL; + return EVENT_ERROR; +} + +static enum event_type +process_symbols(struct event_format *event, struct print_arg *arg, char **tok) +{ + struct print_arg *field; + enum event_type type; + char *token; + + memset(arg, 0, sizeof(*arg)); + arg->type = PRINT_SYMBOL; + + field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out; + } + + type = process_arg(event, field, &token); + if (test_type_token(type, token, EVENT_DELIM, ",")) + goto out_free_field; + + arg->symbol.field = field; + + type = process_fields(event, &arg->symbol.symbols, &token); + if (test_type_token(type, token, EVENT_DELIM, ")")) + goto out_free; + + free_token(token); + type = read_token_item(tok); + return type; + +out_free_field: + free_arg(field); +out_free: + free_token(token); +out: + *tok = NULL; + return EVENT_ERROR; +} + +static enum event_type +process_hex(struct event_format *event, struct print_arg *arg, char **tok) +{ + struct print_arg *field; + enum event_type type; + char *token; + + memset(arg, 0, sizeof(*arg)); + arg->type = PRINT_HEX; + + field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out; + } + + type = process_arg(event, field, &token); + + if (test_type_token(type, token, EVENT_DELIM, ",")) + goto out_free; + + arg->hex.field = field; + + free_token(token); + + field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + *tok = NULL; + return EVENT_ERROR; + } + + type = process_arg(event, field, &token); + + if (test_type_token(type, token, EVENT_DELIM, ")")) + goto out_free; + + arg->hex.size = field; + + free_token(token); + type = read_token_item(tok); + return type; + + out_free: + free_arg(field); + free_token(token); +out: + *tok = NULL; + return EVENT_ERROR; +} + +static enum event_type +process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) +{ + struct format_field *field; + enum event_type type; + char *token; + + memset(arg, 0, sizeof(*arg)); + arg->type = PRINT_DYNAMIC_ARRAY; + + /* + * The item within the parenthesis is another field that holds + * the index into where the array starts. + */ + type = read_token(&token); + *tok = token; + if (type != EVENT_ITEM) + goto out_free; + + /* Find the field */ + + field = pevent_find_field(event, token); + if (!field) + goto out_free; + + arg->dynarray.field = field; + arg->dynarray.index = 0; + + if (read_expected(EVENT_DELIM, ")") < 0) + goto out_free; + + free_token(token); + type = read_token_item(&token); + *tok = token; + if (type != EVENT_OP || strcmp(token, "[") != 0) + return type; + + free_token(token); + arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + *tok = NULL; + return EVENT_ERROR; + } + + type = process_arg(event, arg, &token); + if (type == EVENT_ERROR) + goto out_free_arg; + + if (!test_type_token(type, token, EVENT_OP, "]")) + goto out_free_arg; + + free_token(token); + type = read_token_item(tok); + return type; + + out_free_arg: + free_arg(arg); + out_free: + free_token(token); + *tok = NULL; + return EVENT_ERROR; +} + +static enum event_type +process_paren(struct event_format *event, struct print_arg *arg, char **tok) +{ + struct print_arg *item_arg; + enum event_type type; + char *token; + + type = process_arg(event, arg, &token); + + if (type == EVENT_ERROR) + goto out_free; + + if (type == EVENT_OP) + type = process_op(event, arg, &token); + + if (type == EVENT_ERROR) + goto out_free; + + if (test_type_token(type, token, EVENT_DELIM, ")")) + goto out_free; + + free_token(token); + type = read_token_item(&token); + + /* + * If the next token is an item or another open paren, then + * this was a typecast. + */ + if (event_item_type(type) || + (type == EVENT_DELIM && strcmp(token, "(") == 0)) { + + /* make this a typecast and contine */ + + /* prevous must be an atom */ + if (arg->type != PRINT_ATOM) { + do_warning("previous needed to be PRINT_ATOM"); + goto out_free; + } + + item_arg = alloc_arg(); + if (!item_arg) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } + + arg->type = PRINT_TYPE; + arg->typecast.type = arg->atom.atom; + arg->typecast.item = item_arg; + type = process_arg_token(event, item_arg, &token, type); + + } + + *tok = token; + return type; + + out_free: + free_token(token); + *tok = NULL; + return EVENT_ERROR; +} + + +static enum event_type +process_str(struct event_format *event __maybe_unused, struct print_arg *arg, + char **tok) +{ + enum event_type type; + char *token; + + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto out_free; + + arg->type = PRINT_STRING; + arg->string.string = token; + arg->string.offset = -1; + + if (read_expected(EVENT_DELIM, ")") < 0) + goto out_err; + + type = read_token(&token); + *tok = token; + + return type; + + out_free: + free_token(token); + out_err: + *tok = NULL; + return EVENT_ERROR; +} + +static struct pevent_function_handler * +find_func_handler(struct pevent *pevent, char *func_name) +{ + struct pevent_function_handler *func; + + if (!pevent) + return NULL; + + for (func = pevent->func_handlers; func; func = func->next) { + if (strcmp(func->name, func_name) == 0) + break; + } + + return func; +} + +static void remove_func_handler(struct pevent *pevent, char *func_name) +{ + struct pevent_function_handler *func; + struct pevent_function_handler **next; + + next = &pevent->func_handlers; + while ((func = *next)) { + if (strcmp(func->name, func_name) == 0) { + *next = func->next; + free_func_handle(func); + break; + } + next = &func->next; + } +} + +static enum event_type +process_func_handler(struct event_format *event, struct pevent_function_handler *func, + struct print_arg *arg, char **tok) +{ + struct print_arg **next_arg; + struct print_arg *farg; + enum event_type type; + char *token; + const char *test; + int i; + + arg->type = PRINT_FUNC; + arg->func.func = func; + + *tok = NULL; + + next_arg = &(arg->func.args); + for (i = 0; i < func->nr_args; i++) { + farg = alloc_arg(); + if (!farg) { + do_warning("%s: not enough memory!", __func__); + return EVENT_ERROR; + } + + type = process_arg(event, farg, &token); + if (i < (func->nr_args - 1)) + test = ","; + else + test = ")"; + + if (test_type_token(type, token, EVENT_DELIM, test)) { + free_arg(farg); + free_token(token); + return EVENT_ERROR; + } + + *next_arg = farg; + next_arg = &(farg->next); + free_token(token); + } + + type = read_token(&token); + *tok = token; + + return type; +} + +static enum event_type +process_function(struct event_format *event, struct print_arg *arg, + char *token, char **tok) +{ + struct pevent_function_handler *func; + + if (strcmp(token, "__print_flags") == 0) { + free_token(token); + is_flag_field = 1; + return process_flags(event, arg, tok); + } + if (strcmp(token, "__print_symbolic") == 0) { + free_token(token); + is_symbolic_field = 1; + return process_symbols(event, arg, tok); + } + if (strcmp(token, "__print_hex") == 0) { + free_token(token); + return process_hex(event, arg, tok); + } + if (strcmp(token, "__get_str") == 0) { + free_token(token); + return process_str(event, arg, tok); + } + if (strcmp(token, "__get_dynamic_array") == 0) { + free_token(token); + return process_dynamic_array(event, arg, tok); + } + + func = find_func_handler(event->pevent, token); + if (func) { + free_token(token); + return process_func_handler(event, func, arg, tok); + } + + do_warning("function %s not defined", token); + free_token(token); + return EVENT_ERROR; +} + +static enum event_type +process_arg_token(struct event_format *event, struct print_arg *arg, + char **tok, enum event_type type) +{ + char *token; + char *atom; + + token = *tok; + + switch (type) { + case EVENT_ITEM: + if (strcmp(token, "REC") == 0) { + free_token(token); + type = process_entry(event, arg, &token); + break; + } + atom = token; + /* test the next token */ + type = read_token_item(&token); + + /* + * If the next token is a parenthesis, then this + * is a function. + */ + if (type == EVENT_DELIM && strcmp(token, "(") == 0) { + free_token(token); + token = NULL; + /* this will free atom. */ + type = process_function(event, arg, atom, &token); + break; + } + /* atoms can be more than one token long */ + while (type == EVENT_ITEM) { + char *new_atom; + new_atom = realloc(atom, + strlen(atom) + strlen(token) + 2); + if (!new_atom) { + free(atom); + *tok = NULL; + free_token(token); + return EVENT_ERROR; + } + atom = new_atom; + strcat(atom, " "); + strcat(atom, token); + free_token(token); + type = read_token_item(&token); + } + + arg->type = PRINT_ATOM; + arg->atom.atom = atom; + break; + + case EVENT_DQUOTE: + case EVENT_SQUOTE: + arg->type = PRINT_ATOM; + arg->atom.atom = token; + type = read_token_item(&token); + break; + case EVENT_DELIM: + if (strcmp(token, "(") == 0) { + free_token(token); + type = process_paren(event, arg, &token); + break; + } + case EVENT_OP: + /* handle single ops */ + arg->type = PRINT_OP; + arg->op.op = token; + arg->op.left = NULL; + type = process_op(event, arg, &token); + + /* On error, the op is freed */ + if (type == EVENT_ERROR) + arg->op.op = NULL; + + /* return error type if errored */ + break; + + case EVENT_ERROR ... EVENT_NEWLINE: + default: + do_warning("unexpected type %d", type); + return EVENT_ERROR; + } + *tok = token; + + return type; +} + +static int event_read_print_args(struct event_format *event, struct print_arg **list) +{ + enum event_type type = EVENT_ERROR; + struct print_arg *arg; + char *token; + int args = 0; + + do { + if (type == EVENT_NEWLINE) { + type = read_token_item(&token); + continue; + } + + arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + return -1; + } + + type = process_arg(event, arg, &token); + + if (type == EVENT_ERROR) { + free_token(token); + free_arg(arg); + return -1; + } + + *list = arg; + args++; + + if (type == EVENT_OP) { + type = process_op(event, arg, &token); + free_token(token); + if (type == EVENT_ERROR) { + *list = NULL; + free_arg(arg); + return -1; + } + list = &arg->next; + continue; + } + + if (type == EVENT_DELIM && strcmp(token, ",") == 0) { + free_token(token); + *list = arg; + list = &arg->next; + continue; + } + break; + } while (type != EVENT_NONE); + + if (type != EVENT_NONE && type != EVENT_ERROR) + free_token(token); + + return args; +} + +static int event_read_print(struct event_format *event) +{ + enum event_type type; + char *token; + int ret; + + if (read_expected_item(EVENT_ITEM, "print") < 0) + return -1; + + if (read_expected(EVENT_ITEM, "fmt") < 0) + return -1; + + if (read_expected(EVENT_OP, ":") < 0) + return -1; + + if (read_expect_type(EVENT_DQUOTE, &token) < 0) + goto fail; + + concat: + event->print_fmt.format = token; + event->print_fmt.args = NULL; + + /* ok to have no arg */ + type = read_token_item(&token); + + if (type == EVENT_NONE) + return 0; + + /* Handle concatenation of print lines */ + if (type == EVENT_DQUOTE) { + char *cat; + + if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0) + goto fail; + free_token(token); + free_token(event->print_fmt.format); + event->print_fmt.format = NULL; + token = cat; + goto concat; + } + + if (test_type_token(type, token, EVENT_DELIM, ",")) + goto fail; + + free_token(token); + + ret = event_read_print_args(event, &event->print_fmt.args); + if (ret < 0) + return -1; + + return ret; + + fail: + free_token(token); + return -1; +} + +/** + * pevent_find_common_field - return a common field by event + * @event: handle for the event + * @name: the name of the common field to return + * + * Returns a common field from the event by the given @name. + * This only searchs the common fields and not all field. + */ +struct format_field * +pevent_find_common_field(struct event_format *event, const char *name) +{ + struct format_field *format; + + for (format = event->format.common_fields; + format; format = format->next) { + if (strcmp(format->name, name) == 0) + break; + } + + return format; +} + +/** + * pevent_find_field - find a non-common field + * @event: handle for the event + * @name: the name of the non-common field + * + * Returns a non-common field by the given @name. + * This does not search common fields. + */ +struct format_field * +pevent_find_field(struct event_format *event, const char *name) +{ + struct format_field *format; + + for (format = event->format.fields; + format; format = format->next) { + if (strcmp(format->name, name) == 0) + break; + } + + return format; +} + +/** + * pevent_find_any_field - find any field by name + * @event: handle for the event + * @name: the name of the field + * + * Returns a field by the given @name. + * This searchs the common field names first, then + * the non-common ones if a common one was not found. + */ +struct format_field * +pevent_find_any_field(struct event_format *event, const char *name) +{ + struct format_field *format; + + format = pevent_find_common_field(event, name); + if (format) + return format; + return pevent_find_field(event, name); +} + +/** + * pevent_read_number - read a number from data + * @pevent: handle for the pevent + * @ptr: the raw data + * @size: the size of the data that holds the number + * + * Returns the number (converted to host) from the + * raw data. + */ +unsigned long long pevent_read_number(struct pevent *pevent, + const void *ptr, int size) +{ + switch (size) { + case 1: + return *(unsigned char *)ptr; + case 2: + return data2host2(pevent, ptr); + case 4: + return data2host4(pevent, ptr); + case 8: + return data2host8(pevent, ptr); + default: + /* BUG! */ + return 0; + } +} + +/** + * pevent_read_number_field - read a number from data + * @field: a handle to the field + * @data: the raw data to read + * @value: the value to place the number in + * + * Reads raw data according to a field offset and size, + * and translates it into @value. + * + * Returns 0 on success, -1 otherwise. + */ +int pevent_read_number_field(struct format_field *field, const void *data, + unsigned long long *value) +{ + if (!field) + return -1; + switch (field->size) { + case 1: + case 2: + case 4: + case 8: + *value = pevent_read_number(field->event->pevent, + data + field->offset, field->size); + return 0; + default: + return -1; + } +} + +static int get_common_info(struct pevent *pevent, + const char *type, int *offset, int *size) +{ + struct event_format *event; + struct format_field *field; + + /* + * All events should have the same common elements. + * Pick any event to find where the type is; + */ + if (!pevent->events) { + do_warning("no event_list!"); + return -1; + } + + event = pevent->events[0]; + field = pevent_find_common_field(event, type); + if (!field) + return -1; + + *offset = field->offset; + *size = field->size; + + return 0; +} + +static int __parse_common(struct pevent *pevent, void *data, + int *size, int *offset, const char *name) +{ + int ret; + + if (!*size) { + ret = get_common_info(pevent, name, offset, size); + if (ret < 0) + return ret; + } + return pevent_read_number(pevent, data + *offset, *size); +} + +static int trace_parse_common_type(struct pevent *pevent, void *data) +{ + return __parse_common(pevent, data, + &pevent->type_size, &pevent->type_offset, + "common_type"); +} + +static int parse_common_pid(struct pevent *pevent, void *data) +{ + return __parse_common(pevent, data, + &pevent->pid_size, &pevent->pid_offset, + "common_pid"); +} + +static int parse_common_pc(struct pevent *pevent, void *data) +{ + return __parse_common(pevent, data, + &pevent->pc_size, &pevent->pc_offset, + "common_preempt_count"); +} + +static int parse_common_flags(struct pevent *pevent, void *data) +{ + return __parse_common(pevent, data, + &pevent->flags_size, &pevent->flags_offset, + "common_flags"); +} + +static int parse_common_lock_depth(struct pevent *pevent, void *data) +{ + return __parse_common(pevent, data, + &pevent->ld_size, &pevent->ld_offset, + "common_lock_depth"); +} + +static int parse_common_migrate_disable(struct pevent *pevent, void *data) +{ + return __parse_common(pevent, data, + &pevent->ld_size, &pevent->ld_offset, + "common_migrate_disable"); +} + +static int events_id_cmp(const void *a, const void *b); + +/** + * pevent_find_event - find an event by given id + * @pevent: a handle to the pevent + * @id: the id of the event + * + * Returns an event that has a given @id. + */ +struct event_format *pevent_find_event(struct pevent *pevent, int id) +{ + struct event_format **eventptr; + struct event_format key; + struct event_format *pkey = &key; + + /* Check cache first */ + if (pevent->last_event && pevent->last_event->id == id) + return pevent->last_event; + + key.id = id; + + eventptr = bsearch(&pkey, pevent->events, pevent->nr_events, + sizeof(*pevent->events), events_id_cmp); + + if (eventptr) { + pevent->last_event = *eventptr; + return *eventptr; + } + + return NULL; +} + +/** + * pevent_find_event_by_name - find an event by given name + * @pevent: a handle to the pevent + * @sys: the system name to search for + * @name: the name of the event to search for + * + * This returns an event with a given @name and under the system + * @sys. If @sys is NULL the first event with @name is returned. + */ +struct event_format * +pevent_find_event_by_name(struct pevent *pevent, + const char *sys, const char *name) +{ + struct event_format *event; + int i; + + if (pevent->last_event && + strcmp(pevent->last_event->name, name) == 0 && + (!sys || strcmp(pevent->last_event->system, sys) == 0)) + return pevent->last_event; + + for (i = 0; i < pevent->nr_events; i++) { + event = pevent->events[i]; + if (strcmp(event->name, name) == 0) { + if (!sys) + break; + if (strcmp(event->system, sys) == 0) + break; + } + } + if (i == pevent->nr_events) + event = NULL; + + pevent->last_event = event; + return event; +} + +static unsigned long long +eval_num_arg(void *data, int size, struct event_format *event, struct print_arg *arg) +{ + struct pevent *pevent = event->pevent; + unsigned long long val = 0; + unsigned long long left, right; + struct print_arg *typearg = NULL; + struct print_arg *larg; + unsigned long offset; + unsigned int field_size; + + switch (arg->type) { + case PRINT_NULL: + /* ?? */ + return 0; + case PRINT_ATOM: + return strtoull(arg->atom.atom, NULL, 0); + case PRINT_FIELD: + if (!arg->field.field) { + arg->field.field = pevent_find_any_field(event, arg->field.name); + if (!arg->field.field) + goto out_warning_field; + + } + /* must be a number */ + val = pevent_read_number(pevent, data + arg->field.field->offset, + arg->field.field->size); + break; + case PRINT_FLAGS: + case PRINT_SYMBOL: + case PRINT_HEX: + break; + case PRINT_TYPE: + val = eval_num_arg(data, size, event, arg->typecast.item); + return eval_type(val, arg, 0); + case PRINT_STRING: + case PRINT_BSTRING: + return 0; + case PRINT_FUNC: { + struct trace_seq s; + trace_seq_init(&s); + val = process_defined_func(&s, data, size, event, arg); + trace_seq_destroy(&s); + return val; + } + case PRINT_OP: + if (strcmp(arg->op.op, "[") == 0) { + /* + * Arrays are special, since we don't want + * to read the arg as is. + */ + right = eval_num_arg(data, size, event, arg->op.right); + + /* handle typecasts */ + larg = arg->op.left; + while (larg->type == PRINT_TYPE) { + if (!typearg) + typearg = larg; + larg = larg->typecast.item; + } + + /* Default to long size */ + field_size = pevent->long_size; + + switch (larg->type) { + case PRINT_DYNAMIC_ARRAY: + offset = pevent_read_number(pevent, + data + larg->dynarray.field->offset, + larg->dynarray.field->size); + if (larg->dynarray.field->elementsize) + field_size = larg->dynarray.field->elementsize; + /* + * The actual length of the dynamic array is stored + * in the top half of the field, and the offset + * is in the bottom half of the 32 bit field. + */ + offset &= 0xffff; + offset += right; + break; + case PRINT_FIELD: + if (!larg->field.field) { + larg->field.field = + pevent_find_any_field(event, larg->field.name); + if (!larg->field.field) { + arg = larg; + goto out_warning_field; + } + } + field_size = larg->field.field->elementsize; + offset = larg->field.field->offset + + right * larg->field.field->elementsize; + break; + default: + goto default_op; /* oops, all bets off */ + } + val = pevent_read_number(pevent, + data + offset, field_size); + if (typearg) + val = eval_type(val, typearg, 1); + break; + } else if (strcmp(arg->op.op, "?") == 0) { + left = eval_num_arg(data, size, event, arg->op.left); + arg = arg->op.right; + if (left) + val = eval_num_arg(data, size, event, arg->op.left); + else + val = eval_num_arg(data, size, event, arg->op.right); + break; + } + default_op: + left = eval_num_arg(data, size, event, arg->op.left); + right = eval_num_arg(data, size, event, arg->op.right); + switch (arg->op.op[0]) { + case '!': + switch (arg->op.op[1]) { + case 0: + val = !right; + break; + case '=': + val = left != right; + break; + default: + goto out_warning_op; + } + break; + case '~': + val = ~right; + break; + case '|': + if (arg->op.op[1]) + val = left || right; + else + val = left | right; + break; + case '&': + if (arg->op.op[1]) + val = left && right; + else + val = left & right; + break; + case '<': + switch (arg->op.op[1]) { + case 0: + val = left < right; + break; + case '<': + val = left << right; + break; + case '=': + val = left <= right; + break; + default: + goto out_warning_op; + } + break; + case '>': + switch (arg->op.op[1]) { + case 0: + val = left > right; + break; + case '>': + val = left >> right; + break; + case '=': + val = left >= right; + break; + default: + goto out_warning_op; + } + break; + case '=': + if (arg->op.op[1] != '=') + goto out_warning_op; + + val = left == right; + break; + case '-': + val = left - right; + break; + case '+': + val = left + right; + break; + case '/': + val = left / right; + break; + case '*': + val = left * right; + break; + default: + goto out_warning_op; + } + break; + default: /* not sure what to do there */ + return 0; + } + return val; + +out_warning_op: + do_warning("%s: unknown op '%s'", __func__, arg->op.op); + return 0; + +out_warning_field: + do_warning("%s: field %s not found", __func__, arg->field.name); + return 0; +} + +struct flag { + const char *name; + unsigned long long value; +}; + +static const struct flag flags[] = { + { "HI_SOFTIRQ", 0 }, + { "TIMER_SOFTIRQ", 1 }, + { "NET_TX_SOFTIRQ", 2 }, + { "NET_RX_SOFTIRQ", 3 }, + { "BLOCK_SOFTIRQ", 4 }, + { "BLOCK_IOPOLL_SOFTIRQ", 5 }, + { "TASKLET_SOFTIRQ", 6 }, + { "SCHED_SOFTIRQ", 7 }, + { "HRTIMER_SOFTIRQ", 8 }, + { "RCU_SOFTIRQ", 9 }, + + { "HRTIMER_NORESTART", 0 }, + { "HRTIMER_RESTART", 1 }, +}; + +static unsigned long long eval_flag(const char *flag) +{ + int i; + + /* + * Some flags in the format files do not get converted. + * If the flag is not numeric, see if it is something that + * we already know about. + */ + if (isdigit(flag[0])) + return strtoull(flag, NULL, 0); + + for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) + if (strcmp(flags[i].name, flag) == 0) + return flags[i].value; + + return 0; +} + +static void print_str_to_seq(struct trace_seq *s, const char *format, + int len_arg, const char *str) +{ + if (len_arg >= 0) + trace_seq_printf(s, format, len_arg, str); + else + trace_seq_printf(s, format, str); +} + +static void print_str_arg(struct trace_seq *s, void *data, int size, + struct event_format *event, const char *format, + int len_arg, struct print_arg *arg) +{ + struct pevent *pevent = event->pevent; + struct print_flag_sym *flag; + struct format_field *field; + unsigned long long val, fval; + unsigned long addr; + char *str; + unsigned char *hex; + int print; + int i, len; + + switch (arg->type) { + case PRINT_NULL: + /* ?? */ + return; + case PRINT_ATOM: + print_str_to_seq(s, format, len_arg, arg->atom.atom); + return; + case PRINT_FIELD: + field = arg->field.field; + if (!field) { + field = pevent_find_any_field(event, arg->field.name); + if (!field) { + str = arg->field.name; + goto out_warning_field; + } + arg->field.field = field; + } + /* Zero sized fields, mean the rest of the data */ + len = field->size ? : size - field->offset; + + /* + * Some events pass in pointers. If this is not an array + * and the size is the same as long_size, assume that it + * is a pointer. + */ + if (!(field->flags & FIELD_IS_ARRAY) && + field->size == pevent->long_size) { + addr = *(unsigned long *)(data + field->offset); + trace_seq_printf(s, "%lx", addr); + break; + } + str = malloc(len + 1); + if (!str) { + do_warning("%s: not enough memory!", __func__); + return; + } + memcpy(str, data + field->offset, len); + str[len] = 0; + print_str_to_seq(s, format, len_arg, str); + free(str); + break; + case PRINT_FLAGS: + val = eval_num_arg(data, size, event, arg->flags.field); + print = 0; + for (flag = arg->flags.flags; flag; flag = flag->next) { + fval = eval_flag(flag->value); + if (!val && !fval) { + print_str_to_seq(s, format, len_arg, flag->str); + break; + } + if (fval && (val & fval) == fval) { + if (print && arg->flags.delim) + trace_seq_puts(s, arg->flags.delim); + print_str_to_seq(s, format, len_arg, flag->str); + print = 1; + val &= ~fval; + } + } + break; + case PRINT_SYMBOL: + val = eval_num_arg(data, size, event, arg->symbol.field); + for (flag = arg->symbol.symbols; flag; flag = flag->next) { + fval = eval_flag(flag->value); + if (val == fval) { + print_str_to_seq(s, format, len_arg, flag->str); + break; + } + } + break; + case PRINT_HEX: + field = arg->hex.field->field.field; + if (!field) { + str = arg->hex.field->field.name; + field = pevent_find_any_field(event, str); + if (!field) + goto out_warning_field; + arg->hex.field->field.field = field; + } + hex = data + field->offset; + len = eval_num_arg(data, size, event, arg->hex.size); + for (i = 0; i < len; i++) { + if (i) + trace_seq_putc(s, ' '); + trace_seq_printf(s, "%02x", hex[i]); + } + break; + + case PRINT_TYPE: + break; + case PRINT_STRING: { + int str_offset; + + if (arg->string.offset == -1) { + struct format_field *f; + + f = pevent_find_any_field(event, arg->string.string); + arg->string.offset = f->offset; + } + str_offset = data2host4(pevent, data + arg->string.offset); + str_offset &= 0xffff; + print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset); + break; + } + case PRINT_BSTRING: + print_str_to_seq(s, format, len_arg, arg->string.string); + break; + case PRINT_OP: + /* + * The only op for string should be ? : + */ + if (arg->op.op[0] != '?') + return; + val = eval_num_arg(data, size, event, arg->op.left); + if (val) + print_str_arg(s, data, size, event, + format, len_arg, arg->op.right->op.left); + else + print_str_arg(s, data, size, event, + format, len_arg, arg->op.right->op.right); + break; + case PRINT_FUNC: + process_defined_func(s, data, size, event, arg); + break; + default: + /* well... */ + break; + } + + return; + +out_warning_field: + do_warning("%s: field %s not found", __func__, arg->field.name); +} + +static unsigned long long +process_defined_func(struct trace_seq *s, void *data, int size, + struct event_format *event, struct print_arg *arg) +{ + struct pevent_function_handler *func_handle = arg->func.func; + struct pevent_func_params *param; + unsigned long long *args; + unsigned long long ret; + struct print_arg *farg; + struct trace_seq str; + struct save_str { + struct save_str *next; + char *str; + } *strings = NULL, *string; + int i; + + if (!func_handle->nr_args) { + ret = (*func_handle->func)(s, NULL); + goto out; + } + + farg = arg->func.args; + param = func_handle->params; + + ret = ULLONG_MAX; + args = malloc(sizeof(*args) * func_handle->nr_args); + if (!args) + goto out; + + for (i = 0; i < func_handle->nr_args; i++) { + switch (param->type) { + case PEVENT_FUNC_ARG_INT: + case PEVENT_FUNC_ARG_LONG: + case PEVENT_FUNC_ARG_PTR: + args[i] = eval_num_arg(data, size, event, farg); + break; + case PEVENT_FUNC_ARG_STRING: + trace_seq_init(&str); + print_str_arg(&str, data, size, event, "%s", -1, farg); + trace_seq_terminate(&str); + string = malloc(sizeof(*string)); + if (!string) { + do_warning("%s(%d): malloc str", __func__, __LINE__); + goto out_free; + } + string->next = strings; + string->str = strdup(str.buffer); + if (!string->str) { + free(string); + do_warning("%s(%d): malloc str", __func__, __LINE__); + goto out_free; + } + args[i] = (uintptr_t)string->str; + strings = string; + trace_seq_destroy(&str); + break; + default: + /* + * Something went totally wrong, this is not + * an input error, something in this code broke. + */ + do_warning("Unexpected end of arguments\n"); + goto out_free; + } + farg = farg->next; + param = param->next; + } + + ret = (*func_handle->func)(s, args); +out_free: + free(args); + while (strings) { + string = strings; + strings = string->next; + free(string->str); + free(string); + } + + out: + /* TBD : handle return type here */ + return ret; +} + +static void free_args(struct print_arg *args) +{ + struct print_arg *next; + + while (args) { + next = args->next; + + free_arg(args); + args = next; + } +} + +static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event) +{ + struct pevent *pevent = event->pevent; + struct format_field *field, *ip_field; + struct print_arg *args, *arg, **next; + unsigned long long ip, val; + char *ptr; + void *bptr; + int vsize; + + field = pevent->bprint_buf_field; + ip_field = pevent->bprint_ip_field; + + if (!field) { + field = pevent_find_field(event, "buf"); + if (!field) { + do_warning("can't find buffer field for binary printk"); + return NULL; + } + ip_field = pevent_find_field(event, "ip"); + if (!ip_field) { + do_warning("can't find ip field for binary printk"); + return NULL; + } + pevent->bprint_buf_field = field; + pevent->bprint_ip_field = ip_field; + } + + ip = pevent_read_number(pevent, data + ip_field->offset, ip_field->size); + + /* + * The first arg is the IP pointer. + */ + args = alloc_arg(); + if (!args) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + return NULL; + } + arg = args; + arg->next = NULL; + next = &arg->next; + + arg->type = PRINT_ATOM; + + if (asprintf(&arg->atom.atom, "%lld", ip) < 0) + goto out_free; + + /* skip the first "%pf : " */ + for (ptr = fmt + 6, bptr = data + field->offset; + bptr < data + size && *ptr; ptr++) { + int ls = 0; + + if (*ptr == '%') { + process_again: + ptr++; + switch (*ptr) { + case '%': + break; + case 'l': + ls++; + goto process_again; + case 'L': + ls = 2; + goto process_again; + case '0' ... '9': + goto process_again; + case '.': + goto process_again; + case 'p': + ls = 1; + /* fall through */ + case 'd': + case 'u': + case 'x': + case 'i': + switch (ls) { + case 0: + vsize = 4; + break; + case 1: + vsize = pevent->long_size; + break; + case 2: + vsize = 8; + break; + default: + vsize = ls; /* ? */ + break; + } + /* fall through */ + case '*': + if (*ptr == '*') + vsize = 4; + + /* the pointers are always 4 bytes aligned */ + bptr = (void *)(((unsigned long)bptr + 3) & + ~3); + val = pevent_read_number(pevent, bptr, vsize); + bptr += vsize; + arg = alloc_arg(); + if (!arg) { + do_warning("%s(%d): not enough memory!", + __func__, __LINE__); + goto out_free; + } + arg->next = NULL; + arg->type = PRINT_ATOM; + if (asprintf(&arg->atom.atom, "%lld", val) < 0) { + free(arg); + goto out_free; + } + *next = arg; + next = &arg->next; + /* + * The '*' case means that an arg is used as the length. + * We need to continue to figure out for what. + */ + if (*ptr == '*') + goto process_again; + + break; + case 's': + arg = alloc_arg(); + if (!arg) { + do_warning("%s(%d): not enough memory!", + __func__, __LINE__); + goto out_free; + } + arg->next = NULL; + arg->type = PRINT_BSTRING; + arg->string.string = strdup(bptr); + if (!arg->string.string) + goto out_free; + bptr += strlen(bptr) + 1; + *next = arg; + next = &arg->next; + default: + break; + } + } + } + + return args; + +out_free: + free_args(args); + return NULL; +} + +static char * +get_bprint_format(void *data, int size __maybe_unused, + struct event_format *event) +{ + struct pevent *pevent = event->pevent; + unsigned long long addr; + struct format_field *field; + struct printk_map *printk; + char *format; + char *p; + + field = pevent->bprint_fmt_field; + + if (!field) { + field = pevent_find_field(event, "fmt"); + if (!field) { + do_warning("can't find format field for binary printk"); + return NULL; + } + pevent->bprint_fmt_field = field; + } + + addr = pevent_read_number(pevent, data + field->offset, field->size); + + printk = find_printk(pevent, addr); + if (!printk) { + if (asprintf(&format, "%%pf : (NO FORMAT FOUND at %llx)\n", addr) < 0) + return NULL; + return format; + } + + p = printk->printk; + /* Remove any quotes. */ + if (*p == '"') + p++; + if (asprintf(&format, "%s : %s", "%pf", p) < 0) + return NULL; + /* remove ending quotes and new line since we will add one too */ + p = format + strlen(format) - 1; + if (*p == '"') + *p = 0; + + p -= 2; + if (strcmp(p, "\\n") == 0) + *p = 0; + + return format; +} + +static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, + struct event_format *event, struct print_arg *arg) +{ + unsigned char *buf; + const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"; + + if (arg->type == PRINT_FUNC) { + process_defined_func(s, data, size, event, arg); + return; + } + + if (arg->type != PRINT_FIELD) { + trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", + arg->type); + return; + } + + if (mac == 'm') + fmt = "%.2x%.2x%.2x%.2x%.2x%.2x"; + if (!arg->field.field) { + arg->field.field = + pevent_find_any_field(event, arg->field.name); + if (!arg->field.field) { + do_warning("%s: field %s not found", + __func__, arg->field.name); + return; + } + } + if (arg->field.field->size != 6) { + trace_seq_printf(s, "INVALIDMAC"); + return; + } + buf = data + arg->field.field->offset; + trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); +} + +static int is_printable_array(char *p, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len && p[i]; i++) + if (!isprint(p[i])) + return 0; + return 1; +} + +static void print_event_fields(struct trace_seq *s, void *data, + int size __maybe_unused, + struct event_format *event) +{ + struct format_field *field; + unsigned long long val; + unsigned int offset, len, i; + + field = event->format.fields; + while (field) { + trace_seq_printf(s, " %s=", field->name); + if (field->flags & FIELD_IS_ARRAY) { + offset = field->offset; + len = field->size; + if (field->flags & FIELD_IS_DYNAMIC) { + val = pevent_read_number(event->pevent, data + offset, len); + offset = val; + len = offset >> 16; + offset &= 0xffff; + } + if (field->flags & FIELD_IS_STRING && + is_printable_array(data + offset, len)) { + trace_seq_printf(s, "%s", (char *)data + offset); + } else { + trace_seq_puts(s, "ARRAY["); + for (i = 0; i < len; i++) { + if (i) + trace_seq_puts(s, ", "); + trace_seq_printf(s, "%02x", + *((unsigned char *)data + offset + i)); + } + trace_seq_putc(s, ']'); + field->flags &= ~FIELD_IS_STRING; + } + } else { + val = pevent_read_number(event->pevent, data + field->offset, + field->size); + if (field->flags & FIELD_IS_POINTER) { + trace_seq_printf(s, "0x%llx", val); + } else if (field->flags & FIELD_IS_SIGNED) { + switch (field->size) { + case 4: + /* + * If field is long then print it in hex. + * A long usually stores pointers. + */ + if (field->flags & FIELD_IS_LONG) + trace_seq_printf(s, "0x%x", (int)val); + else + trace_seq_printf(s, "%d", (int)val); + break; + case 2: + trace_seq_printf(s, "%2d", (short)val); + break; + case 1: + trace_seq_printf(s, "%1d", (char)val); + break; + default: + trace_seq_printf(s, "%lld", val); + } + } else { + if (field->flags & FIELD_IS_LONG) + trace_seq_printf(s, "0x%llx", val); + else + trace_seq_printf(s, "%llu", val); + } + } + field = field->next; + } +} + +static void pretty_print(struct trace_seq *s, void *data, int size, struct event_format *event) +{ + struct pevent *pevent = event->pevent; + struct print_fmt *print_fmt = &event->print_fmt; + struct print_arg *arg = print_fmt->args; + struct print_arg *args = NULL; + const char *ptr = print_fmt->format; + unsigned long long val; + struct func_map *func; + const char *saveptr; + char *bprint_fmt = NULL; + char format[32]; + int show_func; + int len_as_arg; + int len_arg; + int len; + int ls; + + if (event->flags & EVENT_FL_FAILED) { + trace_seq_printf(s, "[FAILED TO PARSE]"); + print_event_fields(s, data, size, event); + return; + } + + if (event->flags & EVENT_FL_ISBPRINT) { + bprint_fmt = get_bprint_format(data, size, event); + args = make_bprint_args(bprint_fmt, data, size, event); + arg = args; + ptr = bprint_fmt; + } + + for (; *ptr; ptr++) { + ls = 0; + if (*ptr == '\\') { + ptr++; + switch (*ptr) { + case 'n': + trace_seq_putc(s, '\n'); + break; + case 't': + trace_seq_putc(s, '\t'); + break; + case 'r': + trace_seq_putc(s, '\r'); + break; + case '\\': + trace_seq_putc(s, '\\'); + break; + default: + trace_seq_putc(s, *ptr); + break; + } + + } else if (*ptr == '%') { + saveptr = ptr; + show_func = 0; + len_as_arg = 0; + cont_process: + ptr++; + switch (*ptr) { + case '%': + trace_seq_putc(s, '%'); + break; + case '#': + /* FIXME: need to handle properly */ + goto cont_process; + case 'h': + ls--; + goto cont_process; + case 'l': + ls++; + goto cont_process; + case 'L': + ls = 2; + goto cont_process; + case '*': + /* The argument is the length. */ + if (!arg) { + do_warning("no argument match"); + event->flags |= EVENT_FL_FAILED; + goto out_failed; + } + len_arg = eval_num_arg(data, size, event, arg); + len_as_arg = 1; + arg = arg->next; + goto cont_process; + case '.': + case 'z': + case 'Z': + case '0' ... '9': + goto cont_process; + case 'p': + if (pevent->long_size == 4) + ls = 1; + else + ls = 2; + + if (*(ptr+1) == 'F' || + *(ptr+1) == 'f') { + ptr++; + show_func = *ptr; + } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { + print_mac_arg(s, *(ptr+1), data, size, event, arg); + ptr++; + arg = arg->next; + break; + } + + /* fall through */ + case 'd': + case 'i': + case 'x': + case 'X': + case 'u': + if (!arg) { + do_warning("no argument match"); + event->flags |= EVENT_FL_FAILED; + goto out_failed; + } + + len = ((unsigned long)ptr + 1) - + (unsigned long)saveptr; + + /* should never happen */ + if (len > 31) { + do_warning("bad format!"); + event->flags |= EVENT_FL_FAILED; + len = 31; + } + + memcpy(format, saveptr, len); + format[len] = 0; + + val = eval_num_arg(data, size, event, arg); + arg = arg->next; + + if (show_func) { + func = find_func(pevent, val); + if (func) { + trace_seq_puts(s, func->func); + if (show_func == 'F') + trace_seq_printf(s, + "+0x%llx", + val - func->addr); + break; + } + } + if (pevent->long_size == 8 && ls && + sizeof(long) != 8) { + char *p; + + ls = 2; + /* make %l into %ll */ + p = strchr(format, 'l'); + if (p) + memmove(p+1, p, strlen(p)+1); + else if (strcmp(format, "%p") == 0) + strcpy(format, "0x%llx"); + } + switch (ls) { + case -2: + if (len_as_arg) + trace_seq_printf(s, format, len_arg, (char)val); + else + trace_seq_printf(s, format, (char)val); + break; + case -1: + if (len_as_arg) + trace_seq_printf(s, format, len_arg, (short)val); + else + trace_seq_printf(s, format, (short)val); + break; + case 0: + if (len_as_arg) + trace_seq_printf(s, format, len_arg, (int)val); + else + trace_seq_printf(s, format, (int)val); + break; + case 1: + if (len_as_arg) + trace_seq_printf(s, format, len_arg, (long)val); + else + trace_seq_printf(s, format, (long)val); + break; + case 2: + if (len_as_arg) + trace_seq_printf(s, format, len_arg, + (long long)val); + else + trace_seq_printf(s, format, (long long)val); + break; + default: + do_warning("bad count (%d)", ls); + event->flags |= EVENT_FL_FAILED; + } + break; + case 's': + if (!arg) { + do_warning("no matching argument"); + event->flags |= EVENT_FL_FAILED; + goto out_failed; + } + + len = ((unsigned long)ptr + 1) - + (unsigned long)saveptr; + + /* should never happen */ + if (len > 31) { + do_warning("bad format!"); + event->flags |= EVENT_FL_FAILED; + len = 31; + } + + memcpy(format, saveptr, len); + format[len] = 0; + if (!len_as_arg) + len_arg = -1; + print_str_arg(s, data, size, event, + format, len_arg, arg); + arg = arg->next; + break; + default: + trace_seq_printf(s, ">%c<", *ptr); + + } + } else + trace_seq_putc(s, *ptr); + } + + if (event->flags & EVENT_FL_FAILED) { +out_failed: + trace_seq_printf(s, "[FAILED TO PARSE]"); + } + + if (args) { + free_args(args); + free(bprint_fmt); + } +} + +/** + * pevent_data_lat_fmt - parse the data for the latency format + * @pevent: a handle to the pevent + * @s: the trace_seq to write to + * @record: the record to read from + * + * This parses out the Latency format (interrupts disabled, + * need rescheduling, in hard/soft interrupt, preempt count + * and lock depth) and places it into the trace_seq. + */ +void pevent_data_lat_fmt(struct pevent *pevent, + struct trace_seq *s, struct pevent_record *record) +{ + static int check_lock_depth = 1; + static int check_migrate_disable = 1; + static int lock_depth_exists; + static int migrate_disable_exists; + unsigned int lat_flags; + unsigned int pc; + int lock_depth; + int migrate_disable; + int hardirq; + int softirq; + void *data = record->data; + + lat_flags = parse_common_flags(pevent, data); + pc = parse_common_pc(pevent, data); + /* lock_depth may not always exist */ + if (lock_depth_exists) + lock_depth = parse_common_lock_depth(pevent, data); + else if (check_lock_depth) { + lock_depth = parse_common_lock_depth(pevent, data); + if (lock_depth < 0) + check_lock_depth = 0; + else + lock_depth_exists = 1; + } + + /* migrate_disable may not always exist */ + if (migrate_disable_exists) + migrate_disable = parse_common_migrate_disable(pevent, data); + else if (check_migrate_disable) { + migrate_disable = parse_common_migrate_disable(pevent, data); + if (migrate_disable < 0) + check_migrate_disable = 0; + else + migrate_disable_exists = 1; + } + + hardirq = lat_flags & TRACE_FLAG_HARDIRQ; + softirq = lat_flags & TRACE_FLAG_SOFTIRQ; + + trace_seq_printf(s, "%c%c%c", + (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : + (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? + 'X' : '.', + (lat_flags & TRACE_FLAG_NEED_RESCHED) ? + 'N' : '.', + (hardirq && softirq) ? 'H' : + hardirq ? 'h' : softirq ? 's' : '.'); + + if (pc) + trace_seq_printf(s, "%x", pc); + else + trace_seq_putc(s, '.'); + + if (migrate_disable_exists) { + if (migrate_disable < 0) + trace_seq_putc(s, '.'); + else + trace_seq_printf(s, "%d", migrate_disable); + } + + if (lock_depth_exists) { + if (lock_depth < 0) + trace_seq_putc(s, '.'); + else + trace_seq_printf(s, "%d", lock_depth); + } + + trace_seq_terminate(s); +} + +/** + * pevent_data_type - parse out the given event type + * @pevent: a handle to the pevent + * @rec: the record to read from + * + * This returns the event id from the @rec. + */ +int pevent_data_type(struct pevent *pevent, struct pevent_record *rec) +{ + return trace_parse_common_type(pevent, rec->data); +} + +/** + * pevent_data_event_from_type - find the event by a given type + * @pevent: a handle to the pevent + * @type: the type of the event. + * + * This returns the event form a given @type; + */ +struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type) +{ + return pevent_find_event(pevent, type); +} + +/** + * pevent_data_pid - parse the PID from raw data + * @pevent: a handle to the pevent + * @rec: the record to parse + * + * This returns the PID from a raw data. + */ +int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec) +{ + return parse_common_pid(pevent, rec->data); +} + +/** + * pevent_data_comm_from_pid - return the command line from PID + * @pevent: a handle to the pevent + * @pid: the PID of the task to search for + * + * This returns a pointer to the command line that has the given + * @pid. + */ +const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid) +{ + const char *comm; + + comm = find_cmdline(pevent, pid); + return comm; +} + +/** + * pevent_data_comm_from_pid - parse the data into the print format + * @s: the trace_seq to write to + * @event: the handle to the event + * @record: the record to read from + * + * This parses the raw @data using the given @event information and + * writes the print format into the trace_seq. + */ +void pevent_event_info(struct trace_seq *s, struct event_format *event, + struct pevent_record *record) +{ + int print_pretty = 1; + + if (event->pevent->print_raw) + print_event_fields(s, record->data, record->size, event); + else { + + if (event->handler) + print_pretty = event->handler(s, record, event, + event->context); + + if (print_pretty) + pretty_print(s, record->data, record->size, event); + } + + trace_seq_terminate(s); +} + +void pevent_print_event(struct pevent *pevent, struct trace_seq *s, + struct pevent_record *record) +{ + static const char *spaces = " "; /* 20 spaces */ + struct event_format *event; + unsigned long secs; + unsigned long usecs; + unsigned long nsecs; + const char *comm; + void *data = record->data; + int type; + int pid; + int len; + int p; + + secs = record->ts / NSECS_PER_SEC; + nsecs = record->ts - secs * NSECS_PER_SEC; + + if (record->size < 0) { + do_warning("ug! negative record size %d", record->size); + return; + } + + type = trace_parse_common_type(pevent, data); + + event = pevent_find_event(pevent, type); + if (!event) { + do_warning("ug! no event found for type %d", type); + return; + } + + pid = parse_common_pid(pevent, data); + comm = find_cmdline(pevent, pid); + + if (pevent->latency_format) { + trace_seq_printf(s, "%8.8s-%-5d %3d", + comm, pid, record->cpu); + pevent_data_lat_fmt(pevent, s, record); + } else + trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu); + + if (pevent->flags & PEVENT_NSEC_OUTPUT) { + usecs = nsecs; + p = 9; + } else { + usecs = (nsecs + 500) / NSECS_PER_USEC; + p = 6; + } + + trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name); + + /* Space out the event names evenly. */ + len = strlen(event->name); + if (len < 20) + trace_seq_printf(s, "%.*s", 20 - len, spaces); + + pevent_event_info(s, event, record); +} + +static int events_id_cmp(const void *a, const void *b) +{ + struct event_format * const * ea = a; + struct event_format * const * eb = b; + + if ((*ea)->id < (*eb)->id) + return -1; + + if ((*ea)->id > (*eb)->id) + return 1; + + return 0; +} + +static int events_name_cmp(const void *a, const void *b) +{ + struct event_format * const * ea = a; + struct event_format * const * eb = b; + int res; + + res = strcmp((*ea)->name, (*eb)->name); + if (res) + return res; + + res = strcmp((*ea)->system, (*eb)->system); + if (res) + return res; + + return events_id_cmp(a, b); +} + +static int events_system_cmp(const void *a, const void *b) +{ + struct event_format * const * ea = a; + struct event_format * const * eb = b; + int res; + + res = strcmp((*ea)->system, (*eb)->system); + if (res) + return res; + + res = strcmp((*ea)->name, (*eb)->name); + if (res) + return res; + + return events_id_cmp(a, b); +} + +struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type sort_type) +{ + struct event_format **events; + int (*sort)(const void *a, const void *b); + + events = pevent->sort_events; + + if (events && pevent->last_type == sort_type) + return events; + + if (!events) { + events = malloc(sizeof(*events) * (pevent->nr_events + 1)); + if (!events) + return NULL; + + memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events); + events[pevent->nr_events] = NULL; + + pevent->sort_events = events; + + /* the internal events are sorted by id */ + if (sort_type == EVENT_SORT_ID) { + pevent->last_type = sort_type; + return events; + } + } + + switch (sort_type) { + case EVENT_SORT_ID: + sort = events_id_cmp; + break; + case EVENT_SORT_NAME: + sort = events_name_cmp; + break; + case EVENT_SORT_SYSTEM: + sort = events_system_cmp; + break; + default: + return events; + } + + qsort(events, pevent->nr_events, sizeof(*events), sort); + pevent->last_type = sort_type; + + return events; +} + +static struct format_field ** +get_event_fields(const char *type, const char *name, + int count, struct format_field *list) +{ + struct format_field **fields; + struct format_field *field; + int i = 0; + + fields = malloc(sizeof(*fields) * (count + 1)); + if (!fields) + return NULL; + + for (field = list; field; field = field->next) { + fields[i++] = field; + if (i == count + 1) { + do_warning("event %s has more %s fields than specified", + name, type); + i--; + break; + } + } + + if (i != count) + do_warning("event %s has less %s fields than specified", + name, type); + + fields[i] = NULL; + + return fields; +} + +/** + * pevent_event_common_fields - return a list of common fields for an event + * @event: the event to return the common fields of. + * + * Returns an allocated array of fields. The last item in the array is NULL. + * The array must be freed with free(). + */ +struct format_field **pevent_event_common_fields(struct event_format *event) +{ + return get_event_fields("common", event->name, + event->format.nr_common, + event->format.common_fields); +} + +/** + * pevent_event_fields - return a list of event specific fields for an event + * @event: the event to return the fields of. + * + * Returns an allocated array of fields. The last item in the array is NULL. + * The array must be freed with free(). + */ +struct format_field **pevent_event_fields(struct event_format *event) +{ + return get_event_fields("event", event->name, + event->format.nr_fields, + event->format.fields); +} + +static void print_fields(struct trace_seq *s, struct print_flag_sym *field) +{ + trace_seq_printf(s, "{ %s, %s }", field->value, field->str); + if (field->next) { + trace_seq_puts(s, ", "); + print_fields(s, field->next); + } +} + +/* for debugging */ +static void print_args(struct print_arg *args) +{ + int print_paren = 1; + struct trace_seq s; + + switch (args->type) { + case PRINT_NULL: + printf("null"); + break; + case PRINT_ATOM: + printf("%s", args->atom.atom); + break; + case PRINT_FIELD: + printf("REC->%s", args->field.name); + break; + case PRINT_FLAGS: + printf("__print_flags("); + print_args(args->flags.field); + printf(", %s, ", args->flags.delim); + trace_seq_init(&s); + print_fields(&s, args->flags.flags); + trace_seq_do_printf(&s); + trace_seq_destroy(&s); + printf(")"); + break; + case PRINT_SYMBOL: + printf("__print_symbolic("); + print_args(args->symbol.field); + printf(", "); + trace_seq_init(&s); + print_fields(&s, args->symbol.symbols); + trace_seq_do_printf(&s); + trace_seq_destroy(&s); + printf(")"); + break; + case PRINT_HEX: + printf("__print_hex("); + print_args(args->hex.field); + printf(", "); + print_args(args->hex.size); + printf(")"); + break; + case PRINT_STRING: + case PRINT_BSTRING: + printf("__get_str(%s)", args->string.string); + break; + case PRINT_TYPE: + printf("(%s)", args->typecast.type); + print_args(args->typecast.item); + break; + case PRINT_OP: + if (strcmp(args->op.op, ":") == 0) + print_paren = 0; + if (print_paren) + printf("("); + print_args(args->op.left); + printf(" %s ", args->op.op); + print_args(args->op.right); + if (print_paren) + printf(")"); + break; + default: + /* we should warn... */ + return; + } + if (args->next) { + printf("\n"); + print_args(args->next); + } +} + +static void parse_header_field(const char *field, + int *offset, int *size, int mandatory) +{ + unsigned long long save_input_buf_ptr; + unsigned long long save_input_buf_siz; + char *token; + int type; + + save_input_buf_ptr = input_buf_ptr; + save_input_buf_siz = input_buf_siz; + + if (read_expected(EVENT_ITEM, "field") < 0) + return; + if (read_expected(EVENT_OP, ":") < 0) + return; + + /* type */ + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto fail; + free_token(token); + + /* + * If this is not a mandatory field, then test it first. + */ + if (mandatory) { + if (read_expected(EVENT_ITEM, field) < 0) + return; + } else { + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto fail; + if (strcmp(token, field) != 0) + goto discard; + free_token(token); + } + + if (read_expected(EVENT_OP, ";") < 0) + return; + if (read_expected(EVENT_ITEM, "offset") < 0) + return; + if (read_expected(EVENT_OP, ":") < 0) + return; + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto fail; + *offset = atoi(token); + free_token(token); + if (read_expected(EVENT_OP, ";") < 0) + return; + if (read_expected(EVENT_ITEM, "size") < 0) + return; + if (read_expected(EVENT_OP, ":") < 0) + return; + if (read_expect_type(EVENT_ITEM, &token) < 0) + goto fail; + *size = atoi(token); + free_token(token); + if (read_expected(EVENT_OP, ";") < 0) + return; + type = read_token(&token); + if (type != EVENT_NEWLINE) { + /* newer versions of the kernel have a "signed" type */ + if (type != EVENT_ITEM) + goto fail; + + if (strcmp(token, "signed") != 0) + goto fail; + + free_token(token); + + if (read_expected(EVENT_OP, ":") < 0) + return; + + if (read_expect_type(EVENT_ITEM, &token)) + goto fail; + + free_token(token); + if (read_expected(EVENT_OP, ";") < 0) + return; + + if (read_expect_type(EVENT_NEWLINE, &token)) + goto fail; + } + fail: + free_token(token); + return; + + discard: + input_buf_ptr = save_input_buf_ptr; + input_buf_siz = save_input_buf_siz; + *offset = 0; + *size = 0; + free_token(token); +} + +/** + * pevent_parse_header_page - parse the data stored in the header page + * @pevent: the handle to the pevent + * @buf: the buffer storing the header page format string + * @size: the size of @buf + * @long_size: the long size to use if there is no header + * + * This parses the header page format for information on the + * ring buffer used. The @buf should be copied from + * + * /sys/kernel/debug/tracing/events/header_page + */ +int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size, + int long_size) +{ + int ignore; + + if (!size) { + /* + * Old kernels did not have header page info. + * Sorry but we just use what we find here in user space. + */ + pevent->header_page_ts_size = sizeof(long long); + pevent->header_page_size_size = long_size; + pevent->header_page_data_offset = sizeof(long long) + long_size; + pevent->old_format = 1; + return -1; + } + init_input_buf(buf, size); + + parse_header_field("timestamp", &pevent->header_page_ts_offset, + &pevent->header_page_ts_size, 1); + parse_header_field("commit", &pevent->header_page_size_offset, + &pevent->header_page_size_size, 1); + parse_header_field("overwrite", &pevent->header_page_overwrite, + &ignore, 0); + parse_header_field("data", &pevent->header_page_data_offset, + &pevent->header_page_data_size, 1); + + return 0; +} + +static int event_matches(struct event_format *event, + int id, const char *sys_name, + const char *event_name) +{ + if (id >= 0 && id != event->id) + return 0; + + if (event_name && (strcmp(event_name, event->name) != 0)) + return 0; + + if (sys_name && (strcmp(sys_name, event->system) != 0)) + return 0; + + return 1; +} + +static void free_handler(struct event_handler *handle) +{ + free((void *)handle->sys_name); + free((void *)handle->event_name); + free(handle); +} + +static int find_event_handle(struct pevent *pevent, struct event_format *event) +{ + struct event_handler *handle, **next; + + for (next = &pevent->handlers; *next; + next = &(*next)->next) { + handle = *next; + if (event_matches(event, handle->id, + handle->sys_name, + handle->event_name)) + break; + } + + if (!(*next)) + return 0; + + pr_stat("overriding event (%d) %s:%s with new print handler", + event->id, event->system, event->name); + + event->handler = handle->func; + event->context = handle->context; + + *next = handle->next; + free_handler(handle); + + return 1; +} + +/** + * __pevent_parse_format - parse the event format + * @buf: the buffer storing the event format string + * @size: the size of @buf + * @sys: the system the event belongs to + * + * This parses the event format and creates an event structure + * to quickly parse raw data for a given event. + * + * These files currently come from: + * + * /sys/kernel/debug/tracing/events/.../.../format + */ +enum pevent_errno __pevent_parse_format(struct event_format **eventp, + struct pevent *pevent, const char *buf, + unsigned long size, const char *sys) +{ + struct event_format *event; + int ret; + + init_input_buf(buf, size); + + *eventp = event = alloc_event(); + if (!event) + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + + event->name = event_read_name(); + if (!event->name) { + /* Bad event? */ + ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; + goto event_alloc_failed; + } + + if (strcmp(sys, "ftrace") == 0) { + event->flags |= EVENT_FL_ISFTRACE; + + if (strcmp(event->name, "bprint") == 0) + event->flags |= EVENT_FL_ISBPRINT; + } + + event->id = event_read_id(); + if (event->id < 0) { + ret = PEVENT_ERRNO__READ_ID_FAILED; + /* + * This isn't an allocation error actually. + * But as the ID is critical, just bail out. + */ + goto event_alloc_failed; + } + + event->system = strdup(sys); + if (!event->system) { + ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; + goto event_alloc_failed; + } + + /* Add pevent to event so that it can be referenced */ + event->pevent = pevent; + + ret = event_read_format(event); + if (ret < 0) { + ret = PEVENT_ERRNO__READ_FORMAT_FAILED; + goto event_parse_failed; + } + + /* + * If the event has an override, don't print warnings if the event + * print format fails to parse. + */ + if (pevent && find_event_handle(pevent, event)) + show_warning = 0; + + ret = event_read_print(event); + show_warning = 1; + + if (ret < 0) { + ret = PEVENT_ERRNO__READ_PRINT_FAILED; + goto event_parse_failed; + } + + if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { + struct format_field *field; + struct print_arg *arg, **list; + + /* old ftrace had no args */ + list = &event->print_fmt.args; + for (field = event->format.fields; field; field = field->next) { + arg = alloc_arg(); + if (!arg) { + event->flags |= EVENT_FL_FAILED; + return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; + } + arg->type = PRINT_FIELD; + arg->field.name = strdup(field->name); + if (!arg->field.name) { + event->flags |= EVENT_FL_FAILED; + free_arg(arg); + return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; + } + arg->field.field = field; + *list = arg; + list = &arg->next; + } + return 0; + } + + return 0; + + event_parse_failed: + event->flags |= EVENT_FL_FAILED; + return ret; + + event_alloc_failed: + free(event->system); + free(event->name); + free(event); + *eventp = NULL; + return ret; +} + +/** + * pevent_parse_format - parse the event format + * @buf: the buffer storing the event format string + * @size: the size of @buf + * @sys: the system the event belongs to + * + * This parses the event format and creates an event structure + * to quickly parse raw data for a given event. + * + * These files currently come from: + * + * /sys/kernel/debug/tracing/events/.../.../format + */ +enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf, + unsigned long size, const char *sys) +{ + return __pevent_parse_format(eventp, NULL, buf, size, sys); +} + +/** + * pevent_parse_event - parse the event format + * @pevent: the handle to the pevent + * @buf: the buffer storing the event format string + * @size: the size of @buf + * @sys: the system the event belongs to + * + * This parses the event format and creates an event structure + * to quickly parse raw data for a given event. + * + * These files currently come from: + * + * /sys/kernel/debug/tracing/events/.../.../format + */ +enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, + unsigned long size, const char *sys) +{ + struct event_format *event = NULL; + int ret = __pevent_parse_format(&event, pevent, buf, size, sys); + + if (event == NULL) + return ret; + + if (add_event(pevent, event)) { + ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; + goto event_add_failed; + } + +#define PRINT_ARGS 0 + if (PRINT_ARGS && event->print_fmt.args) + print_args(event->print_fmt.args); + + return 0; + +event_add_failed: + pevent_free_format(event); + return ret; +} + +#undef _PE +#define _PE(code, str) str +static const char * const pevent_error_str[] = { + PEVENT_ERRORS +}; +#undef _PE + +int pevent_strerror(struct pevent *pevent __maybe_unused, + enum pevent_errno errnum, char *buf, size_t buflen) +{ + int idx; + const char *msg; + + if (errnum >= 0) { +#if defined(__GLIBC__) + msg = strerror_r(errnum, buf, buflen); + if (msg != buf) { + size_t len = strlen(msg); + memcpy(buf, msg, min(buflen - 1, len)); + *(buf + min(buflen - 1, len)) = '\0'; + } +#else + if (strerror_r(errnum, buf, buflen)) + snprintf(buf, buflen, "errnum %i", errnum); +#endif + return 0; + } + + if (errnum <= __PEVENT_ERRNO__START || + errnum >= __PEVENT_ERRNO__END) + return -1; + + idx = errnum - __PEVENT_ERRNO__START - 1; + msg = pevent_error_str[idx]; + + switch (errnum) { + case PEVENT_ERRNO__MEM_ALLOC_FAILED: + case PEVENT_ERRNO__PARSE_EVENT_FAILED: + case PEVENT_ERRNO__READ_ID_FAILED: + case PEVENT_ERRNO__READ_FORMAT_FAILED: + case PEVENT_ERRNO__READ_PRINT_FAILED: + case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED: + case PEVENT_ERRNO__INVALID_ARG_TYPE: + snprintf(buf, buflen, "%s", msg); + break; + + default: + /* cannot reach here */ + break; + } + + return 0; +} + +int get_field_val(struct trace_seq *s, struct format_field *field, + const char *name, struct pevent_record *record, + unsigned long long *val, int err) +{ + if (!field) { + if (err) + trace_seq_printf(s, "<CAN'T FIND FIELD %s>", name); + return -1; + } + + if (pevent_read_number_field(field, record->data, val)) { + if (err) + trace_seq_printf(s, " %s=INVALID", name); + return -1; + } + + return 0; +} + +/** + * pevent_get_field_raw - return the raw pointer into the data field + * @s: The seq to print to on error + * @event: the event that the field is for + * @name: The name of the field + * @record: The record with the field name. + * @len: place to store the field length. + * @err: print default error if failed. + * + * Returns a pointer into record->data of the field and places + * the length of the field in @len. + * + * On failure, it returns NULL. + */ +void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, + const char *name, struct pevent_record *record, + int *len, int err) +{ + struct format_field *field; + void *data = record->data; + unsigned offset; + int dummy; + + if (!event) + return NULL; + + field = pevent_find_field(event, name); + + if (!field) { + if (err) + trace_seq_printf(s, "<CAN'T FIND FIELD %s>", name); + return NULL; + } + + /* Allow @len to be NULL */ + if (!len) + len = &dummy; + + offset = field->offset; + if (field->flags & FIELD_IS_DYNAMIC) { + offset = pevent_read_number(event->pevent, + data + offset, field->size); + *len = offset >> 16; + offset &= 0xffff; + } else + *len = field->size; + + return data + offset; +} + +/** + * pevent_get_field_val - find a field and return its value + * @s: The seq to print to on error + * @event: the event that the field is for + * @name: The name of the field + * @record: The record with the field name. + * @val: place to store the value of the field. + * @err: print default error if failed. + * + * Returns 0 on success -1 on field not found. + */ +int pevent_get_field_val(struct trace_seq *s, struct event_format *event, + const char *name, struct pevent_record *record, + unsigned long long *val, int err) +{ + struct format_field *field; + + if (!event) + return -1; + + field = pevent_find_field(event, name); + + return get_field_val(s, field, name, record, val, err); +} + +/** + * pevent_get_common_field_val - find a common field and return its value + * @s: The seq to print to on error + * @event: the event that the field is for + * @name: The name of the field + * @record: The record with the field name. + * @val: place to store the value of the field. + * @err: print default error if failed. + * + * Returns 0 on success -1 on field not found. + */ +int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event, + const char *name, struct pevent_record *record, + unsigned long long *val, int err) +{ + struct format_field *field; + + if (!event) + return -1; + + field = pevent_find_common_field(event, name); + + return get_field_val(s, field, name, record, val, err); +} + +/** + * pevent_get_any_field_val - find a any field and return its value + * @s: The seq to print to on error + * @event: the event that the field is for + * @name: The name of the field + * @record: The record with the field name. + * @val: place to store the value of the field. + * @err: print default error if failed. + * + * Returns 0 on success -1 on field not found. + */ +int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event, + const char *name, struct pevent_record *record, + unsigned long long *val, int err) +{ + struct format_field *field; + + if (!event) + return -1; + + field = pevent_find_any_field(event, name); + + return get_field_val(s, field, name, record, val, err); +} + +/** + * pevent_print_num_field - print a field and a format + * @s: The seq to print to + * @fmt: The printf format to print the field with. + * @event: the event that the field is for + * @name: The name of the field + * @record: The record with the field name. + * @err: print default error if failed. + * + * Returns: 0 on success, -1 field not found, or 1 if buffer is full. + */ +int pevent_print_num_field(struct trace_seq *s, const char *fmt, + struct event_format *event, const char *name, + struct pevent_record *record, int err) +{ + struct format_field *field = pevent_find_field(event, name); + unsigned long long val; + + if (!field) + goto failed; + + if (pevent_read_number_field(field, record->data, &val)) + goto failed; + + return trace_seq_printf(s, fmt, val); + + failed: + if (err) + trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); + return -1; +} + +static void free_func_handle(struct pevent_function_handler *func) +{ + struct pevent_func_params *params; + + free(func->name); + + while (func->params) { + params = func->params; + func->params = params->next; + free(params); + } + + free(func); +} + +/** + * pevent_register_print_function - register a helper function + * @pevent: the handle to the pevent + * @func: the function to process the helper function + * @ret_type: the return type of the helper function + * @name: the name of the helper function + * @parameters: A list of enum pevent_func_arg_type + * + * Some events may have helper functions in the print format arguments. + * This allows a plugin to dynamically create a way to process one + * of these functions. + * + * The @parameters is a variable list of pevent_func_arg_type enums that + * must end with PEVENT_FUNC_ARG_VOID. + */ +int pevent_register_print_function(struct pevent *pevent, + pevent_func_handler func, + enum pevent_func_arg_type ret_type, + char *name, ...) +{ + struct pevent_function_handler *func_handle; + struct pevent_func_params **next_param; + struct pevent_func_params *param; + enum pevent_func_arg_type type; + va_list ap; + int ret; + + func_handle = find_func_handler(pevent, name); + if (func_handle) { + /* + * This is most like caused by the users own + * plugins updating the function. This overrides the + * system defaults. + */ + pr_stat("override of function helper '%s'", name); + remove_func_handler(pevent, name); + } + + func_handle = calloc(1, sizeof(*func_handle)); + if (!func_handle) { + do_warning("Failed to allocate function handler"); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } + + func_handle->ret_type = ret_type; + func_handle->name = strdup(name); + func_handle->func = func; + if (!func_handle->name) { + do_warning("Failed to allocate function name"); + free(func_handle); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } + + next_param = &(func_handle->params); + va_start(ap, name); + for (;;) { + type = va_arg(ap, enum pevent_func_arg_type); + if (type == PEVENT_FUNC_ARG_VOID) + break; + + if (type >= PEVENT_FUNC_ARG_MAX_TYPES) { + do_warning("Invalid argument type %d", type); + ret = PEVENT_ERRNO__INVALID_ARG_TYPE; + goto out_free; + } + + param = malloc(sizeof(*param)); + if (!param) { + do_warning("Failed to allocate function param"); + ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; + goto out_free; + } + param->type = type; + param->next = NULL; + + *next_param = param; + next_param = &(param->next); + + func_handle->nr_args++; + } + va_end(ap); + + func_handle->next = pevent->func_handlers; + pevent->func_handlers = func_handle; + + return 0; + out_free: + va_end(ap); + free_func_handle(func_handle); + return ret; +} + +/** + * pevent_register_event_handler - register a way to parse an event + * @pevent: the handle to the pevent + * @id: the id of the event to register + * @sys_name: the system name the event belongs to + * @event_name: the name of the event + * @func: the function to call to parse the event information + * @context: the data to be passed to @func + * + * This function allows a developer to override the parsing of + * a given event. If for some reason the default print format + * is not sufficient, this function will register a function + * for an event to be used to parse the data instead. + * + * If @id is >= 0, then it is used to find the event. + * else @sys_name and @event_name are used. + */ +int pevent_register_event_handler(struct pevent *pevent, int id, + const char *sys_name, const char *event_name, + pevent_event_handler_func func, void *context) +{ + struct event_format *event; + struct event_handler *handle; + + if (id >= 0) { + /* search by id */ + event = pevent_find_event(pevent, id); + if (!event) + goto not_found; + if (event_name && (strcmp(event_name, event->name) != 0)) + goto not_found; + if (sys_name && (strcmp(sys_name, event->system) != 0)) + goto not_found; + } else { + event = pevent_find_event_by_name(pevent, sys_name, event_name); + if (!event) + goto not_found; + } + + pr_stat("overriding event (%d) %s:%s with new print handler", + event->id, event->system, event->name); + + event->handler = func; + event->context = context; + return 0; + + not_found: + /* Save for later use. */ + handle = calloc(1, sizeof(*handle)); + if (!handle) { + do_warning("Failed to allocate event handler"); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } + + handle->id = id; + if (event_name) + handle->event_name = strdup(event_name); + if (sys_name) + handle->sys_name = strdup(sys_name); + + if ((event_name && !handle->event_name) || + (sys_name && !handle->sys_name)) { + do_warning("Failed to allocate event/sys name"); + free((void *)handle->event_name); + free((void *)handle->sys_name); + free(handle); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } + + handle->func = func; + handle->next = pevent->handlers; + pevent->handlers = handle; + handle->context = context; + + return -1; +} + +/** + * pevent_alloc - create a pevent handle + */ +struct pevent *pevent_alloc(void) +{ + struct pevent *pevent = calloc(1, sizeof(*pevent)); + + if (pevent) + pevent->ref_count = 1; + + return pevent; +} + +void pevent_ref(struct pevent *pevent) +{ + pevent->ref_count++; +} + +static void free_format_fields(struct format_field *field) +{ + struct format_field *next; + + while (field) { + next = field->next; + free(field->type); + free(field->name); + free(field); + field = next; + } +} + +static void free_formats(struct format *format) +{ + free_format_fields(format->common_fields); + free_format_fields(format->fields); +} + +void pevent_free_format(struct event_format *event) +{ + free(event->name); + free(event->system); + + free_formats(&event->format); + + free(event->print_fmt.format); + free_args(event->print_fmt.args); + + free(event); +} + +/** + * pevent_free - free a pevent handle + * @pevent: the pevent handle to free + */ +void pevent_free(struct pevent *pevent) +{ + struct cmdline_list *cmdlist, *cmdnext; + struct func_list *funclist, *funcnext; + struct printk_list *printklist, *printknext; + struct pevent_function_handler *func_handler; + struct event_handler *handle; + int i; + + if (!pevent) + return; + + cmdlist = pevent->cmdlist; + funclist = pevent->funclist; + printklist = pevent->printklist; + + pevent->ref_count--; + if (pevent->ref_count) + return; + + if (pevent->cmdlines) { + for (i = 0; i < pevent->cmdline_count; i++) + free(pevent->cmdlines[i].comm); + free(pevent->cmdlines); + } + + while (cmdlist) { + cmdnext = cmdlist->next; + free(cmdlist->comm); + free(cmdlist); + cmdlist = cmdnext; + } + + if (pevent->func_map) { + for (i = 0; i < (int)pevent->func_count; i++) { + free(pevent->func_map[i].func); + free(pevent->func_map[i].mod); + } + free(pevent->func_map); + } + + while (funclist) { + funcnext = funclist->next; + free(funclist->func); + free(funclist->mod); + free(funclist); + funclist = funcnext; + } + + while (pevent->func_handlers) { + func_handler = pevent->func_handlers; + pevent->func_handlers = func_handler->next; + free_func_handle(func_handler); + } + + if (pevent->printk_map) { + for (i = 0; i < (int)pevent->printk_count; i++) + free(pevent->printk_map[i].printk); + free(pevent->printk_map); + } + + while (printklist) { + printknext = printklist->next; + free(printklist->printk); + free(printklist); + printklist = printknext; + } + + for (i = 0; i < pevent->nr_events; i++) + pevent_free_format(pevent->events[i]); + + while (pevent->handlers) { + handle = pevent->handlers; + pevent->handlers = handle->next; + free_handler(handle); + } + + free(pevent->events); + free(pevent->sort_events); + + free(pevent); +} + +void pevent_unref(struct pevent *pevent) +{ + pevent_free(pevent); +} diff --git a/traceevent/event-parse.h b/traceevent/event-parse.h new file mode 100644 index 0000000..c37b202 --- /dev/null +++ b/traceevent/event-parse.h @@ -0,0 +1,857 @@ +/* + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#ifndef _PARSE_EVENTS_H +#define _PARSE_EVENTS_H + +#include <stdarg.h> +#include <regex.h> + +#ifndef __maybe_unused +#define __maybe_unused __attribute__((unused)) +#endif + +/* ----------------------- trace_seq ----------------------- */ + + +#ifndef TRACE_SEQ_BUF_SIZE +#define TRACE_SEQ_BUF_SIZE 4096 +#endif + +#ifndef DEBUG_RECORD +#define DEBUG_RECORD 0 +#endif + +struct pevent_record { + unsigned long long ts; + unsigned long long offset; + long long missed_events; /* buffer dropped events before */ + int record_size; /* size of binary record */ + int size; /* size of data */ + void *data; + int cpu; + int ref_count; + int locked; /* Do not free, even if ref_count is zero */ + void *priv; +#if DEBUG_RECORD + struct pevent_record *prev; + struct pevent_record *next; + long alloc_addr; +#endif +}; + +/* + * Trace sequences are used to allow a function to call several other functions + * to create a string of data to use (up to a max of PAGE_SIZE). + */ + +struct trace_seq { + char *buffer; + unsigned int buffer_size; + unsigned int len; + unsigned int readpos; +}; + +void trace_seq_init(struct trace_seq *s); +void trace_seq_reset(struct trace_seq *s); +void trace_seq_destroy(struct trace_seq *s); + +extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); +extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) + __attribute__ ((format (printf, 2, 0))); + +extern int trace_seq_puts(struct trace_seq *s, const char *str); +extern int trace_seq_putc(struct trace_seq *s, unsigned char c); + +extern void trace_seq_terminate(struct trace_seq *s); + +extern int trace_seq_do_printf(struct trace_seq *s); + + +/* ----------------------- pevent ----------------------- */ + +struct pevent; +struct event_format; + +typedef int (*pevent_event_handler_func)(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, + void *context); + +typedef int (*pevent_plugin_load_func)(struct pevent *pevent); +typedef int (*pevent_plugin_unload_func)(void); + +struct plugin_option { + struct plugin_option *next; + void *handle; + char *file; + char *name; + char *plugin_alias; + char *description; + char *value; + void *priv; + int set; +}; + +/* + * Plugin hooks that can be called: + * + * PEVENT_PLUGIN_LOADER: (required) + * The function name to initialized the plugin. + * + * int PEVENT_PLUGIN_LOADER(struct pevent *pevent) + * + * PEVENT_PLUGIN_UNLOADER: (optional) + * The function called just before unloading + * + * int PEVENT_PLUGIN_UNLOADER(void) + * + * PEVENT_PLUGIN_OPTIONS: (optional) + * Plugin options that can be set before loading + * + * struct plugin_option PEVENT_PLUGIN_OPTIONS[] = { + * { + * .name = "option-name", + * .plugin_alias = "overide-file-name", (optional) + * .description = "description of option to show users", + * }, + * { + * .name = NULL, + * }, + * }; + * + * Array must end with .name = NULL; + * + * + * .plugin_alias is used to give a shorter name to access + * the vairable. Useful if a plugin handles more than one event. + * + * PEVENT_PLUGIN_ALIAS: (optional) + * The name to use for finding options (uses filename if not defined) + */ +#define PEVENT_PLUGIN_LOADER pevent_plugin_loader +#define PEVENT_PLUGIN_UNLOADER pevent_plugin_unloader +#define PEVENT_PLUGIN_OPTIONS pevent_plugin_options +#define PEVENT_PLUGIN_ALIAS pevent_plugin_alias +#define _MAKE_STR(x) #x +#define MAKE_STR(x) _MAKE_STR(x) +#define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(PEVENT_PLUGIN_LOADER) +#define PEVENT_PLUGIN_UNLOADER_NAME MAKE_STR(PEVENT_PLUGIN_UNLOADER) +#define PEVENT_PLUGIN_OPTIONS_NAME MAKE_STR(PEVENT_PLUGIN_OPTIONS) +#define PEVENT_PLUGIN_ALIAS_NAME MAKE_STR(PEVENT_PLUGIN_ALIAS) + +#define NSECS_PER_SEC 1000000000ULL +#define NSECS_PER_USEC 1000ULL + +enum format_flags { + FIELD_IS_ARRAY = 1, + FIELD_IS_POINTER = 2, + FIELD_IS_SIGNED = 4, + FIELD_IS_STRING = 8, + FIELD_IS_DYNAMIC = 16, + FIELD_IS_LONG = 32, + FIELD_IS_FLAG = 64, + FIELD_IS_SYMBOLIC = 128, +}; + +struct format_field { + struct format_field *next; + struct event_format *event; + char *type; + char *name; + int offset; + int size; + unsigned int arraylen; + unsigned int elementsize; + unsigned long flags; +}; + +struct format { + int nr_common; + int nr_fields; + struct format_field *common_fields; + struct format_field *fields; +}; + +struct print_arg_atom { + char *atom; +}; + +struct print_arg_string { + char *string; + int offset; +}; + +struct print_arg_field { + char *name; + struct format_field *field; +}; + +struct print_flag_sym { + struct print_flag_sym *next; + char *value; + char *str; +}; + +struct print_arg_typecast { + char *type; + struct print_arg *item; +}; + +struct print_arg_flags { + struct print_arg *field; + char *delim; + struct print_flag_sym *flags; +}; + +struct print_arg_symbol { + struct print_arg *field; + struct print_flag_sym *symbols; +}; + +struct print_arg_hex { + struct print_arg *field; + struct print_arg *size; +}; + +struct print_arg_dynarray { + struct format_field *field; + struct print_arg *index; +}; + +struct print_arg; + +struct print_arg_op { + char *op; + int prio; + struct print_arg *left; + struct print_arg *right; +}; + +struct pevent_function_handler; + +struct print_arg_func { + struct pevent_function_handler *func; + struct print_arg *args; +}; + +enum print_arg_type { + PRINT_NULL, + PRINT_ATOM, + PRINT_FIELD, + PRINT_FLAGS, + PRINT_SYMBOL, + PRINT_HEX, + PRINT_TYPE, + PRINT_STRING, + PRINT_BSTRING, + PRINT_DYNAMIC_ARRAY, + PRINT_OP, + PRINT_FUNC, +}; + +struct print_arg { + struct print_arg *next; + enum print_arg_type type; + union { + struct print_arg_atom atom; + struct print_arg_field field; + struct print_arg_typecast typecast; + struct print_arg_flags flags; + struct print_arg_symbol symbol; + struct print_arg_hex hex; + struct print_arg_func func; + struct print_arg_string string; + struct print_arg_op op; + struct print_arg_dynarray dynarray; + }; +}; + +struct print_fmt { + char *format; + struct print_arg *args; +}; + +struct event_format { + struct pevent *pevent; + char *name; + int id; + int flags; + struct format format; + struct print_fmt print_fmt; + char *system; + pevent_event_handler_func handler; + void *context; +}; + +enum { + EVENT_FL_ISFTRACE = 0x01, + EVENT_FL_ISPRINT = 0x02, + EVENT_FL_ISBPRINT = 0x04, + EVENT_FL_ISFUNCENT = 0x10, + EVENT_FL_ISFUNCRET = 0x20, + + EVENT_FL_FAILED = 0x80000000 +}; + +enum event_sort_type { + EVENT_SORT_ID, + EVENT_SORT_NAME, + EVENT_SORT_SYSTEM, +}; + +enum event_type { + EVENT_ERROR, + EVENT_NONE, + EVENT_SPACE, + EVENT_NEWLINE, + EVENT_OP, + EVENT_DELIM, + EVENT_ITEM, + EVENT_DQUOTE, + EVENT_SQUOTE, +}; + +typedef unsigned long long (*pevent_func_handler)(struct trace_seq *s, + unsigned long long *args); + +enum pevent_func_arg_type { + PEVENT_FUNC_ARG_VOID, + PEVENT_FUNC_ARG_INT, + PEVENT_FUNC_ARG_LONG, + PEVENT_FUNC_ARG_STRING, + PEVENT_FUNC_ARG_PTR, + PEVENT_FUNC_ARG_MAX_TYPES +}; + +enum pevent_flag { + PEVENT_NSEC_OUTPUT = 1, /* output in NSECS */ +}; + +#define PEVENT_ERRORS \ + _PE(MEM_ALLOC_FAILED, "failed to allocate memory"), \ + _PE(PARSE_EVENT_FAILED, "failed to parse event"), \ + _PE(READ_ID_FAILED, "failed to read event id"), \ + _PE(READ_FORMAT_FAILED, "failed to read event format"), \ + _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \ + _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\ + _PE(INVALID_ARG_TYPE, "invalid argument type") + +#undef _PE +#define _PE(__code, __str) PEVENT_ERRNO__ ## __code +enum pevent_errno { + PEVENT_ERRNO__SUCCESS = 0, + + /* + * Choose an arbitrary negative big number not to clash with standard + * errno since SUS requires the errno has distinct positive values. + * See 'Issue 6' in the link below. + * + * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html + */ + __PEVENT_ERRNO__START = -100000, + + PEVENT_ERRORS, + + __PEVENT_ERRNO__END, +}; +#undef _PE + +struct cmdline; +struct cmdline_list; +struct func_map; +struct func_list; +struct event_handler; + +struct pevent { + int ref_count; + + int header_page_ts_offset; + int header_page_ts_size; + int header_page_size_offset; + int header_page_size_size; + int header_page_data_offset; + int header_page_data_size; + int header_page_overwrite; + + int file_bigendian; + int host_bigendian; + + int latency_format; + + int old_format; + + int cpus; + int long_size; + int page_size; + + struct cmdline *cmdlines; + struct cmdline_list *cmdlist; + int cmdline_count; + + struct func_map *func_map; + struct func_list *funclist; + unsigned int func_count; + + struct printk_map *printk_map; + struct printk_list *printklist; + unsigned int printk_count; + + + struct event_format **events; + int nr_events; + struct event_format **sort_events; + enum event_sort_type last_type; + + int type_offset; + int type_size; + + int pid_offset; + int pid_size; + + int pc_offset; + int pc_size; + + int flags_offset; + int flags_size; + + int ld_offset; + int ld_size; + + int print_raw; + + int test_filters; + + int flags; + + struct format_field *bprint_ip_field; + struct format_field *bprint_fmt_field; + struct format_field *bprint_buf_field; + + struct event_handler *handlers; + struct pevent_function_handler *func_handlers; + + /* cache */ + struct event_format *last_event; +}; + +static inline void pevent_set_flag(struct pevent *pevent, int flag) +{ + pevent->flags |= flag; +} + +static inline unsigned short +__data2host2(struct pevent *pevent, unsigned short data) +{ + unsigned short swap; + + if (pevent->host_bigendian == pevent->file_bigendian) + return data; + + swap = ((data & 0xffULL) << 8) | + ((data & (0xffULL << 8)) >> 8); + + return swap; +} + +static inline unsigned int +__data2host4(struct pevent *pevent, unsigned int data) +{ + unsigned int swap; + + if (pevent->host_bigendian == pevent->file_bigendian) + return data; + + swap = ((data & 0xffULL) << 24) | + ((data & (0xffULL << 8)) << 8) | + ((data & (0xffULL << 16)) >> 8) | + ((data & (0xffULL << 24)) >> 24); + + return swap; +} + +static inline unsigned long long +__data2host8(struct pevent *pevent, unsigned long long data) +{ + unsigned long long swap; + + if (pevent->host_bigendian == pevent->file_bigendian) + return data; + + swap = ((data & 0xffULL) << 56) | + ((data & (0xffULL << 8)) << 40) | + ((data & (0xffULL << 16)) << 24) | + ((data & (0xffULL << 24)) << 8) | + ((data & (0xffULL << 32)) >> 8) | + ((data & (0xffULL << 40)) >> 24) | + ((data & (0xffULL << 48)) >> 40) | + ((data & (0xffULL << 56)) >> 56); + + return swap; +} + +#define data2host2(pevent, ptr) __data2host2(pevent, *(unsigned short *)(ptr)) +#define data2host4(pevent, ptr) __data2host4(pevent, *(unsigned int *)(ptr)) +#define data2host8(pevent, ptr) \ +({ \ + unsigned long long __val; \ + \ + memcpy(&__val, (ptr), sizeof(unsigned long long)); \ + __data2host8(pevent, __val); \ +}) + +/* taken from kernel/trace/trace.h */ +enum trace_flag_type { + TRACE_FLAG_IRQS_OFF = 0x01, + TRACE_FLAG_IRQS_NOSUPPORT = 0x02, + TRACE_FLAG_NEED_RESCHED = 0x04, + TRACE_FLAG_HARDIRQ = 0x08, + TRACE_FLAG_SOFTIRQ = 0x10, +}; + +int pevent_register_comm(struct pevent *pevent, const char *comm, int pid); +int pevent_register_function(struct pevent *pevent, char *name, + unsigned long long addr, char *mod); +int pevent_register_print_string(struct pevent *pevent, char *fmt, + unsigned long long addr); +int pevent_pid_is_registered(struct pevent *pevent, int pid); + +void pevent_print_event(struct pevent *pevent, struct trace_seq *s, + struct pevent_record *record); + +int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size, + int long_size); + +enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, + unsigned long size, const char *sys); +enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf, + unsigned long size, const char *sys); +void pevent_free_format(struct event_format *event); + +void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, + const char *name, struct pevent_record *record, + int *len, int err); + +int pevent_get_field_val(struct trace_seq *s, struct event_format *event, + const char *name, struct pevent_record *record, + unsigned long long *val, int err); +int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event, + const char *name, struct pevent_record *record, + unsigned long long *val, int err); +int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event, + const char *name, struct pevent_record *record, + unsigned long long *val, int err); + +int pevent_print_num_field(struct trace_seq *s, const char *fmt, + struct event_format *event, const char *name, + struct pevent_record *record, int err); + +int pevent_register_event_handler(struct pevent *pevent, int id, + const char *sys_name, const char *event_name, + pevent_event_handler_func func, void *context); +int pevent_register_print_function(struct pevent *pevent, + pevent_func_handler func, + enum pevent_func_arg_type ret_type, + char *name, ...); + +struct format_field *pevent_find_common_field(struct event_format *event, const char *name); +struct format_field *pevent_find_field(struct event_format *event, const char *name); +struct format_field *pevent_find_any_field(struct event_format *event, const char *name); + +const char *pevent_find_function(struct pevent *pevent, unsigned long long addr); +unsigned long long +pevent_find_function_address(struct pevent *pevent, unsigned long long addr); +unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size); +int pevent_read_number_field(struct format_field *field, const void *data, + unsigned long long *value); + +struct event_format *pevent_find_event(struct pevent *pevent, int id); + +struct event_format * +pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name); + +void pevent_data_lat_fmt(struct pevent *pevent, + struct trace_seq *s, struct pevent_record *record); +int pevent_data_type(struct pevent *pevent, struct pevent_record *rec); +struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type); +int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec); +const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid); +void pevent_event_info(struct trace_seq *s, struct event_format *event, + struct pevent_record *record); +int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, + char *buf, size_t buflen); + +struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type); +struct format_field **pevent_event_common_fields(struct event_format *event); +struct format_field **pevent_event_fields(struct event_format *event); + +static inline int pevent_get_cpus(struct pevent *pevent) +{ + return pevent->cpus; +} + +static inline void pevent_set_cpus(struct pevent *pevent, int cpus) +{ + pevent->cpus = cpus; +} + +static inline int pevent_get_long_size(struct pevent *pevent) +{ + return pevent->long_size; +} + +static inline void pevent_set_long_size(struct pevent *pevent, int long_size) +{ + pevent->long_size = long_size; +} + +static inline int pevent_get_page_size(struct pevent *pevent) +{ + return pevent->page_size; +} + +static inline void pevent_set_page_size(struct pevent *pevent, int _page_size) +{ + pevent->page_size = _page_size; +} + +static inline int pevent_is_file_bigendian(struct pevent *pevent) +{ + return pevent->file_bigendian; +} + +static inline void pevent_set_file_bigendian(struct pevent *pevent, int endian) +{ + pevent->file_bigendian = endian; +} + +static inline int pevent_is_host_bigendian(struct pevent *pevent) +{ + return pevent->host_bigendian; +} + +static inline void pevent_set_host_bigendian(struct pevent *pevent, int endian) +{ + pevent->host_bigendian = endian; +} + +static inline int pevent_is_latency_format(struct pevent *pevent) +{ + return pevent->latency_format; +} + +static inline void pevent_set_latency_format(struct pevent *pevent, int lat) +{ + pevent->latency_format = lat; +} + +struct pevent *pevent_alloc(void); +void pevent_free(struct pevent *pevent); +void pevent_ref(struct pevent *pevent); +void pevent_unref(struct pevent *pevent); + +/* access to the internal parser */ +void pevent_buffer_init(const char *buf, unsigned long long size); +enum event_type pevent_read_token(char **tok); +void pevent_free_token(char *token); +int pevent_peek_char(void); +const char *pevent_get_input_buf(void); +unsigned long long pevent_get_input_buf_ptr(void); + +/* for debugging */ +void pevent_print_funcs(struct pevent *pevent); +void pevent_print_printk(struct pevent *pevent); + +/* ----------------------- filtering ----------------------- */ + +enum filter_boolean_type { + FILTER_FALSE, + FILTER_TRUE, +}; + +enum filter_op_type { + FILTER_OP_AND = 1, + FILTER_OP_OR, + FILTER_OP_NOT, +}; + +enum filter_cmp_type { + FILTER_CMP_NONE, + FILTER_CMP_EQ, + FILTER_CMP_NE, + FILTER_CMP_GT, + FILTER_CMP_LT, + FILTER_CMP_GE, + FILTER_CMP_LE, + FILTER_CMP_MATCH, + FILTER_CMP_NOT_MATCH, + FILTER_CMP_REGEX, + FILTER_CMP_NOT_REGEX, +}; + +enum filter_exp_type { + FILTER_EXP_NONE, + FILTER_EXP_ADD, + FILTER_EXP_SUB, + FILTER_EXP_MUL, + FILTER_EXP_DIV, + FILTER_EXP_MOD, + FILTER_EXP_RSHIFT, + FILTER_EXP_LSHIFT, + FILTER_EXP_AND, + FILTER_EXP_OR, + FILTER_EXP_XOR, + FILTER_EXP_NOT, +}; + +enum filter_arg_type { + FILTER_ARG_NONE, + FILTER_ARG_BOOLEAN, + FILTER_ARG_VALUE, + FILTER_ARG_FIELD, + FILTER_ARG_EXP, + FILTER_ARG_OP, + FILTER_ARG_NUM, + FILTER_ARG_STR, +}; + +enum filter_value_type { + FILTER_NUMBER, + FILTER_STRING, + FILTER_CHAR +}; + +struct fliter_arg; + +struct filter_arg_boolean { + enum filter_boolean_type value; +}; + +struct filter_arg_field { + struct format_field *field; +}; + +struct filter_arg_value { + enum filter_value_type type; + union { + char *str; + unsigned long long val; + }; +}; + +struct filter_arg_op { + enum filter_op_type type; + struct filter_arg *left; + struct filter_arg *right; +}; + +struct filter_arg_exp { + enum filter_exp_type type; + struct filter_arg *left; + struct filter_arg *right; +}; + +struct filter_arg_num { + enum filter_cmp_type type; + struct filter_arg *left; + struct filter_arg *right; +}; + +struct filter_arg_str { + enum filter_cmp_type type; + struct format_field *field; + char *val; + char *buffer; + regex_t reg; +}; + +struct filter_arg { + enum filter_arg_type type; + union { + struct filter_arg_boolean boolean; + struct filter_arg_field field; + struct filter_arg_value value; + struct filter_arg_op op; + struct filter_arg_exp exp; + struct filter_arg_num num; + struct filter_arg_str str; + }; +}; + +struct filter_type { + int event_id; + struct event_format *event; + struct filter_arg *filter; +}; + +struct event_filter { + struct pevent *pevent; + int filters; + struct filter_type *event_filters; +}; + +struct event_filter *pevent_filter_alloc(struct pevent *pevent); + +#define FILTER_NONE -2 +#define FILTER_NOEXIST -1 +#define FILTER_MISS 0 +#define FILTER_MATCH 1 + +enum filter_trivial_type { + FILTER_TRIVIAL_FALSE, + FILTER_TRIVIAL_TRUE, + FILTER_TRIVIAL_BOTH, +}; + +int pevent_filter_add_filter_str(struct event_filter *filter, + const char *filter_str, + char **error_str); + + +int pevent_filter_match(struct event_filter *filter, + struct pevent_record *record); + +int pevent_event_filtered(struct event_filter *filter, + int event_id); + +void pevent_filter_reset(struct event_filter *filter); + +void pevent_filter_clear_trivial(struct event_filter *filter, + enum filter_trivial_type type); + +void pevent_filter_free(struct event_filter *filter); + +char *pevent_filter_make_string(struct event_filter *filter, int event_id); + +int pevent_filter_remove_event(struct event_filter *filter, + int event_id); + +int pevent_filter_event_has_trivial(struct event_filter *filter, + int event_id, + enum filter_trivial_type type); + +int pevent_filter_copy(struct event_filter *dest, struct event_filter *source); + +int pevent_update_trivial(struct event_filter *dest, struct event_filter *source, + enum filter_trivial_type type); + +int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2); + +#endif /* _PARSE_EVENTS_H */ diff --git a/traceevent/event-utils.h b/traceevent/event-utils.h new file mode 100644 index 0000000..e76c9ac --- /dev/null +++ b/traceevent/event-utils.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#ifndef __UTIL_H +#define __UTIL_H + +#include <ctype.h> + +/* Can be overridden */ +void die(const char *fmt, ...); +void *malloc_or_die(unsigned int size); +void warning(const char *fmt, ...); +void pr_stat(const char *fmt, ...); +void vpr_stat(const char *fmt, va_list ap); + +/* Always available */ +void __die(const char *fmt, ...); +void __warning(const char *fmt, ...); +void __pr_stat(const char *fmt, ...); + +void __vdie(const char *fmt, ...); +void __vwarning(const char *fmt, ...); +void __vpr_stat(const char *fmt, ...); + +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +static inline char *strim(char *string) +{ + char *ret; + + if (!string) + return NULL; + while (*string) { + if (!isspace(*string)) + break; + string++; + } + ret = string; + + string = ret + strlen(ret) - 1; + while (string > ret) { + if (!isspace(*string)) + break; + string--; + } + string[1] = 0; + + return ret; +} + +static inline int has_text(const char *text) +{ + if (!text) + return 0; + + while (*text) { + if (!isspace(*text)) + return 1; + text++; + } + + return 0; +} + +#endif diff --git a/traceevent/kbuffer-parse.c b/traceevent/kbuffer-parse.c new file mode 100644 index 0000000..8deddc9 --- /dev/null +++ b/traceevent/kbuffer-parse.c @@ -0,0 +1,732 @@ +/* + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "kbuffer.h" + +#define MISSING_EVENTS (1 << 31) +#define MISSING_STORED (1 << 30) + +#define COMMIT_MASK ((1 << 27) - 1) + +enum { + KBUFFER_FL_HOST_BIG_ENDIAN = (1<<0), + KBUFFER_FL_BIG_ENDIAN = (1<<1), + KBUFFER_FL_LONG_8 = (1<<2), + KBUFFER_FL_OLD_FORMAT = (1<<3), +}; + +#define ENDIAN_MASK (KBUFFER_FL_HOST_BIG_ENDIAN | KBUFFER_FL_BIG_ENDIAN) + +/** kbuffer + * @timestamp - timestamp of current event + * @lost_events - # of lost events between this subbuffer and previous + * @flags - special flags of the kbuffer + * @subbuffer - pointer to the sub-buffer page + * @data - pointer to the start of data on the sub-buffer page + * @index - index from @data to the @curr event data + * @curr - offset from @data to the start of current event + * (includes metadata) + * @next - offset from @data to the start of next event + * @size - The size of data on @data + * @start - The offset from @subbuffer where @data lives + * + * @read_4 - Function to read 4 raw bytes (may swap) + * @read_8 - Function to read 8 raw bytes (may swap) + * @read_long - Function to read a long word (4 or 8 bytes with needed swap) + */ +struct kbuffer { + unsigned long long timestamp; + long long lost_events; + unsigned long flags; + void *subbuffer; + void *data; + unsigned int index; + unsigned int curr; + unsigned int next; + unsigned int size; + unsigned int start; + + unsigned int (*read_4)(void *ptr); + unsigned long long (*read_8)(void *ptr); + unsigned long long (*read_long)(struct kbuffer *kbuf, void *ptr); + int (*next_event)(struct kbuffer *kbuf); +}; + +static void *zmalloc(size_t size) +{ + return calloc(1, size); +} + +static int host_is_bigendian(void) +{ + unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 }; + unsigned int *ptr; + + ptr = (unsigned int *)str; + return *ptr == 0x01020304; +} + +static int do_swap(struct kbuffer *kbuf) +{ + return ((kbuf->flags & KBUFFER_FL_HOST_BIG_ENDIAN) + kbuf->flags) & + ENDIAN_MASK; +} + +static unsigned long long __read_8(void *ptr) +{ + unsigned long long data = *(unsigned long long *)ptr; + + return data; +} + +static unsigned long long __read_8_sw(void *ptr) +{ + unsigned long long data = *(unsigned long long *)ptr; + unsigned long long swap; + + swap = ((data & 0xffULL) << 56) | + ((data & (0xffULL << 8)) << 40) | + ((data & (0xffULL << 16)) << 24) | + ((data & (0xffULL << 24)) << 8) | + ((data & (0xffULL << 32)) >> 8) | + ((data & (0xffULL << 40)) >> 24) | + ((data & (0xffULL << 48)) >> 40) | + ((data & (0xffULL << 56)) >> 56); + + return swap; +} + +static unsigned int __read_4(void *ptr) +{ + unsigned int data = *(unsigned int *)ptr; + + return data; +} + +static unsigned int __read_4_sw(void *ptr) +{ + unsigned int data = *(unsigned int *)ptr; + unsigned int swap; + + swap = ((data & 0xffULL) << 24) | + ((data & (0xffULL << 8)) << 8) | + ((data & (0xffULL << 16)) >> 8) | + ((data & (0xffULL << 24)) >> 24); + + return swap; +} + +static unsigned long long read_8(struct kbuffer *kbuf, void *ptr) +{ + return kbuf->read_8(ptr); +} + +static unsigned int read_4(struct kbuffer *kbuf, void *ptr) +{ + return kbuf->read_4(ptr); +} + +static unsigned long long __read_long_8(struct kbuffer *kbuf, void *ptr) +{ + return kbuf->read_8(ptr); +} + +static unsigned long long __read_long_4(struct kbuffer *kbuf, void *ptr) +{ + return kbuf->read_4(ptr); +} + +static unsigned long long read_long(struct kbuffer *kbuf, void *ptr) +{ + return kbuf->read_long(kbuf, ptr); +} + +static int calc_index(struct kbuffer *kbuf, void *ptr) +{ + return (unsigned long)ptr - (unsigned long)kbuf->data; +} + +static int __next_event(struct kbuffer *kbuf); + +/** + * kbuffer_alloc - allocat a new kbuffer + * @size; enum to denote size of word + * @endian: enum to denote endianness + * + * Allocates and returns a new kbuffer. + */ +struct kbuffer * +kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian) +{ + struct kbuffer *kbuf; + int flags = 0; + + switch (size) { + case KBUFFER_LSIZE_4: + break; + case KBUFFER_LSIZE_8: + flags |= KBUFFER_FL_LONG_8; + break; + default: + return NULL; + } + + switch (endian) { + case KBUFFER_ENDIAN_LITTLE: + break; + case KBUFFER_ENDIAN_BIG: + flags |= KBUFFER_FL_BIG_ENDIAN; + break; + default: + return NULL; + } + + kbuf = zmalloc(sizeof(*kbuf)); + if (!kbuf) + return NULL; + + kbuf->flags = flags; + + if (host_is_bigendian()) + kbuf->flags |= KBUFFER_FL_HOST_BIG_ENDIAN; + + if (do_swap(kbuf)) { + kbuf->read_8 = __read_8_sw; + kbuf->read_4 = __read_4_sw; + } else { + kbuf->read_8 = __read_8; + kbuf->read_4 = __read_4; + } + + if (kbuf->flags & KBUFFER_FL_LONG_8) + kbuf->read_long = __read_long_8; + else + kbuf->read_long = __read_long_4; + + /* May be changed by kbuffer_set_old_format() */ + kbuf->next_event = __next_event; + + return kbuf; +} + +/** kbuffer_free - free an allocated kbuffer + * @kbuf: The kbuffer to free + * + * Can take NULL as a parameter. + */ +void kbuffer_free(struct kbuffer *kbuf) +{ + free(kbuf); +} + +static unsigned int type4host(struct kbuffer *kbuf, + unsigned int type_len_ts) +{ + if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN) + return (type_len_ts >> 29) & 3; + else + return type_len_ts & 3; +} + +static unsigned int len4host(struct kbuffer *kbuf, + unsigned int type_len_ts) +{ + if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN) + return (type_len_ts >> 27) & 7; + else + return (type_len_ts >> 2) & 7; +} + +static unsigned int type_len4host(struct kbuffer *kbuf, + unsigned int type_len_ts) +{ + if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN) + return (type_len_ts >> 27) & ((1 << 5) - 1); + else + return type_len_ts & ((1 << 5) - 1); +} + +static unsigned int ts4host(struct kbuffer *kbuf, + unsigned int type_len_ts) +{ + if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN) + return type_len_ts & ((1 << 27) - 1); + else + return type_len_ts >> 5; +} + +/* + * Linux 2.6.30 and earlier (not much earlier) had a different + * ring buffer format. It should be obsolete, but we handle it anyway. + */ +enum old_ring_buffer_type { + OLD_RINGBUF_TYPE_PADDING, + OLD_RINGBUF_TYPE_TIME_EXTEND, + OLD_RINGBUF_TYPE_TIME_STAMP, + OLD_RINGBUF_TYPE_DATA, +}; + +static unsigned int old_update_pointers(struct kbuffer *kbuf) +{ + unsigned long long extend; + unsigned int type_len_ts; + unsigned int type; + unsigned int len; + unsigned int delta; + unsigned int length; + void *ptr = kbuf->data + kbuf->curr; + + type_len_ts = read_4(kbuf, ptr); + ptr += 4; + + type = type4host(kbuf, type_len_ts); + len = len4host(kbuf, type_len_ts); + delta = ts4host(kbuf, type_len_ts); + + switch (type) { + case OLD_RINGBUF_TYPE_PADDING: + kbuf->next = kbuf->size; + return 0; + + case OLD_RINGBUF_TYPE_TIME_EXTEND: + extend = read_4(kbuf, ptr); + extend <<= TS_SHIFT; + extend += delta; + delta = extend; + ptr += 4; + break; + + case OLD_RINGBUF_TYPE_TIME_STAMP: + /* should never happen! */ + kbuf->curr = kbuf->size; + kbuf->next = kbuf->size; + kbuf->index = kbuf->size; + return -1; + default: + if (len) + length = len * 4; + else { + length = read_4(kbuf, ptr); + length -= 4; + ptr += 4; + } + break; + } + + kbuf->timestamp += delta; + kbuf->index = calc_index(kbuf, ptr); + kbuf->next = kbuf->index + length; + + return type; +} + +static int __old_next_event(struct kbuffer *kbuf) +{ + int type; + + do { + kbuf->curr = kbuf->next; + if (kbuf->next >= kbuf->size) + return -1; + type = old_update_pointers(kbuf); + } while (type == OLD_RINGBUF_TYPE_TIME_EXTEND || type == OLD_RINGBUF_TYPE_PADDING); + + return 0; +} + +static unsigned int +translate_data(struct kbuffer *kbuf, void *data, void **rptr, + unsigned long long *delta, int *length) +{ + unsigned long long extend; + unsigned int type_len_ts; + unsigned int type_len; + + type_len_ts = read_4(kbuf, data); + data += 4; + + type_len = type_len4host(kbuf, type_len_ts); + *delta = ts4host(kbuf, type_len_ts); + + switch (type_len) { + case KBUFFER_TYPE_PADDING: + *length = read_4(kbuf, data); + data += *length; + break; + + case KBUFFER_TYPE_TIME_EXTEND: + extend = read_4(kbuf, data); + data += 4; + extend <<= TS_SHIFT; + extend += *delta; + *delta = extend; + *length = 0; + break; + + case KBUFFER_TYPE_TIME_STAMP: + data += 12; + *length = 0; + break; + case 0: + *length = read_4(kbuf, data) - 4; + *length = (*length + 3) & ~3; + data += 4; + break; + default: + *length = type_len * 4; + break; + } + + *rptr = data; + + return type_len; +} + +static unsigned int update_pointers(struct kbuffer *kbuf) +{ + unsigned long long delta; + unsigned int type_len; + int length; + void *ptr = kbuf->data + kbuf->curr; + + type_len = translate_data(kbuf, ptr, &ptr, &delta, &length); + + kbuf->timestamp += delta; + kbuf->index = calc_index(kbuf, ptr); + kbuf->next = kbuf->index + length; + + return type_len; +} + +/** + * kbuffer_translate_data - read raw data to get a record + * @swap: Set to 1 if bytes in words need to be swapped when read + * @data: The raw data to read + * @size: Address to store the size of the event data. + * + * Returns a pointer to the event data. To determine the entire + * record size (record metadata + data) just add the difference between + * @data and the returned value to @size. + */ +void *kbuffer_translate_data(int swap, void *data, unsigned int *size) +{ + unsigned long long delta; + struct kbuffer kbuf; + int type_len; + int length; + void *ptr; + + if (swap) { + kbuf.read_8 = __read_8_sw; + kbuf.read_4 = __read_4_sw; + kbuf.flags = host_is_bigendian() ? 0 : KBUFFER_FL_BIG_ENDIAN; + } else { + kbuf.read_8 = __read_8; + kbuf.read_4 = __read_4; + kbuf.flags = host_is_bigendian() ? KBUFFER_FL_BIG_ENDIAN: 0; + } + + type_len = translate_data(&kbuf, data, &ptr, &delta, &length); + switch (type_len) { + case KBUFFER_TYPE_PADDING: + case KBUFFER_TYPE_TIME_EXTEND: + case KBUFFER_TYPE_TIME_STAMP: + return NULL; + }; + + *size = length; + + return ptr; +} + +static int __next_event(struct kbuffer *kbuf) +{ + int type; + + do { + kbuf->curr = kbuf->next; + if (kbuf->next >= kbuf->size) + return -1; + type = update_pointers(kbuf); + } while (type == KBUFFER_TYPE_TIME_EXTEND || type == KBUFFER_TYPE_PADDING); + + return 0; +} + +static int next_event(struct kbuffer *kbuf) +{ + return kbuf->next_event(kbuf); +} + +/** + * kbuffer_next_event - increment the current pointer + * @kbuf: The kbuffer to read + * @ts: Address to store the next record's timestamp (may be NULL to ignore) + * + * Increments the pointers into the subbuffer of the kbuffer to point to the + * next event so that the next kbuffer_read_event() will return a + * new event. + * + * Returns the data of the next event if a new event exists on the subbuffer, + * NULL otherwise. + */ +void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts) +{ + int ret; + + if (!kbuf || !kbuf->subbuffer) + return NULL; + + ret = next_event(kbuf); + if (ret < 0) + return NULL; + + if (ts) + *ts = kbuf->timestamp; + + return kbuf->data + kbuf->index; +} + +/** + * kbuffer_load_subbuffer - load a new subbuffer into the kbuffer + * @kbuf: The kbuffer to load + * @subbuffer: The subbuffer to load into @kbuf. + * + * Load a new subbuffer (page) into @kbuf. This will reset all + * the pointers and update the @kbuf timestamp. The next read will + * return the first event on @subbuffer. + * + * Returns 0 on succes, -1 otherwise. + */ +int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer) +{ + unsigned long long flags; + void *ptr = subbuffer; + + if (!kbuf || !subbuffer) + return -1; + + kbuf->subbuffer = subbuffer; + + kbuf->timestamp = read_8(kbuf, ptr); + ptr += 8; + + kbuf->curr = 0; + + if (kbuf->flags & KBUFFER_FL_LONG_8) + kbuf->start = 16; + else + kbuf->start = 12; + + kbuf->data = subbuffer + kbuf->start; + + flags = read_long(kbuf, ptr); + kbuf->size = (unsigned int)flags & COMMIT_MASK; + + if (flags & MISSING_EVENTS) { + if (flags & MISSING_STORED) { + ptr = kbuf->data + kbuf->size; + kbuf->lost_events = read_long(kbuf, ptr); + } else + kbuf->lost_events = -1; + } else + kbuf->lost_events = 0; + + kbuf->index = 0; + kbuf->next = 0; + + next_event(kbuf); + + return 0; +} + +/** + * kbuffer_read_event - read the next event in the kbuffer subbuffer + * @kbuf: The kbuffer to read from + * @ts: The address to store the timestamp of the event (may be NULL to ignore) + * + * Returns a pointer to the data part of the current event. + * NULL if no event is left on the subbuffer. + */ +void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts) +{ + if (!kbuf || !kbuf->subbuffer) + return NULL; + + if (kbuf->curr >= kbuf->size) + return NULL; + + if (ts) + *ts = kbuf->timestamp; + return kbuf->data + kbuf->index; +} + +/** + * kbuffer_timestamp - Return the timestamp of the current event + * @kbuf: The kbuffer to read from + * + * Returns the timestamp of the current (next) event. + */ +unsigned long long kbuffer_timestamp(struct kbuffer *kbuf) +{ + return kbuf->timestamp; +} + +/** + * kbuffer_read_at_offset - read the event that is at offset + * @kbuf: The kbuffer to read from + * @offset: The offset into the subbuffer + * @ts: The address to store the timestamp of the event (may be NULL to ignore) + * + * The @offset must be an index from the @kbuf subbuffer beginning. + * If @offset is bigger than the stored subbuffer, NULL will be returned. + * + * Returns the data of the record that is at @offset. Note, @offset does + * not need to be the start of the record, the offset just needs to be + * in the record (or beginning of it). + * + * Note, the kbuf timestamp and pointers are updated to the + * returned record. That is, kbuffer_read_event() will return the same + * data and timestamp, and kbuffer_next_event() will increment from + * this record. + */ +void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset, + unsigned long long *ts) +{ + void *data; + + if (offset < kbuf->start) + offset = 0; + else + offset -= kbuf->start; + + /* Reset the buffer */ + kbuffer_load_subbuffer(kbuf, kbuf->subbuffer); + + while (kbuf->curr < offset) { + data = kbuffer_next_event(kbuf, ts); + if (!data) + break; + } + + return data; +} + +/** + * kbuffer_subbuffer_size - the size of the loaded subbuffer + * @kbuf: The kbuffer to read from + * + * Returns the size of the subbuffer. Note, this size is + * where the last event resides. The stored subbuffer may actually be + * bigger due to padding and such. + */ +int kbuffer_subbuffer_size(struct kbuffer *kbuf) +{ + return kbuf->size; +} + +/** + * kbuffer_curr_index - Return the index of the record + * @kbuf: The kbuffer to read from + * + * Returns the index from the start of the data part of + * the subbuffer to the current location. Note this is not + * from the start of the subbuffer. An index of zero will + * point to the first record. Use kbuffer_curr_offset() for + * the actually offset (that can be used by kbuffer_read_at_offset()) + */ +int kbuffer_curr_index(struct kbuffer *kbuf) +{ + return kbuf->curr; +} + +/** + * kbuffer_curr_offset - Return the offset of the record + * @kbuf: The kbuffer to read from + * + * Returns the offset from the start of the subbuffer to the + * current location. + */ +int kbuffer_curr_offset(struct kbuffer *kbuf) +{ + return kbuf->curr + kbuf->start; +} + +/** + * kbuffer_event_size - return the size of the event data + * @kbuf: The kbuffer to read + * + * Returns the size of the event data (the payload not counting + * the meta data of the record) of the current event. + */ +int kbuffer_event_size(struct kbuffer *kbuf) +{ + return kbuf->next - kbuf->index; +} + +/** + * kbuffer_curr_size - return the size of the entire record + * @kbuf: The kbuffer to read + * + * Returns the size of the entire record (meta data and payload) + * of the current event. + */ +int kbuffer_curr_size(struct kbuffer *kbuf) +{ + return kbuf->next - kbuf->curr; +} + +/** + * kbuffer_missed_events - return the # of missed events from last event. + * @kbuf: The kbuffer to read from + * + * Returns the # of missed events (if recorded) before the current + * event. Note, only events on the beginning of a subbuffer can + * have missed events, all other events within the buffer will be + * zero. + */ +int kbuffer_missed_events(struct kbuffer *kbuf) +{ + /* Only the first event can have missed events */ + if (kbuf->curr) + return 0; + + return kbuf->lost_events; +} + +/** + * kbuffer_set_old_forma - set the kbuffer to use the old format parsing + * @kbuf: The kbuffer to set + * + * This is obsolete (or should be). The first kernels to use the + * new ring buffer had a slightly different ring buffer format + * (2.6.30 and earlier). It is still somewhat supported by kbuffer, + * but should not be counted on in the future. + */ +void kbuffer_set_old_format(struct kbuffer *kbuf) +{ + kbuf->flags |= KBUFFER_FL_OLD_FORMAT; + + kbuf->next_event = __old_next_event; +} diff --git a/traceevent/kbuffer.h b/traceevent/kbuffer.h new file mode 100644 index 0000000..c831f64 --- /dev/null +++ b/traceevent/kbuffer.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2012 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#ifndef _KBUFFER_H +#define _KBUFFER_H + +#ifndef TS_SHIFT +#define TS_SHIFT 27 +#endif + +enum kbuffer_endian { + KBUFFER_ENDIAN_BIG, + KBUFFER_ENDIAN_LITTLE, +}; + +enum kbuffer_long_size { + KBUFFER_LSIZE_4, + KBUFFER_LSIZE_8, +}; + +enum { + KBUFFER_TYPE_PADDING = 29, + KBUFFER_TYPE_TIME_EXTEND = 30, + KBUFFER_TYPE_TIME_STAMP = 31, +}; + +struct kbuffer; + +struct kbuffer *kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian); +void kbuffer_free(struct kbuffer *kbuf); +int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer); +void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts); +void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts); +unsigned long long kbuffer_timestamp(struct kbuffer *kbuf); + +void *kbuffer_translate_data(int swap, void *data, unsigned int *size); + +void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset, unsigned long long *ts); + +int kbuffer_curr_index(struct kbuffer *kbuf); + +int kbuffer_curr_offset(struct kbuffer *kbuf); +int kbuffer_curr_size(struct kbuffer *kbuf); +int kbuffer_event_size(struct kbuffer *kbuf); +int kbuffer_missed_events(struct kbuffer *kbuf); +int kbuffer_subbuffer_size(struct kbuffer *kbuf); + +void kbuffer_set_old_format(struct kbuffer *kbuf); + +#endif /* _K_BUFFER_H */ diff --git a/traceevent/parse-filter.c b/traceevent/parse-filter.c new file mode 100644 index 0000000..ec308ae --- /dev/null +++ b/traceevent/parse-filter.c @@ -0,0 +1,2303 @@ +/* + * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <errno.h> +#include <sys/types.h> + +#include "event-parse.h" +#include "event-utils.h" + +#define COMM "COMM" + +static struct format_field comm = { + .name = "COMM", +}; + +struct event_list { + struct event_list *next; + struct event_format *event; +}; + +#define MAX_ERR_STR_SIZE 256 + +static void show_error(char **error_str, const char *fmt, ...) +{ + unsigned long long index; + const char *input; + char *error; + va_list ap; + int len; + int i; + + if (!error_str) + return; + + input = pevent_get_input_buf(); + index = pevent_get_input_buf_ptr(); + len = input ? strlen(input) : 0; + + error = malloc_or_die(MAX_ERR_STR_SIZE + (len*2) + 3); + + if (len) { + strcpy(error, input); + error[len] = '\n'; + for (i = 1; i < len && i < index; i++) + error[len+i] = ' '; + error[len + i] = '^'; + error[len + i + 1] = '\n'; + len += i+2; + } + + va_start(ap, fmt); + vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap); + va_end(ap); + + *error_str = error; +} + +static void free_token(char *token) +{ + pevent_free_token(token); +} + +static enum event_type read_token(char **tok) +{ + enum event_type type; + char *token = NULL; + + do { + free_token(token); + type = pevent_read_token(&token); + } while (type == EVENT_NEWLINE || type == EVENT_SPACE); + + /* If token is = or ! check to see if the next char is ~ */ + if (token && + (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && + pevent_peek_char() == '~') { + /* append it */ + *tok = malloc_or_die(3); + sprintf(*tok, "%c%c", *token, '~'); + free_token(token); + /* Now remove the '~' from the buffer */ + pevent_read_token(&token); + free_token(token); + } else + *tok = token; + + return type; +} + +static int filter_cmp(const void *a, const void *b) +{ + const struct filter_type *ea = a; + const struct filter_type *eb = b; + + if (ea->event_id < eb->event_id) + return -1; + + if (ea->event_id > eb->event_id) + return 1; + + return 0; +} + +static struct filter_type * +find_filter_type(struct event_filter *filter, int id) +{ + struct filter_type *filter_type; + struct filter_type key; + + key.event_id = id; + + filter_type = bsearch(&key, filter->event_filters, + filter->filters, + sizeof(*filter->event_filters), + filter_cmp); + + return filter_type; +} + +static struct filter_type * +add_filter_type(struct event_filter *filter, int id) +{ + struct filter_type *filter_type; + int i; + + filter_type = find_filter_type(filter, id); + if (filter_type) + return filter_type; + + filter->event_filters = realloc(filter->event_filters, + sizeof(*filter->event_filters) * + (filter->filters + 1)); + if (!filter->event_filters) + die("Could not allocate filter"); + + for (i = 0; i < filter->filters; i++) { + if (filter->event_filters[i].event_id > id) + break; + } + + if (i < filter->filters) + memmove(&filter->event_filters[i+1], + &filter->event_filters[i], + sizeof(*filter->event_filters) * + (filter->filters - i)); + + filter_type = &filter->event_filters[i]; + filter_type->event_id = id; + filter_type->event = pevent_find_event(filter->pevent, id); + filter_type->filter = NULL; + + filter->filters++; + + return filter_type; +} + +/** + * pevent_filter_alloc - create a new event filter + * @pevent: The pevent that this filter is associated with + */ +struct event_filter *pevent_filter_alloc(struct pevent *pevent) +{ + struct event_filter *filter; + + filter = malloc_or_die(sizeof(*filter)); + memset(filter, 0, sizeof(*filter)); + filter->pevent = pevent; + pevent_ref(pevent); + + return filter; +} + +static struct filter_arg *allocate_arg(void) +{ + struct filter_arg *arg; + + arg = malloc_or_die(sizeof(*arg)); + memset(arg, 0, sizeof(*arg)); + + return arg; +} + +static void free_arg(struct filter_arg *arg) +{ + if (!arg) + return; + + switch (arg->type) { + case FILTER_ARG_NONE: + case FILTER_ARG_BOOLEAN: + break; + + case FILTER_ARG_NUM: + free_arg(arg->num.left); + free_arg(arg->num.right); + break; + + case FILTER_ARG_EXP: + free_arg(arg->exp.left); + free_arg(arg->exp.right); + break; + + case FILTER_ARG_STR: + free(arg->str.val); + regfree(&arg->str.reg); + free(arg->str.buffer); + break; + + case FILTER_ARG_VALUE: + if (arg->value.type == FILTER_STRING || + arg->value.type == FILTER_CHAR) + free(arg->value.str); + break; + + case FILTER_ARG_OP: + free_arg(arg->op.left); + free_arg(arg->op.right); + default: + break; + } + + free(arg); +} + +static void add_event(struct event_list **events, + struct event_format *event) +{ + struct event_list *list; + + list = malloc_or_die(sizeof(*list)); + list->next = *events; + *events = list; + list->event = event; +} + +static int event_match(struct event_format *event, + regex_t *sreg, regex_t *ereg) +{ + if (sreg) { + return !regexec(sreg, event->system, 0, NULL, 0) && + !regexec(ereg, event->name, 0, NULL, 0); + } + + return !regexec(ereg, event->system, 0, NULL, 0) || + !regexec(ereg, event->name, 0, NULL, 0); +} + +static int +find_event(struct pevent *pevent, struct event_list **events, + char *sys_name, char *event_name) +{ + struct event_format *event; + regex_t ereg; + regex_t sreg; + int match = 0; + char *reg; + int ret; + int i; + + if (!event_name) { + /* if no name is given, then swap sys and name */ + event_name = sys_name; + sys_name = NULL; + } + + reg = malloc_or_die(strlen(event_name) + 3); + sprintf(reg, "^%s$", event_name); + + ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB); + free(reg); + + if (ret) + return -1; + + if (sys_name) { + reg = malloc_or_die(strlen(sys_name) + 3); + sprintf(reg, "^%s$", sys_name); + ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB); + free(reg); + if (ret) { + regfree(&ereg); + return -1; + } + } + + for (i = 0; i < pevent->nr_events; i++) { + event = pevent->events[i]; + if (event_match(event, sys_name ? &sreg : NULL, &ereg)) { + match = 1; + add_event(events, event); + } + } + + regfree(&ereg); + if (sys_name) + regfree(&sreg); + + if (!match) + return -1; + + return 0; +} + +static void free_events(struct event_list *events) +{ + struct event_list *event; + + while (events) { + event = events; + events = events->next; + free(event); + } +} + +static struct filter_arg * +create_arg_item(struct event_format *event, const char *token, + enum event_type type, char **error_str) +{ + struct format_field *field; + struct filter_arg *arg; + + arg = allocate_arg(); + + switch (type) { + + case EVENT_SQUOTE: + case EVENT_DQUOTE: + arg->type = FILTER_ARG_VALUE; + arg->value.type = + type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR; + arg->value.str = strdup(token); + if (!arg->value.str) + die("malloc string"); + break; + case EVENT_ITEM: + /* if it is a number, then convert it */ + if (isdigit(token[0])) { + arg->type = FILTER_ARG_VALUE; + arg->value.type = FILTER_NUMBER; + arg->value.val = strtoull(token, NULL, 0); + break; + } + /* Consider this a field */ + field = pevent_find_any_field(event, token); + if (!field) { + if (strcmp(token, COMM) != 0) { + /* not a field, Make it false */ + arg->type = FILTER_ARG_BOOLEAN; + arg->boolean.value = FILTER_FALSE; + break; + } + /* If token is 'COMM' then it is special */ + field = &comm; + } + arg->type = FILTER_ARG_FIELD; + arg->field.field = field; + break; + default: + free_arg(arg); + show_error(error_str, "expected a value but found %s", + token); + return NULL; + } + return arg; +} + +static struct filter_arg * +create_arg_op(enum filter_op_type btype) +{ + struct filter_arg *arg; + + arg = allocate_arg(); + arg->type = FILTER_ARG_OP; + arg->op.type = btype; + + return arg; +} + +static struct filter_arg * +create_arg_exp(enum filter_exp_type etype) +{ + struct filter_arg *arg; + + arg = allocate_arg(); + arg->type = FILTER_ARG_EXP; + arg->op.type = etype; + + return arg; +} + +static struct filter_arg * +create_arg_cmp(enum filter_exp_type etype) +{ + struct filter_arg *arg; + + arg = allocate_arg(); + /* Use NUM and change if necessary */ + arg->type = FILTER_ARG_NUM; + arg->op.type = etype; + + return arg; +} + +static int add_right(struct filter_arg *op, struct filter_arg *arg, + char **error_str) +{ + struct filter_arg *left; + char *str; + int op_type; + int ret; + + switch (op->type) { + case FILTER_ARG_EXP: + if (op->exp.right) + goto out_fail; + op->exp.right = arg; + break; + + case FILTER_ARG_OP: + if (op->op.right) + goto out_fail; + op->op.right = arg; + break; + + case FILTER_ARG_NUM: + if (op->op.right) + goto out_fail; + /* + * The arg must be num, str, or field + */ + switch (arg->type) { + case FILTER_ARG_VALUE: + case FILTER_ARG_FIELD: + break; + default: + show_error(error_str, + "Illegal rvalue"); + return -1; + } + + /* + * Depending on the type, we may need to + * convert this to a string or regex. + */ + switch (arg->value.type) { + case FILTER_CHAR: + /* + * A char should be converted to number if + * the string is 1 byte, and the compare + * is not a REGEX. + */ + if (strlen(arg->value.str) == 1 && + op->num.type != FILTER_CMP_REGEX && + op->num.type != FILTER_CMP_NOT_REGEX) { + arg->value.type = FILTER_NUMBER; + goto do_int; + } + /* fall through */ + case FILTER_STRING: + + /* convert op to a string arg */ + op_type = op->num.type; + left = op->num.left; + str = arg->value.str; + + /* reset the op for the new field */ + memset(op, 0, sizeof(*op)); + + /* + * If left arg was a field not found then + * NULL the entire op. + */ + if (left->type == FILTER_ARG_BOOLEAN) { + free_arg(left); + free_arg(arg); + op->type = FILTER_ARG_BOOLEAN; + op->boolean.value = FILTER_FALSE; + break; + } + + /* Left arg must be a field */ + if (left->type != FILTER_ARG_FIELD) { + show_error(error_str, + "Illegal lvalue for string comparison"); + return -1; + } + + /* Make sure this is a valid string compare */ + switch (op_type) { + case FILTER_CMP_EQ: + op_type = FILTER_CMP_MATCH; + break; + case FILTER_CMP_NE: + op_type = FILTER_CMP_NOT_MATCH; + break; + + case FILTER_CMP_REGEX: + case FILTER_CMP_NOT_REGEX: + ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB); + if (ret) { + show_error(error_str, + "RegEx '%s' did not compute", + str); + return -1; + } + break; + default: + show_error(error_str, + "Illegal comparison for string"); + return -1; + } + + op->type = FILTER_ARG_STR; + op->str.type = op_type; + op->str.field = left->field.field; + op->str.val = strdup(str); + if (!op->str.val) + die("malloc string"); + /* + * Need a buffer to copy data for tests + */ + op->str.buffer = malloc_or_die(op->str.field->size + 1); + /* Null terminate this buffer */ + op->str.buffer[op->str.field->size] = 0; + + /* We no longer have left or right args */ + free_arg(arg); + free_arg(left); + + break; + + case FILTER_NUMBER: + + do_int: + switch (op->num.type) { + case FILTER_CMP_REGEX: + case FILTER_CMP_NOT_REGEX: + show_error(error_str, + "Op not allowed with integers"); + return -1; + + default: + break; + } + + /* numeric compare */ + op->num.right = arg; + break; + default: + goto out_fail; + } + break; + default: + goto out_fail; + } + + return 0; + + out_fail: + show_error(error_str, + "Syntax error"); + return -1; +} + +static struct filter_arg * +rotate_op_right(struct filter_arg *a, struct filter_arg *b) +{ + struct filter_arg *arg; + + arg = a->op.right; + a->op.right = b; + return arg; +} + +static int add_left(struct filter_arg *op, struct filter_arg *arg) +{ + switch (op->type) { + case FILTER_ARG_EXP: + if (arg->type == FILTER_ARG_OP) + arg = rotate_op_right(arg, op); + op->exp.left = arg; + break; + + case FILTER_ARG_OP: + op->op.left = arg; + break; + case FILTER_ARG_NUM: + if (arg->type == FILTER_ARG_OP) + arg = rotate_op_right(arg, op); + + /* left arg of compares must be a field */ + if (arg->type != FILTER_ARG_FIELD && + arg->type != FILTER_ARG_BOOLEAN) + return -1; + op->num.left = arg; + break; + default: + return -1; + } + return 0; +} + +enum op_type { + OP_NONE, + OP_BOOL, + OP_NOT, + OP_EXP, + OP_CMP, +}; + +static enum op_type process_op(const char *token, + enum filter_op_type *btype, + enum filter_cmp_type *ctype, + enum filter_exp_type *etype) +{ + *btype = FILTER_OP_NOT; + *etype = FILTER_EXP_NONE; + *ctype = FILTER_CMP_NONE; + + if (strcmp(token, "&&") == 0) + *btype = FILTER_OP_AND; + else if (strcmp(token, "||") == 0) + *btype = FILTER_OP_OR; + else if (strcmp(token, "!") == 0) + return OP_NOT; + + if (*btype != FILTER_OP_NOT) + return OP_BOOL; + + /* Check for value expressions */ + if (strcmp(token, "+") == 0) { + *etype = FILTER_EXP_ADD; + } else if (strcmp(token, "-") == 0) { + *etype = FILTER_EXP_SUB; + } else if (strcmp(token, "*") == 0) { + *etype = FILTER_EXP_MUL; + } else if (strcmp(token, "/") == 0) { + *etype = FILTER_EXP_DIV; + } else if (strcmp(token, "%") == 0) { + *etype = FILTER_EXP_MOD; + } else if (strcmp(token, ">>") == 0) { + *etype = FILTER_EXP_RSHIFT; + } else if (strcmp(token, "<<") == 0) { + *etype = FILTER_EXP_LSHIFT; + } else if (strcmp(token, "&") == 0) { + *etype = FILTER_EXP_AND; + } else if (strcmp(token, "|") == 0) { + *etype = FILTER_EXP_OR; + } else if (strcmp(token, "^") == 0) { + *etype = FILTER_EXP_XOR; + } else if (strcmp(token, "~") == 0) + *etype = FILTER_EXP_NOT; + + if (*etype != FILTER_EXP_NONE) + return OP_EXP; + + /* Check for compares */ + if (strcmp(token, "==") == 0) + *ctype = FILTER_CMP_EQ; + else if (strcmp(token, "!=") == 0) + *ctype = FILTER_CMP_NE; + else if (strcmp(token, "<") == 0) + *ctype = FILTER_CMP_LT; + else if (strcmp(token, ">") == 0) + *ctype = FILTER_CMP_GT; + else if (strcmp(token, "<=") == 0) + *ctype = FILTER_CMP_LE; + else if (strcmp(token, ">=") == 0) + *ctype = FILTER_CMP_GE; + else if (strcmp(token, "=~") == 0) + *ctype = FILTER_CMP_REGEX; + else if (strcmp(token, "!~") == 0) + *ctype = FILTER_CMP_NOT_REGEX; + else + return OP_NONE; + + return OP_CMP; +} + +static int check_op_done(struct filter_arg *arg) +{ + switch (arg->type) { + case FILTER_ARG_EXP: + return arg->exp.right != NULL; + + case FILTER_ARG_OP: + return arg->op.right != NULL; + + case FILTER_ARG_NUM: + return arg->num.right != NULL; + + case FILTER_ARG_STR: + /* A string conversion is always done */ + return 1; + + case FILTER_ARG_BOOLEAN: + /* field not found, is ok */ + return 1; + + default: + return 0; + } +} + +enum filter_vals { + FILTER_VAL_NORM, + FILTER_VAL_FALSE, + FILTER_VAL_TRUE, +}; + +void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, + struct filter_arg *arg) +{ + struct filter_arg *other_child; + struct filter_arg **ptr; + + if (parent->type != FILTER_ARG_OP && + arg->type != FILTER_ARG_OP) + die("can not reparent other than OP"); + + /* Get the sibling */ + if (old_child->op.right == arg) { + ptr = &old_child->op.right; + other_child = old_child->op.left; + } else if (old_child->op.left == arg) { + ptr = &old_child->op.left; + other_child = old_child->op.right; + } else + die("Error in reparent op, find other child"); + + /* Detach arg from old_child */ + *ptr = NULL; + + /* Check for root */ + if (parent == old_child) { + free_arg(other_child); + *parent = *arg; + /* Free arg without recussion */ + free(arg); + return; + } + + if (parent->op.right == old_child) + ptr = &parent->op.right; + else if (parent->op.left == old_child) + ptr = &parent->op.left; + else + die("Error in reparent op"); + *ptr = arg; + + free_arg(old_child); +} + +enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg) +{ + enum filter_vals lval, rval; + + switch (arg->type) { + + /* bad case */ + case FILTER_ARG_BOOLEAN: + return FILTER_VAL_FALSE + arg->boolean.value; + + /* good cases: */ + case FILTER_ARG_STR: + case FILTER_ARG_VALUE: + case FILTER_ARG_FIELD: + return FILTER_VAL_NORM; + + case FILTER_ARG_EXP: + lval = test_arg(arg, arg->exp.left); + if (lval != FILTER_VAL_NORM) + return lval; + rval = test_arg(arg, arg->exp.right); + if (rval != FILTER_VAL_NORM) + return rval; + return FILTER_VAL_NORM; + + case FILTER_ARG_NUM: + lval = test_arg(arg, arg->num.left); + if (lval != FILTER_VAL_NORM) + return lval; + rval = test_arg(arg, arg->num.right); + if (rval != FILTER_VAL_NORM) + return rval; + return FILTER_VAL_NORM; + + case FILTER_ARG_OP: + if (arg->op.type != FILTER_OP_NOT) { + lval = test_arg(arg, arg->op.left); + switch (lval) { + case FILTER_VAL_NORM: + break; + case FILTER_VAL_TRUE: + if (arg->op.type == FILTER_OP_OR) + return FILTER_VAL_TRUE; + rval = test_arg(arg, arg->op.right); + if (rval != FILTER_VAL_NORM) + return rval; + + reparent_op_arg(parent, arg, arg->op.right); + return FILTER_VAL_NORM; + + case FILTER_VAL_FALSE: + if (arg->op.type == FILTER_OP_AND) + return FILTER_VAL_FALSE; + rval = test_arg(arg, arg->op.right); + if (rval != FILTER_VAL_NORM) + return rval; + + reparent_op_arg(parent, arg, arg->op.right); + return FILTER_VAL_NORM; + } + } + + rval = test_arg(arg, arg->op.right); + switch (rval) { + case FILTER_VAL_NORM: + break; + case FILTER_VAL_TRUE: + if (arg->op.type == FILTER_OP_OR) + return FILTER_VAL_TRUE; + if (arg->op.type == FILTER_OP_NOT) + return FILTER_VAL_FALSE; + + reparent_op_arg(parent, arg, arg->op.left); + return FILTER_VAL_NORM; + + case FILTER_VAL_FALSE: + if (arg->op.type == FILTER_OP_AND) + return FILTER_VAL_FALSE; + if (arg->op.type == FILTER_OP_NOT) + return FILTER_VAL_TRUE; + + reparent_op_arg(parent, arg, arg->op.left); + return FILTER_VAL_NORM; + } + + return FILTER_VAL_NORM; + default: + die("bad arg in filter tree"); + } + return FILTER_VAL_NORM; +} + +/* Remove any unknown event fields */ +static struct filter_arg *collapse_tree(struct filter_arg *arg) +{ + enum filter_vals ret; + + ret = test_arg(arg, arg); + switch (ret) { + case FILTER_VAL_NORM: + return arg; + + case FILTER_VAL_TRUE: + case FILTER_VAL_FALSE: + free_arg(arg); + arg = allocate_arg(); + arg->type = FILTER_ARG_BOOLEAN; + arg->boolean.value = ret == FILTER_VAL_TRUE; + } + + return arg; +} + +static int +process_filter(struct event_format *event, struct filter_arg **parg, + char **error_str, int not) +{ + enum event_type type; + char *token = NULL; + struct filter_arg *current_op = NULL; + struct filter_arg *current_exp = NULL; + struct filter_arg *left_item = NULL; + struct filter_arg *arg = NULL; + enum op_type op_type; + enum filter_op_type btype; + enum filter_exp_type etype; + enum filter_cmp_type ctype; + int ret; + + *parg = NULL; + + do { + free(token); + type = read_token(&token); + switch (type) { + case EVENT_SQUOTE: + case EVENT_DQUOTE: + case EVENT_ITEM: + arg = create_arg_item(event, token, type, error_str); + if (!arg) + goto fail; + if (!left_item) + left_item = arg; + else if (current_exp) { + ret = add_right(current_exp, arg, error_str); + if (ret < 0) + goto fail; + left_item = NULL; + /* Not's only one one expression */ + if (not) { + arg = NULL; + if (current_op) + goto fail_print; + free(token); + *parg = current_exp; + return 0; + } + } else + goto fail_print; + arg = NULL; + break; + + case EVENT_DELIM: + if (*token == ',') { + show_error(error_str, + "Illegal token ','"); + goto fail; + } + + if (*token == '(') { + if (left_item) { + show_error(error_str, + "Open paren can not come after item"); + goto fail; + } + if (current_exp) { + show_error(error_str, + "Open paren can not come after expression"); + goto fail; + } + + ret = process_filter(event, &arg, error_str, 0); + if (ret != 1) { + if (ret == 0) + show_error(error_str, + "Unbalanced number of '('"); + goto fail; + } + ret = 0; + + /* A not wants just one expression */ + if (not) { + if (current_op) + goto fail_print; + *parg = arg; + return 0; + } + + if (current_op) + ret = add_right(current_op, arg, error_str); + else + current_exp = arg; + + if (ret < 0) + goto fail; + + } else { /* ')' */ + if (!current_op && !current_exp) + goto fail_print; + + /* Make sure everything is finished at this level */ + if (current_exp && !check_op_done(current_exp)) + goto fail_print; + if (current_op && !check_op_done(current_op)) + goto fail_print; + + if (current_op) + *parg = current_op; + else + *parg = current_exp; + return 1; + } + break; + + case EVENT_OP: + op_type = process_op(token, &btype, &ctype, &etype); + + /* All expect a left arg except for NOT */ + switch (op_type) { + case OP_BOOL: + /* Logic ops need a left expression */ + if (!current_exp && !current_op) + goto fail_print; + /* fall through */ + case OP_NOT: + /* logic only processes ops and exp */ + if (left_item) + goto fail_print; + break; + case OP_EXP: + case OP_CMP: + if (!left_item) + goto fail_print; + break; + case OP_NONE: + show_error(error_str, + "Unknown op token %s", token); + goto fail; + } + + ret = 0; + switch (op_type) { + case OP_BOOL: + arg = create_arg_op(btype); + if (current_op) + ret = add_left(arg, current_op); + else + ret = add_left(arg, current_exp); + current_op = arg; + current_exp = NULL; + break; + + case OP_NOT: + arg = create_arg_op(btype); + if (current_op) + ret = add_right(current_op, arg, error_str); + if (ret < 0) + goto fail; + current_exp = arg; + ret = process_filter(event, &arg, error_str, 1); + if (ret < 0) + goto fail; + ret = add_right(current_exp, arg, error_str); + if (ret < 0) + goto fail; + break; + + case OP_EXP: + case OP_CMP: + if (op_type == OP_EXP) + arg = create_arg_exp(etype); + else + arg = create_arg_cmp(ctype); + + if (current_op) + ret = add_right(current_op, arg, error_str); + if (ret < 0) + goto fail; + ret = add_left(arg, left_item); + if (ret < 0) { + arg = NULL; + goto fail_print; + } + current_exp = arg; + break; + default: + break; + } + arg = NULL; + if (ret < 0) + goto fail_print; + break; + case EVENT_NONE: + break; + default: + goto fail_print; + } + } while (type != EVENT_NONE); + + if (!current_op && !current_exp) + goto fail_print; + + if (!current_op) + current_op = current_exp; + + current_op = collapse_tree(current_op); + + *parg = current_op; + + return 0; + + fail_print: + show_error(error_str, "Syntax error"); + fail: + free_arg(current_op); + free_arg(current_exp); + free_arg(arg); + free(token); + return -1; +} + +static int +process_event(struct event_format *event, const char *filter_str, + struct filter_arg **parg, char **error_str) +{ + int ret; + + pevent_buffer_init(filter_str, strlen(filter_str)); + + ret = process_filter(event, parg, error_str, 0); + if (ret == 1) { + show_error(error_str, + "Unbalanced number of ')'"); + return -1; + } + if (ret < 0) + return ret; + + /* If parg is NULL, then make it into FALSE */ + if (!*parg) { + *parg = allocate_arg(); + (*parg)->type = FILTER_ARG_BOOLEAN; + (*parg)->boolean.value = FILTER_FALSE; + } + + return 0; +} + +static int filter_event(struct event_filter *filter, + struct event_format *event, + const char *filter_str, char **error_str) +{ + struct filter_type *filter_type; + struct filter_arg *arg; + int ret; + + if (filter_str) { + ret = process_event(event, filter_str, &arg, error_str); + if (ret < 0) + return ret; + + } else { + /* just add a TRUE arg */ + arg = allocate_arg(); + arg->type = FILTER_ARG_BOOLEAN; + arg->boolean.value = FILTER_TRUE; + } + + filter_type = add_filter_type(filter, event->id); + if (filter_type->filter) + free_arg(filter_type->filter); + filter_type->filter = arg; + + return 0; +} + +/** + * pevent_filter_add_filter_str - add a new filter + * @filter: the event filter to add to + * @filter_str: the filter string that contains the filter + * @error_str: string containing reason for failed filter + * + * Returns 0 if the filter was successfully added + * -1 if there was an error. + * + * On error, if @error_str points to a string pointer, + * it is set to the reason that the filter failed. + * This string must be freed with "free". + */ +int pevent_filter_add_filter_str(struct event_filter *filter, + const char *filter_str, + char **error_str) +{ + struct pevent *pevent = filter->pevent; + struct event_list *event; + struct event_list *events = NULL; + const char *filter_start; + const char *next_event; + char *this_event; + char *event_name = NULL; + char *sys_name = NULL; + char *sp; + int rtn = 0; + int len; + int ret; + + /* clear buffer to reset show error */ + pevent_buffer_init("", 0); + + if (error_str) + *error_str = NULL; + + filter_start = strchr(filter_str, ':'); + if (filter_start) + len = filter_start - filter_str; + else + len = strlen(filter_str); + + + do { + next_event = strchr(filter_str, ','); + if (next_event && + (!filter_start || next_event < filter_start)) + len = next_event - filter_str; + else if (filter_start) + len = filter_start - filter_str; + else + len = strlen(filter_str); + + this_event = malloc_or_die(len + 1); + memcpy(this_event, filter_str, len); + this_event[len] = 0; + + if (next_event) + next_event++; + + filter_str = next_event; + + sys_name = strtok_r(this_event, "/", &sp); + event_name = strtok_r(NULL, "/", &sp); + + if (!sys_name) { + show_error(error_str, "No filter found"); + /* This can only happen when events is NULL, but still */ + free_events(events); + free(this_event); + return -1; + } + + /* Find this event */ + ret = find_event(pevent, &events, strim(sys_name), strim(event_name)); + if (ret < 0) { + if (event_name) + show_error(error_str, + "No event found under '%s.%s'", + sys_name, event_name); + else + show_error(error_str, + "No event found under '%s'", + sys_name); + free_events(events); + free(this_event); + return -1; + } + free(this_event); + } while (filter_str); + + /* Skip the ':' */ + if (filter_start) + filter_start++; + + /* filter starts here */ + for (event = events; event; event = event->next) { + ret = filter_event(filter, event->event, filter_start, + error_str); + /* Failures are returned if a parse error happened */ + if (ret < 0) + rtn = ret; + + if (ret >= 0 && pevent->test_filters) { + char *test; + test = pevent_filter_make_string(filter, event->event->id); + printf(" '%s: %s'\n", event->event->name, test); + free(test); + } + } + + free_events(events); + + if (rtn >= 0 && pevent->test_filters) + exit(0); + + return rtn; +} + +static void free_filter_type(struct filter_type *filter_type) +{ + free_arg(filter_type->filter); +} + +/** + * pevent_filter_remove_event - remove a filter for an event + * @filter: the event filter to remove from + * @event_id: the event to remove a filter for + * + * Removes the filter saved for an event defined by @event_id + * from the @filter. + * + * Returns 1: if an event was removed + * 0: if the event was not found + */ +int pevent_filter_remove_event(struct event_filter *filter, + int event_id) +{ + struct filter_type *filter_type; + unsigned long len; + + if (!filter->filters) + return 0; + + filter_type = find_filter_type(filter, event_id); + + if (!filter_type) + return 0; + + free_filter_type(filter_type); + + /* The filter_type points into the event_filters array */ + len = (unsigned long)(filter->event_filters + filter->filters) - + (unsigned long)(filter_type + 1); + + memmove(filter_type, filter_type + 1, len); + filter->filters--; + + memset(&filter->event_filters[filter->filters], 0, + sizeof(*filter_type)); + + return 1; +} + +/** + * pevent_filter_reset - clear all filters in a filter + * @filter: the event filter to reset + * + * Removes all filters from a filter and resets it. + */ +void pevent_filter_reset(struct event_filter *filter) +{ + int i; + + for (i = 0; i < filter->filters; i++) + free_filter_type(&filter->event_filters[i]); + + free(filter->event_filters); + filter->filters = 0; + filter->event_filters = NULL; +} + +void pevent_filter_free(struct event_filter *filter) +{ + pevent_unref(filter->pevent); + + pevent_filter_reset(filter); + + free(filter); +} + +static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg); + +static int copy_filter_type(struct event_filter *filter, + struct event_filter *source, + struct filter_type *filter_type) +{ + struct filter_arg *arg; + struct event_format *event; + const char *sys; + const char *name; + char *str; + + /* Can't assume that the pevent's are the same */ + sys = filter_type->event->system; + name = filter_type->event->name; + event = pevent_find_event_by_name(filter->pevent, sys, name); + if (!event) + return -1; + + str = arg_to_str(source, filter_type->filter); + if (!str) + return -1; + + if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) { + /* Add trivial event */ + arg = allocate_arg(); + arg->type = FILTER_ARG_BOOLEAN; + if (strcmp(str, "TRUE") == 0) + arg->boolean.value = 1; + else + arg->boolean.value = 0; + + filter_type = add_filter_type(filter, event->id); + filter_type->filter = arg; + + free(str); + return 0; + } + + filter_event(filter, event, str, NULL); + free(str); + + return 0; +} + +/** + * pevent_filter_copy - copy a filter using another filter + * @dest - the filter to copy to + * @source - the filter to copy from + * + * Returns 0 on success and -1 if not all filters were copied + */ +int pevent_filter_copy(struct event_filter *dest, struct event_filter *source) +{ + int ret = 0; + int i; + + pevent_filter_reset(dest); + + for (i = 0; i < source->filters; i++) { + if (copy_filter_type(dest, source, &source->event_filters[i])) + ret = -1; + } + return ret; +} + + +/** + * pevent_update_trivial - update the trivial filters with the given filter + * @dest - the filter to update + * @source - the filter as the source of the update + * @type - the type of trivial filter to update. + * + * Scan dest for trivial events matching @type to replace with the source. + * + * Returns 0 on success and -1 if there was a problem updating, but + * events may have still been updated on error. + */ +int pevent_update_trivial(struct event_filter *dest, struct event_filter *source, + enum filter_trivial_type type) +{ + struct pevent *src_pevent; + struct pevent *dest_pevent; + struct event_format *event; + struct filter_type *filter_type; + struct filter_arg *arg; + char *str; + int i; + + src_pevent = source->pevent; + dest_pevent = dest->pevent; + + /* Do nothing if either of the filters has nothing to filter */ + if (!dest->filters || !source->filters) + return 0; + + for (i = 0; i < dest->filters; i++) { + filter_type = &dest->event_filters[i]; + arg = filter_type->filter; + if (arg->type != FILTER_ARG_BOOLEAN) + continue; + if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) || + (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE)) + continue; + + event = filter_type->event; + + if (src_pevent != dest_pevent) { + /* do a look up */ + event = pevent_find_event_by_name(src_pevent, + event->system, + event->name); + if (!event) + return -1; + } + + str = pevent_filter_make_string(source, event->id); + if (!str) + continue; + + /* Don't bother if the filter is trivial too */ + if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0) + filter_event(dest, event, str, NULL); + free(str); + } + return 0; +} + +/** + * pevent_filter_clear_trivial - clear TRUE and FALSE filters + * @filter: the filter to remove trivial filters from + * @type: remove only true, false, or both + * + * Removes filters that only contain a TRUE or FALES boolean arg. + */ +void pevent_filter_clear_trivial(struct event_filter *filter, + enum filter_trivial_type type) +{ + struct filter_type *filter_type; + int count = 0; + int *ids = NULL; + int i; + + if (!filter->filters) + return; + + /* + * Two steps, first get all ids with trivial filters. + * then remove those ids. + */ + for (i = 0; i < filter->filters; i++) { + filter_type = &filter->event_filters[i]; + if (filter_type->filter->type != FILTER_ARG_BOOLEAN) + continue; + switch (type) { + case FILTER_TRIVIAL_FALSE: + if (filter_type->filter->boolean.value) + continue; + case FILTER_TRIVIAL_TRUE: + if (!filter_type->filter->boolean.value) + continue; + default: + break; + } + + ids = realloc(ids, sizeof(*ids) * (count + 1)); + if (!ids) + die("Can't allocate ids"); + ids[count++] = filter_type->event_id; + } + + if (!count) + return; + + for (i = 0; i < count; i++) + pevent_filter_remove_event(filter, ids[i]); + + free(ids); +} + +/** + * pevent_filter_event_has_trivial - return true event contains trivial filter + * @filter: the filter with the information + * @event_id: the id of the event to test + * @type: trivial type to test for (TRUE, FALSE, EITHER) + * + * Returns 1 if the event contains a matching trivial type + * otherwise 0. + */ +int pevent_filter_event_has_trivial(struct event_filter *filter, + int event_id, + enum filter_trivial_type type) +{ + struct filter_type *filter_type; + + if (!filter->filters) + return 0; + + filter_type = find_filter_type(filter, event_id); + + if (!filter_type) + return 0; + + if (filter_type->filter->type != FILTER_ARG_BOOLEAN) + return 0; + + switch (type) { + case FILTER_TRIVIAL_FALSE: + return !filter_type->filter->boolean.value; + + case FILTER_TRIVIAL_TRUE: + return filter_type->filter->boolean.value; + default: + return 1; + } +} + +static int test_filter(struct event_format *event, + struct filter_arg *arg, struct pevent_record *record); + +static const char * +get_comm(struct event_format *event, struct pevent_record *record) +{ + const char *comm; + int pid; + + pid = pevent_data_pid(event->pevent, record); + comm = pevent_data_comm_from_pid(event->pevent, pid); + return comm; +} + +static unsigned long long +get_value(struct event_format *event, + struct format_field *field, struct pevent_record *record) +{ + unsigned long long val; + + /* Handle our dummy "comm" field */ + if (field == &comm) { + const char *name; + + name = get_comm(event, record); + return (unsigned long)name; + } + + pevent_read_number_field(field, record->data, &val); + + if (!(field->flags & FIELD_IS_SIGNED)) + return val; + + switch (field->size) { + case 1: + return (char)val; + case 2: + return (short)val; + case 4: + return (int)val; + case 8: + return (long long)val; + } + return val; +} + +static unsigned long long +get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record); + +static unsigned long long +get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record) +{ + unsigned long long lval, rval; + + lval = get_arg_value(event, arg->exp.left, record); + rval = get_arg_value(event, arg->exp.right, record); + + switch (arg->exp.type) { + case FILTER_EXP_ADD: + return lval + rval; + + case FILTER_EXP_SUB: + return lval - rval; + + case FILTER_EXP_MUL: + return lval * rval; + + case FILTER_EXP_DIV: + return lval / rval; + + case FILTER_EXP_MOD: + return lval % rval; + + case FILTER_EXP_RSHIFT: + return lval >> rval; + + case FILTER_EXP_LSHIFT: + return lval << rval; + + case FILTER_EXP_AND: + return lval & rval; + + case FILTER_EXP_OR: + return lval | rval; + + case FILTER_EXP_XOR: + return lval ^ rval; + + case FILTER_EXP_NOT: + default: + die("error in exp"); + } + return 0; +} + +static unsigned long long +get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record) +{ + switch (arg->type) { + case FILTER_ARG_FIELD: + return get_value(event, arg->field.field, record); + + case FILTER_ARG_VALUE: + if (arg->value.type != FILTER_NUMBER) + die("must have number field!"); + return arg->value.val; + + case FILTER_ARG_EXP: + return get_exp_value(event, arg, record); + + default: + die("oops in filter"); + } + return 0; +} + +static int test_num(struct event_format *event, + struct filter_arg *arg, struct pevent_record *record) +{ + unsigned long long lval, rval; + + lval = get_arg_value(event, arg->num.left, record); + rval = get_arg_value(event, arg->num.right, record); + + switch (arg->num.type) { + case FILTER_CMP_EQ: + return lval == rval; + + case FILTER_CMP_NE: + return lval != rval; + + case FILTER_CMP_GT: + return lval > rval; + + case FILTER_CMP_LT: + return lval < rval; + + case FILTER_CMP_GE: + return lval >= rval; + + case FILTER_CMP_LE: + return lval <= rval; + + default: + /* ?? */ + return 0; + } +} + +static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record) +{ + struct event_format *event; + struct pevent *pevent; + unsigned long long addr; + const char *val = NULL; + static char hex[64]; + + /* If the field is not a string convert it */ + if (arg->str.field->flags & FIELD_IS_STRING) { + val = record->data + arg->str.field->offset; + + /* + * We need to copy the data since we can't be sure the field + * is null terminated. + */ + if (*(val + arg->str.field->size - 1)) { + /* copy it */ + memcpy(arg->str.buffer, val, arg->str.field->size); + /* the buffer is already NULL terminated */ + val = arg->str.buffer; + } + + } else { + event = arg->str.field->event; + pevent = event->pevent; + addr = get_value(event, arg->str.field, record); + + if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG)) + /* convert to a kernel symbol */ + val = pevent_find_function(pevent, addr); + + if (val == NULL) { + /* just use the hex of the string name */ + snprintf(hex, 64, "0x%llx", addr); + val = hex; + } + } + + return val; +} + +static int test_str(struct event_format *event, + struct filter_arg *arg, struct pevent_record *record) +{ + const char *val; + + if (arg->str.field == &comm) + val = get_comm(event, record); + else + val = get_field_str(arg, record); + + switch (arg->str.type) { + case FILTER_CMP_MATCH: + return strcmp(val, arg->str.val) == 0; + + case FILTER_CMP_NOT_MATCH: + return strcmp(val, arg->str.val) != 0; + + case FILTER_CMP_REGEX: + /* Returns zero on match */ + return !regexec(&arg->str.reg, val, 0, NULL, 0); + + case FILTER_CMP_NOT_REGEX: + return regexec(&arg->str.reg, val, 0, NULL, 0); + + default: + /* ?? */ + return 0; + } +} + +static int test_op(struct event_format *event, + struct filter_arg *arg, struct pevent_record *record) +{ + switch (arg->op.type) { + case FILTER_OP_AND: + return test_filter(event, arg->op.left, record) && + test_filter(event, arg->op.right, record); + + case FILTER_OP_OR: + return test_filter(event, arg->op.left, record) || + test_filter(event, arg->op.right, record); + + case FILTER_OP_NOT: + return !test_filter(event, arg->op.right, record); + + default: + /* ?? */ + return 0; + } +} + +static int test_filter(struct event_format *event, + struct filter_arg *arg, struct pevent_record *record) +{ + switch (arg->type) { + case FILTER_ARG_BOOLEAN: + /* easy case */ + return arg->boolean.value; + + case FILTER_ARG_OP: + return test_op(event, arg, record); + + case FILTER_ARG_NUM: + return test_num(event, arg, record); + + case FILTER_ARG_STR: + return test_str(event, arg, record); + + case FILTER_ARG_EXP: + case FILTER_ARG_VALUE: + case FILTER_ARG_FIELD: + /* + * Expressions, fields and values evaluate + * to true if they return non zero + */ + return !!get_arg_value(event, arg, record); + + default: + die("oops!"); + /* ?? */ + return 0; + } +} + +/** + * pevent_event_filtered - return true if event has filter + * @filter: filter struct with filter information + * @event_id: event id to test if filter exists + * + * Returns 1 if filter found for @event_id + * otherwise 0; + */ +int pevent_event_filtered(struct event_filter *filter, + int event_id) +{ + struct filter_type *filter_type; + + if (!filter->filters) + return 0; + + filter_type = find_filter_type(filter, event_id); + + return filter_type ? 1 : 0; +} + +/** + * pevent_filter_match - test if a record matches a filter + * @filter: filter struct with filter information + * @record: the record to test against the filter + * + * Returns: + * 1 - filter found for event and @record matches + * 0 - filter found for event and @record does not match + * -1 - no filter found for @record's event + * -2 - if no filters exist + */ +int pevent_filter_match(struct event_filter *filter, + struct pevent_record *record) +{ + struct pevent *pevent = filter->pevent; + struct filter_type *filter_type; + int event_id; + + if (!filter->filters) + return FILTER_NONE; + + event_id = pevent_data_type(pevent, record); + + filter_type = find_filter_type(filter, event_id); + + if (!filter_type) + return FILTER_NOEXIST; + + return test_filter(filter_type->event, filter_type->filter, record) ? + FILTER_MATCH : FILTER_MISS; +} + +static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) +{ + char *str = NULL; + char *left = NULL; + char *right = NULL; + char *op = NULL; + int left_val = -1; + int right_val = -1; + int val; + int len; + + switch (arg->op.type) { + case FILTER_OP_AND: + op = "&&"; + /* fall through */ + case FILTER_OP_OR: + if (!op) + op = "||"; + + left = arg_to_str(filter, arg->op.left); + right = arg_to_str(filter, arg->op.right); + if (!left || !right) + break; + + /* Try to consolidate boolean values */ + if (strcmp(left, "TRUE") == 0) + left_val = 1; + else if (strcmp(left, "FALSE") == 0) + left_val = 0; + + if (strcmp(right, "TRUE") == 0) + right_val = 1; + else if (strcmp(right, "FALSE") == 0) + right_val = 0; + + if (left_val >= 0) { + if ((arg->op.type == FILTER_OP_AND && !left_val) || + (arg->op.type == FILTER_OP_OR && left_val)) { + /* Just return left value */ + str = left; + left = NULL; + break; + } + if (right_val >= 0) { + /* just evaluate this. */ + val = 0; + switch (arg->op.type) { + case FILTER_OP_AND: + val = left_val && right_val; + break; + case FILTER_OP_OR: + val = left_val || right_val; + break; + default: + break; + } + str = malloc_or_die(6); + if (val) + strcpy(str, "TRUE"); + else + strcpy(str, "FALSE"); + break; + } + } + if (right_val >= 0) { + if ((arg->op.type == FILTER_OP_AND && !right_val) || + (arg->op.type == FILTER_OP_OR && right_val)) { + /* Just return right value */ + str = right; + right = NULL; + break; + } + /* The right value is meaningless */ + str = left; + left = NULL; + break; + } + + len = strlen(left) + strlen(right) + strlen(op) + 10; + str = malloc_or_die(len); + snprintf(str, len, "(%s) %s (%s)", + left, op, right); + break; + + case FILTER_OP_NOT: + op = "!"; + right = arg_to_str(filter, arg->op.right); + if (!right) + break; + + /* See if we can consolidate */ + if (strcmp(right, "TRUE") == 0) + right_val = 1; + else if (strcmp(right, "FALSE") == 0) + right_val = 0; + if (right_val >= 0) { + /* just return the opposite */ + str = malloc_or_die(6); + if (right_val) + strcpy(str, "FALSE"); + else + strcpy(str, "TRUE"); + break; + } + len = strlen(right) + strlen(op) + 3; + str = malloc_or_die(len); + snprintf(str, len, "%s(%s)", op, right); + break; + + default: + /* ?? */ + break; + } + free(left); + free(right); + return str; +} + +static char *val_to_str(struct event_filter *filter, struct filter_arg *arg) +{ + char *str; + + str = malloc_or_die(30); + + snprintf(str, 30, "%lld", arg->value.val); + + return str; +} + +static char *field_to_str(struct event_filter *filter, struct filter_arg *arg) +{ + return strdup(arg->field.field->name); +} + +static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) +{ + char *lstr; + char *rstr; + char *op; + char *str = NULL; + int len; + + lstr = arg_to_str(filter, arg->exp.left); + rstr = arg_to_str(filter, arg->exp.right); + if (!lstr || !rstr) + goto out; + + switch (arg->exp.type) { + case FILTER_EXP_ADD: + op = "+"; + break; + case FILTER_EXP_SUB: + op = "-"; + break; + case FILTER_EXP_MUL: + op = "*"; + break; + case FILTER_EXP_DIV: + op = "/"; + break; + case FILTER_EXP_MOD: + op = "%"; + break; + case FILTER_EXP_RSHIFT: + op = ">>"; + break; + case FILTER_EXP_LSHIFT: + op = "<<"; + break; + case FILTER_EXP_AND: + op = "&"; + break; + case FILTER_EXP_OR: + op = "|"; + break; + case FILTER_EXP_XOR: + op = "^"; + break; + default: + die("oops in exp"); + } + + len = strlen(op) + strlen(lstr) + strlen(rstr) + 4; + str = malloc_or_die(len); + snprintf(str, len, "%s %s %s", lstr, op, rstr); +out: + free(lstr); + free(rstr); + + return str; +} + +static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) +{ + char *lstr; + char *rstr; + char *str = NULL; + char *op = NULL; + int len; + + lstr = arg_to_str(filter, arg->num.left); + rstr = arg_to_str(filter, arg->num.right); + if (!lstr || !rstr) + goto out; + + switch (arg->num.type) { + case FILTER_CMP_EQ: + op = "=="; + /* fall through */ + case FILTER_CMP_NE: + if (!op) + op = "!="; + /* fall through */ + case FILTER_CMP_GT: + if (!op) + op = ">"; + /* fall through */ + case FILTER_CMP_LT: + if (!op) + op = "<"; + /* fall through */ + case FILTER_CMP_GE: + if (!op) + op = ">="; + /* fall through */ + case FILTER_CMP_LE: + if (!op) + op = "<="; + + len = strlen(lstr) + strlen(op) + strlen(rstr) + 4; + str = malloc_or_die(len); + sprintf(str, "%s %s %s", lstr, op, rstr); + + break; + + default: + /* ?? */ + break; + } + +out: + free(lstr); + free(rstr); + return str; +} + +static char *str_to_str(struct event_filter *filter, struct filter_arg *arg) +{ + char *str = NULL; + char *op = NULL; + int len; + + switch (arg->str.type) { + case FILTER_CMP_MATCH: + op = "=="; + /* fall through */ + case FILTER_CMP_NOT_MATCH: + if (!op) + op = "!="; + /* fall through */ + case FILTER_CMP_REGEX: + if (!op) + op = "=~"; + /* fall through */ + case FILTER_CMP_NOT_REGEX: + if (!op) + op = "!~"; + + len = strlen(arg->str.field->name) + strlen(op) + + strlen(arg->str.val) + 6; + str = malloc_or_die(len); + snprintf(str, len, "%s %s \"%s\"", + arg->str.field->name, + op, arg->str.val); + break; + + default: + /* ?? */ + break; + } + return str; +} + +static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg) +{ + char *str; + + switch (arg->type) { + case FILTER_ARG_BOOLEAN: + str = malloc_or_die(6); + if (arg->boolean.value) + strcpy(str, "TRUE"); + else + strcpy(str, "FALSE"); + return str; + + case FILTER_ARG_OP: + return op_to_str(filter, arg); + + case FILTER_ARG_NUM: + return num_to_str(filter, arg); + + case FILTER_ARG_STR: + return str_to_str(filter, arg); + + case FILTER_ARG_VALUE: + return val_to_str(filter, arg); + + case FILTER_ARG_FIELD: + return field_to_str(filter, arg); + + case FILTER_ARG_EXP: + return exp_to_str(filter, arg); + + default: + /* ?? */ + return NULL; + } + +} + +/** + * pevent_filter_make_string - return a string showing the filter + * @filter: filter struct with filter information + * @event_id: the event id to return the filter string with + * + * Returns a string that displays the filter contents. + * This string must be freed with free(str). + * NULL is returned if no filter is found. + */ +char * +pevent_filter_make_string(struct event_filter *filter, int event_id) +{ + struct filter_type *filter_type; + + if (!filter->filters) + return NULL; + + filter_type = find_filter_type(filter, event_id); + + if (!filter_type) + return NULL; + + return arg_to_str(filter, filter_type->filter); +} + +/** + * pevent_filter_compare - compare two filters and return if they are the same + * @filter1: Filter to compare with @filter2 + * @filter2: Filter to compare with @filter1 + * + * Returns: + * 1 if the two filters hold the same content. + * 0 if they do not. + */ +int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2) +{ + struct filter_type *filter_type1; + struct filter_type *filter_type2; + char *str1, *str2; + int result; + int i; + + /* Do the easy checks first */ + if (filter1->filters != filter2->filters) + return 0; + if (!filter1->filters && !filter2->filters) + return 1; + + /* + * Now take a look at each of the events to see if they have the same + * filters to them. + */ + for (i = 0; i < filter1->filters; i++) { + filter_type1 = &filter1->event_filters[i]; + filter_type2 = find_filter_type(filter2, filter_type1->event_id); + if (!filter_type2) + break; + if (filter_type1->filter->type != filter_type2->filter->type) + break; + switch (filter_type1->filter->type) { + case FILTER_TRIVIAL_FALSE: + case FILTER_TRIVIAL_TRUE: + /* trivial types just need the type compared */ + continue; + default: + break; + } + /* The best way to compare complex filters is with strings */ + str1 = arg_to_str(filter1, filter_type1->filter); + str2 = arg_to_str(filter2, filter_type2->filter); + if (str1 && str2) + result = strcmp(str1, str2) != 0; + else + /* bail out if allocation fails */ + result = 1; + + free(str1); + free(str2); + if (result) + break; + } + + if (i < filter1->filters) + return 0; + return 1; +} + diff --git a/traceevent/parse-utils.c b/traceevent/parse-utils.c new file mode 100644 index 0000000..bba701c --- /dev/null +++ b/traceevent/parse-utils.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <errno.h> + +#define __weak __attribute__((weak)) + +void __vdie(const char *fmt, va_list ap) +{ + int ret = errno; + + if (errno) + perror("trace-cmd"); + else + ret = -1; + + fprintf(stderr, " "); + vfprintf(stderr, fmt, ap); + + fprintf(stderr, "\n"); + exit(ret); +} + +void __die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + __vdie(fmt, ap); + va_end(ap); +} + +void __weak die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + __vdie(fmt, ap); + va_end(ap); +} + +void __vwarning(const char *fmt, va_list ap) +{ + if (errno) + perror("trace-cmd"); + errno = 0; + + fprintf(stderr, " "); + vfprintf(stderr, fmt, ap); + + fprintf(stderr, "\n"); +} + +void __warning(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + __vwarning(fmt, ap); + va_end(ap); +} + +void __weak warning(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + __vwarning(fmt, ap); + va_end(ap); +} + +void __vpr_stat(const char *fmt, va_list ap) +{ + vprintf(fmt, ap); + printf("\n"); +} + +void __pr_stat(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + __vpr_stat(fmt, ap); + va_end(ap); +} + +void __weak vpr_stat(const char *fmt, va_list ap) +{ + __vpr_stat(fmt, ap); +} + +void __weak pr_stat(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + __vpr_stat(fmt, ap); + va_end(ap); +} + +void __weak *malloc_or_die(unsigned int size) +{ + void *data; + + data = malloc(size); + if (!data) + die("malloc"); + return data; +} diff --git a/traceevent/trace-seq.c b/traceevent/trace-seq.c new file mode 100644 index 0000000..d7f2e68 --- /dev/null +++ b/traceevent/trace-seq.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include "event-parse.h" +#include "event-utils.h" + +/* + * The TRACE_SEQ_POISON is to catch the use of using + * a trace_seq structure after it was destroyed. + */ +#define TRACE_SEQ_POISON ((void *)0xdeadbeef) +#define TRACE_SEQ_CHECK(s) \ +do { \ + if ((s)->buffer == TRACE_SEQ_POISON) \ + die("Usage of trace_seq after it was destroyed"); \ +} while (0) + +/** + * trace_seq_init - initialize the trace_seq structure + * @s: a pointer to the trace_seq structure to initialize + */ +void trace_seq_init(struct trace_seq *s) +{ + s->len = 0; + s->readpos = 0; + s->buffer_size = TRACE_SEQ_BUF_SIZE; + s->buffer = malloc_or_die(s->buffer_size); +} + +/** + * trace_seq_reset - re-initialize the trace_seq structure + * @s: a pointer to the trace_seq structure to reset + */ +void trace_seq_reset(struct trace_seq *s) +{ + if (!s) + return; + TRACE_SEQ_CHECK(s); + s->len = 0; + s->readpos = 0; +} + +/** + * trace_seq_destroy - free up memory of a trace_seq + * @s: a pointer to the trace_seq to free the buffer + * + * Only frees the buffer, not the trace_seq struct itself. + */ +void trace_seq_destroy(struct trace_seq *s) +{ + if (!s) + return; + TRACE_SEQ_CHECK(s); + free(s->buffer); + s->buffer = TRACE_SEQ_POISON; +} + +static void expand_buffer(struct trace_seq *s) +{ + s->buffer_size += TRACE_SEQ_BUF_SIZE; + s->buffer = realloc(s->buffer, s->buffer_size); + if (!s->buffer) + die("Can't allocate trace_seq buffer memory"); +} + +/** + * trace_seq_printf - sequence printing of trace information + * @s: trace sequence descriptor + * @fmt: printf format string + * + * It returns 0 if the trace oversizes the buffer's free + * space, 1 otherwise. + * + * The tracer may use either sequence operations or its own + * copy to user routines. To simplify formating of a trace + * trace_seq_printf is used to store strings into a special + * buffer (@s). Then the output may be either used by + * the sequencer or pulled into another buffer. + */ +int +trace_seq_printf(struct trace_seq *s, const char *fmt, ...) +{ + va_list ap; + int len; + int ret; + + TRACE_SEQ_CHECK(s); + + try_again: + len = (s->buffer_size - 1) - s->len; + + va_start(ap, fmt); + ret = vsnprintf(s->buffer + s->len, len, fmt, ap); + va_end(ap); + + if (ret >= len) { + expand_buffer(s); + goto try_again; + } + + s->len += ret; + + return 1; +} + +/** + * trace_seq_vprintf - sequence printing of trace information + * @s: trace sequence descriptor + * @fmt: printf format string + * + * The tracer may use either sequence operations or its own + * copy to user routines. To simplify formating of a trace + * trace_seq_printf is used to store strings into a special + * buffer (@s). Then the output may be either used by + * the sequencer or pulled into another buffer. + */ +int +trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) +{ + int len; + int ret; + + TRACE_SEQ_CHECK(s); + + try_again: + len = (s->buffer_size - 1) - s->len; + + ret = vsnprintf(s->buffer + s->len, len, fmt, args); + + if (ret >= len) { + expand_buffer(s); + goto try_again; + } + + s->len += ret; + + return len; +} + +/** + * trace_seq_puts - trace sequence printing of simple string + * @s: trace sequence descriptor + * @str: simple string to record + * + * The tracer may use either the sequence operations or its own + * copy to user routines. This function records a simple string + * into a special buffer (@s) for later retrieval by a sequencer + * or other mechanism. + */ +int trace_seq_puts(struct trace_seq *s, const char *str) +{ + int len; + + TRACE_SEQ_CHECK(s); + + len = strlen(str); + + while (len > ((s->buffer_size - 1) - s->len)) + expand_buffer(s); + + memcpy(s->buffer + s->len, str, len); + s->len += len; + + return len; +} + +int trace_seq_putc(struct trace_seq *s, unsigned char c) +{ + TRACE_SEQ_CHECK(s); + + while (s->len >= (s->buffer_size - 1)) + expand_buffer(s); + + s->buffer[s->len++] = c; + + return 1; +} + +void trace_seq_terminate(struct trace_seq *s) +{ + TRACE_SEQ_CHECK(s); + + /* There's always one character left on the buffer */ + s->buffer[s->len] = 0; +} + +int trace_seq_do_printf(struct trace_seq *s) +{ + TRACE_SEQ_CHECK(s); + return printf("%.*s", s->len, s->buffer); +} |