From ce2fd89c28c143cf64c3f6ea95179b74bbaf6906 Mon Sep 17 00:00:00 2001 From: Siarhei Siniak Date: Sat, 31 Dec 2022 19:45:03 +0300 Subject: [PATCH] [~] Refactor --- deps/cpulimit-fork/.gitignore | 5 + deps/cpulimit-fork/LICENSE | 16 + deps/cpulimit-fork/Makefile | 8 + deps/cpulimit-fork/README.md | 42 ++ deps/cpulimit-fork/pacman-package/.SRCINFO | 19 + deps/cpulimit-fork/pacman-package/PKGBUILD | 42 ++ .../cpulimit-fork/pacman-package/cpulimit-git | 1 + .../cpulimit-git-1-1-x86_64.pkg.tar.zst | Bin 0 -> 18274 bytes deps/cpulimit-fork/pacman-package/patch | 12 + .../pkg/cpulimit-git/.BUILDINFO | 654 ++++++++++++++++++ .../pacman-package/pkg/cpulimit-git/.MTREE | Bin 0 -> 359 bytes .../pacman-package/pkg/cpulimit-git/.PKGINFO | 16 + .../pkg/cpulimit-git/usr/bin/cpulimit | Bin 0 -> 30920 bytes .../pacman-package/src/cpulimit-git | 1 + deps/cpulimit-fork/src/Makefile | 28 + deps/cpulimit-fork/src/cpulimit.c | 555 +++++++++++++++ deps/cpulimit-fork/src/list.c | 148 ++++ deps/cpulimit-fork/src/list.h | 138 ++++ deps/cpulimit-fork/src/memrchr.c | 38 + deps/cpulimit-fork/src/process_group.c | 251 +++++++ deps/cpulimit-fork/src/process_group.h | 59 ++ deps/cpulimit-fork/src/process_iterator.c | 49 ++ deps/cpulimit-fork/src/process_iterator.h | 101 +++ .../src/process_iterator_apple.c | 148 ++++ .../src/process_iterator_freebsd.c | 119 ++++ .../src/process_iterator_linux.c | 181 +++++ deps/cpulimit-fork/tests/Makefile | 23 + deps/cpulimit-fork/tests/busy.c | 29 + .../tests/process_iterator_test.c | 242 +++++++ deps/cpulimit-fork/tests/run_tests.sh | 0 30 files changed, 2925 insertions(+) create mode 100644 deps/cpulimit-fork/.gitignore create mode 100644 deps/cpulimit-fork/LICENSE create mode 100644 deps/cpulimit-fork/Makefile create mode 100644 deps/cpulimit-fork/README.md create mode 100644 deps/cpulimit-fork/pacman-package/.SRCINFO create mode 100644 deps/cpulimit-fork/pacman-package/PKGBUILD create mode 120000 deps/cpulimit-fork/pacman-package/cpulimit-git create mode 100644 deps/cpulimit-fork/pacman-package/cpulimit-git-1-1-x86_64.pkg.tar.zst create mode 100644 deps/cpulimit-fork/pacman-package/patch create mode 100644 deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.BUILDINFO create mode 100644 deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.MTREE create mode 100644 deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.PKGINFO create mode 100755 deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/usr/bin/cpulimit create mode 120000 deps/cpulimit-fork/pacman-package/src/cpulimit-git create mode 100644 deps/cpulimit-fork/src/Makefile create mode 100644 deps/cpulimit-fork/src/cpulimit.c create mode 100644 deps/cpulimit-fork/src/list.c create mode 100644 deps/cpulimit-fork/src/list.h create mode 100644 deps/cpulimit-fork/src/memrchr.c create mode 100644 deps/cpulimit-fork/src/process_group.c create mode 100644 deps/cpulimit-fork/src/process_group.h create mode 100644 deps/cpulimit-fork/src/process_iterator.c create mode 100644 deps/cpulimit-fork/src/process_iterator.h create mode 100644 deps/cpulimit-fork/src/process_iterator_apple.c create mode 100644 deps/cpulimit-fork/src/process_iterator_freebsd.c create mode 100644 deps/cpulimit-fork/src/process_iterator_linux.c create mode 100644 deps/cpulimit-fork/tests/Makefile create mode 100644 deps/cpulimit-fork/tests/busy.c create mode 100644 deps/cpulimit-fork/tests/process_iterator_test.c create mode 100644 deps/cpulimit-fork/tests/run_tests.sh diff --git a/deps/cpulimit-fork/.gitignore b/deps/cpulimit-fork/.gitignore new file mode 100644 index 0000000..70e4875 --- /dev/null +++ b/deps/cpulimit-fork/.gitignore @@ -0,0 +1,5 @@ +*.o +*~ +src/cpulimit +busy +process_iterator_test diff --git a/deps/cpulimit-fork/LICENSE b/deps/cpulimit-fork/LICENSE new file mode 100644 index 0000000..97f263e --- /dev/null +++ b/deps/cpulimit-fork/LICENSE @@ -0,0 +1,16 @@ +cpulimit - a CPU usage limiter for Linux +Copyright (C) 2005-2012, by: Angelo Marletta + +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 Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/deps/cpulimit-fork/Makefile b/deps/cpulimit-fork/Makefile new file mode 100644 index 0000000..b9c655a --- /dev/null +++ b/deps/cpulimit-fork/Makefile @@ -0,0 +1,8 @@ +default: build + +build: + cd src && $(MAKE) + cd tests && $(MAKE) + +pacman: build + cd pacman-package && makepkg -e -f diff --git a/deps/cpulimit-fork/README.md b/deps/cpulimit-fork/README.md new file mode 100644 index 0000000..019579d --- /dev/null +++ b/deps/cpulimit-fork/README.md @@ -0,0 +1,42 @@ +CPULIMIT +======== + +Cpulimit is a tool which limits the CPU usage of a process (expressed in percentage, not in CPU time). It is useful to control batch jobs, when you don't want them to eat too many CPU cycles. The goal is prevent a process from running for more than a specified time ratio. It does not change the nice value or other scheduling priority settings, but the real CPU usage. Also, it is able to adapt itself to the overall system load, dynamically and quickly. +The control of the used CPU amount is done sending SIGSTOP and SIGCONT POSIX signals to processes. +All the children processes and threads of the specified process will share the same percentage of CPU. + +Developed by Angelo Marletta. +Please send your feedback, bug reports, feature requests or just thanks. + + +Get the latest source code +-------------------------- + +The latest available code is here: + +https://github.com/opsengine/cpulimit + + +Install instructions +-------------------- + +On Linux/OS X: + + $ make + # cp src/cpulimit /usr/bin + +On FreeBSD: + + $ gmake + # cp src/cpulimit /usr/bin + +Run unit tests: + + $ ./tests/process_iterator_test + + +Contributions +------------- + +You are welcome to contribute to cpulimit with bugfixes, new features, or support for a new OS. +If you want to submit a pull request, please do it on the branch develop and make sure all tests pass. diff --git a/deps/cpulimit-fork/pacman-package/.SRCINFO b/deps/cpulimit-fork/pacman-package/.SRCINFO new file mode 100644 index 0000000..3444770 --- /dev/null +++ b/deps/cpulimit-fork/pacman-package/.SRCINFO @@ -0,0 +1,19 @@ +pkgbase = cpulimit-git + pkgdesc = Limit cpu usage in %. Actualy sends SIGSTOP/SIGCONT + pkgver = 113.f4d2682 + pkgrel = 1 + url = https://github.com/opsengine/cpulimit + arch = i686 + arch = x86_64 + license = GPL + makedepends = git + depends = glibc + provides = cpulimit + conflicts = cpulimit + source = cpulimit-git::git+https://github.com/opsengine/cpulimit.git + source = patch + md5sums = SKIP + md5sums = 524d8ec2fa0d6f5c4e2f453929c94c3e + +pkgname = cpulimit-git + diff --git a/deps/cpulimit-fork/pacman-package/PKGBUILD b/deps/cpulimit-fork/pacman-package/PKGBUILD new file mode 100644 index 0000000..046cad6 --- /dev/null +++ b/deps/cpulimit-fork/pacman-package/PKGBUILD @@ -0,0 +1,42 @@ +# This is an example PKGBUILD file. Use this as a start to creating your own, +# and remove these comments. For more information, see 'man PKGBUILD'. +# NOTE: Please fill out the license field for your package! If it is unknown, +# then please put 'unknown'. + +# See http://wiki.archlinux.org/index.php/VCS_PKGBUILD_Guidelines +# for more information on packaging from GIT sources. + +# Maintainer: Mike Lenzen +pkgname=cpulimit-git +pkgver=1 +pkgrel=1 +pkgdesc="Limit cpu usage in %. Actualy sends SIGSTOP/SIGCONT" +arch=('i686' 'x86_64') +url="https://github.com/opsengine/cpulimit" +license=('GPL') +depends=('glibc') +makedepends=('git') +provides=('cpulimit') +conflicts=('cpulimit') +source=("patch") + +md5sums=('SKIP' + '524d8ec2fa0d6f5c4e2f453929c94c3e') + +build() { + rm $pkgname + ln -sf $srcdir/../.. $pkgname + cd "$srcdir/$pkgname" + + make +} + +# Patch to remove sysctl.h - removed from linxu +prepare() { + cd "$srcdir/$pkgname" + patch --forward --strip=1 --input="${srcdir}/patch" +} + +package() { + install -D -m0755 $srcdir/$pkgname/src/cpulimit $pkgdir/usr/bin/cpulimit +} diff --git a/deps/cpulimit-fork/pacman-package/cpulimit-git b/deps/cpulimit-fork/pacman-package/cpulimit-git new file mode 120000 index 0000000..4ffd5d6 --- /dev/null +++ b/deps/cpulimit-fork/pacman-package/cpulimit-git @@ -0,0 +1 @@ +/home/nartes/Documents/current/freelance-project-34-marketing-blog/deps/cpulimit-fork/pacman-package/.. \ No newline at end of file diff --git a/deps/cpulimit-fork/pacman-package/cpulimit-git-1-1-x86_64.pkg.tar.zst b/deps/cpulimit-fork/pacman-package/cpulimit-git-1-1-x86_64.pkg.tar.zst new file mode 100644 index 0000000000000000000000000000000000000000..0742835c1ad2b56f5a357c22e7be227734f9683e GIT binary patch literal 18274 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 literal 0 KcmV+b0RR6000031 diff --git a/deps/cpulimit-fork/pacman-package/patch b/deps/cpulimit-fork/pacman-package/patch new file mode 100644 index 0000000..2cab992 --- /dev/null +++ b/deps/cpulimit-fork/pacman-package/patch @@ -0,0 +1,12 @@ +Only in cpulimit-git: patch~ +diff --unified --recursive --text cpulimit-git/src/cpulimit.c cpulimit-git-patched/src/cpulimit.c +--- cpulimit-git/src/cpulimit.c 2021-05-23 14:30:31.441532911 -0600 ++++ cpulimit-git-patched/src/cpulimit.c 2021-05-23 14:29:24.612229881 -0600 +@@ -38,7 +38,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.BUILDINFO b/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.BUILDINFO new file mode 100644 index 0000000..46bb6b4 --- /dev/null +++ b/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.BUILDINFO @@ -0,0 +1,654 @@ +format = 2 +pkgname = cpulimit-git +pkgbase = cpulimit-git +pkgver = 1-1 +pkgarch = x86_64 +pkgbuild_sha256sum = b44eb50d49132f14ad7e35865b0478ea7f0b8b9e623e54dd829ef84b4f7848e4 +packager = Unknown Packager +builddate = 1672505075 +builddir = /home/nartes/Documents/current/freelance-project-34-marketing-blog/deps/cpulimit-fork/pacman-package +startdir = /home/nartes/Documents/current/freelance-project-34-marketing-blog/deps/cpulimit-fork/pacman-package +buildtool = makepkg +buildtoolver = 6.0.2 +buildenv = !distcc +buildenv = color +buildenv = !ccache +buildenv = check +buildenv = !sign +options = strip +options = docs +options = !libtool +options = !staticlibs +options = emptydirs +options = zipman +options = purge +options = !debug +options = !lto +installed = a52dec-0.7.4-12-x86_64 +installed = abseil-cpp-20220623.1-1-x86_64 +installed = accountsservice-22.08.8-2-x86_64 +installed = acl-2.3.1-2-x86_64 +installed = adobe-source-code-pro-fonts-2.038ro+1.058it+1.018var-1-any +installed = adwaita-cursors-43-2-any +installed = adwaita-icon-theme-43-2-any +installed = alsa-lib-1.2.8-1-x86_64 +installed = alsa-plugins-1:1.2.7.1-1-x86_64 +installed = alsa-topology-conf-1.2.5.1-1-any +installed = alsa-ucm-conf-1.2.8-1-any +installed = aom-3.5.0-1-x86_64 +installed = archlinux-keyring-20221220-1-any +installed = argon2-20190702-4-x86_64 +installed = at-spi2-core-2.46.0-2-x86_64 +installed = atkmm-2.28.3-1-x86_64 +installed = attr-2.5.1-2-x86_64 +installed = audit-3.0.8-1-x86_64 +installed = autoconf-2.71-1-any +installed = automake-1.16.5-1-any +installed = avahi-0.8+22+gfd482a7-3-x86_64 +installed = base-3-1-any +installed = bash-5.1.016-1-x86_64 +installed = bemenu-0.6.13-1-x86_64 +installed = bemenu-wayland-0.6.13-1-x86_64 +installed = binutils-2.39-4-x86_64 +installed = bison-3.8.2-4-x86_64 +installed = bluez-5.66-1-x86_64 +installed = bluez-libs-5.66-1-x86_64 +installed = bluez-utils-5.66-1-x86_64 +installed = bolt-0.9.4-1-x86_64 +installed = broadcom-wl-6.30.223.271-436-x86_64 +installed = brotli-1.0.9-9-x86_64 +installed = btrfs-progs-6.1-1-x86_64 +installed = bubblewrap-0.7.0-1-x86_64 +installed = bzip2-1.0.8-5-x86_64 +installed = ca-certificates-20220905-1-any +installed = ca-certificates-mozilla-3.86-1-x86_64 +installed = ca-certificates-utils-20220905-1-any +installed = cairo-1.17.6-2-x86_64 +installed = cairomm-1.14.4-1-x86_64 +installed = cantarell-fonts-1:0.303.1-1-any +installed = cifs-utils-7.0-2-x86_64 +installed = cmake-3.25.1-1-x86_64 +installed = colord-1.4.6-1-x86_64 +installed = colord-gtk-common-0.3.0-2-x86_64 +installed = colord-gtk4-0.3.0-2-x86_64 +installed = coreutils-9.1-3-x86_64 +installed = cpulimit-git-113.f4d2682-1-x86_64 +installed = cpupower-6.1-1-x86_64 +installed = cracklib-2.9.8-1-x86_64 +installed = cryptsetup-2.6.0-1-x86_64 +installed = cups-pk-helper-0.2.7-1-x86_64 +installed = curl-7.87.0-1-x86_64 +installed = dav1d-1.0.0-1-x86_64 +installed = db5.3-5.3.28-2-x86_64 +installed = dbus-1.14.4-1-x86_64 +installed = dbus-python-1.2.18-3-x86_64 +installed = dconf-0.40.0-2-x86_64 +installed = debugedit-5.0-4-x86_64 +installed = default-cursors-2-1-any +installed = desktop-file-utils-0.26-2-x86_64 +installed = device-mapper-2.03.18-1-x86_64 +installed = dhcpcd-9.4.1-1-x86_64 +installed = diffutils-3.8-1-x86_64 +installed = dmenu-5.2-1-x86_64 +installed = dmg2img-1.6.7-5-x86_64 +installed = dmraid-1.0.0.rc16.3-14-x86_64 +installed = dnssec-anchors-20190629-3-any +installed = dosfstools-4.2-2-x86_64 +installed = double-conversion-3.2.1-1-x86_64 +installed = duktape-2.7.0-5-x86_64 +installed = e2fsprogs-1.46.5-4-x86_64 +installed = efibootmgr-18-1-x86_64 +installed = efivar-38-2-x86_64 +installed = egl-wayland-2:1.1.11-2-x86_64 +installed = eglexternalplatform-1.1-2-any +installed = enchant-2.3.3-2-x86_64 +installed = eog-43.1-1-x86_64 +installed = exempi-2.6.3-1-x86_64 +installed = exiv2-0.27.5-3-x86_64 +installed = expat-2.5.0-1-x86_64 +installed = faad2-2.10.1-1-x86_64 +installed = fakeroot-1.30.1-1-x86_64 +installed = ffmpeg-2:5.1.2-1-x86_64 +installed = ffmpeg4.4-4.4.2-3-x86_64 +installed = fftw-3.3.10-3-x86_64 +installed = file-5.44-1-x86_64 +installed = filesystem-2022.10.18-1-x86_64 +installed = findutils-4.9.0-1-x86_64 +installed = flac-1.4.2-1-x86_64 +installed = flex-2.6.4-3-x86_64 +installed = fontconfig-2:2.14.1-2-x86_64 +installed = freeglut-3.4.0-1-x86_64 +installed = freetype2-2.12.1-1-x86_64 +installed = fribidi-1.0.12-1-x86_64 +installed = fuse-common-3.12.0-1-x86_64 +installed = fuse3-3.12.0-1-x86_64 +installed = gawk-5.2.1-1-x86_64 +installed = gc-8.2.2-1-x86_64 +installed = gcc-12.2.0-1-x86_64 +installed = gcc-libs-12.2.0-1-x86_64 +installed = gcr-3.41.1-3-x86_64 +installed = gcr-4-4.0.0-1-x86_64 +installed = gdbm-1.23-1-x86_64 +installed = gdk-pixbuf2-2.42.10-1-x86_64 +installed = geoclue-2.6.0-3-x86_64 +installed = geocode-glib-2-3.26.4-2-x86_64 +installed = geocode-glib-common-3.26.4-2-x86_64 +installed = gettext-0.21.1-2-x86_64 +installed = giflib-5.2.1-2-x86_64 +installed = git-2.39.0-1-x86_64 +installed = glib-networking-1:2.74.0-1-x86_64 +installed = glib2-2.74.4-1-x86_64 +installed = glibc-2.36-6-x86_64 +installed = glibmm-2.66.5-1-x86_64 +installed = glibmm-2.68-2.74.0-1-x86_64 +installed = glslang-11.11.0-1-x86_64 +installed = glu-9.0.2-3-x86_64 +installed = gmp-6.2.1-2-x86_64 +installed = gnome-autoar-0.4.3-2-x86_64 +installed = gnome-bluetooth-3.0-42.5-1-x86_64 +installed = gnome-color-manager-3.36.0+r42+g90481514-1-x86_64 +installed = gnome-control-center-43.2-1-x86_64 +installed = gnome-desktop-1:43-1-x86_64 +installed = gnome-desktop-4-1:43-1-x86_64 +installed = gnome-desktop-common-1:43-1-x86_64 +installed = gnome-disk-utility-43.0-1-x86_64 +installed = gnome-online-accounts-3.46.0-1-x86_64 +installed = gnome-settings-daemon-43.0-2-x86_64 +installed = gnome-terminal-3.46.7-1-x86_64 +installed = gnu-free-fonts-20120503-8-any +installed = gnu-netcat-0.7.1-9-x86_64 +installed = gnupg-2.2.40-1-x86_64 +installed = gnutls-3.7.8-4-x86_64 +installed = go-2:1.19.4-1-x86_64 +installed = gobject-introspection-runtime-1.74.0-1-x86_64 +installed = google-chrome-108.0.5359.124-1-x86_64 +installed = gperftools-2.10-1-x86_64 +installed = gpgme-1.18.0-1-x86_64 +installed = gpm-1.20.7.r38.ge82d1a6-4-x86_64 +installed = gptfdisk-1.0.9-2-x86_64 +installed = graphene-1.10.8-1-x86_64 +installed = graphite-1:1.3.14-2-x86_64 +installed = grep-3.8-2-x86_64 +installed = groff-1.22.4-7-x86_64 +installed = gsettings-desktop-schemas-43.0-1-any +installed = gsm-1.0.22-1-x86_64 +installed = gsound-1.0.3-2-x86_64 +installed = gst-plugins-bad-libs-1.20.5-1-x86_64 +installed = gst-plugins-base-libs-1.20.5-1-x86_64 +installed = gstreamer-1.20.5-1-x86_64 +installed = gtk-update-icon-cache-1:4.8.3-1-x86_64 +installed = gtk3-1:3.24.36-1-x86_64 +installed = gtk4-1:4.8.3-1-x86_64 +installed = gtkmm3-3.24.7-1-x86_64 +installed = guile-3.0.8-3-x86_64 +installed = gupnp-dlna-0.12.0-2-x86_64 +installed = gvfs-1.50.2-1-x86_64 +installed = gzip-1.12-1-x86_64 +installed = harfbuzz-6.0.0-1-x86_64 +installed = harfbuzz-icu-6.0.0-1-x86_64 +installed = hicolor-icon-theme-0.17-2-any +installed = hidapi-0.12.0-1-x86_64 +installed = highway-1.0.2-1-x86_64 +installed = htop-3.2.1-1-x86_64 +installed = http-parser-2.9.4-1-x86_64 +installed = hunspell-1.7.1-1-x86_64 +installed = hwdata-0.365-1-any +installed = hwloc-2.8.0-1-x86_64 +installed = hyphen-2.8.8-5-x86_64 +installed = iana-etc-20221215-1-any +installed = ibus-1.5.27-1-x86_64 +installed = icu-72.1-2-x86_64 +installed = imath-3.1.6-1-x86_64 +installed = iniparser-4.1-4-x86_64 +installed = intel-ucode-20221108-1-any +installed = iproute2-6.1.0-3-x86_64 +installed = iptables-1:1.8.8-2-x86_64 +installed = iputils-20221126-1-x86_64 +installed = ipython-8.7.0-1-any +installed = iso-codes-4.12.0-1-any +installed = jack2-1.9.21-3-x86_64 +installed = jansson-2.14-2-x86_64 +installed = jasper-4.0.0-1-x86_64 +installed = jemalloc-1:5.3.0-1-x86_64 +installed = jq-1.6-4-x86_64 +installed = json-c-0.16-1-x86_64 +installed = json-glib-1.6.6-2-x86_64 +installed = jsoncpp-1.9.5-2-x86_64 +installed = kbd-2.5.1-1-x86_64 +installed = keychain-2.8.5-2-any +installed = keyutils-1.6.3-1-x86_64 +installed = kmod-30-3-x86_64 +installed = krb5-1.20.1-1-x86_64 +installed = kwayland-5.101.0-1-x86_64 +installed = l-smash-2.14.5-2-x86_64 +installed = lame-3.100-4-x86_64 +installed = lcms2-2.14-1-x86_64 +installed = ldb-2:2.6.1-1-x86_64 +installed = ldns-1.8.3-2-x86_64 +installed = less-1:608-1-x86_64 +installed = libadwaita-1:1.2.0-1-x86_64 +installed = libaio-0.3.113-1-x86_64 +installed = libarchive-3.6.2-2-x86_64 +installed = libass-0.17.0-1-x86_64 +installed = libassuan-2.5.5-1-x86_64 +installed = libasyncns-1:0.8+r3+g68cd5af-2-x86_64 +installed = libatasmart-0.19-5-x86_64 +installed = libavc1394-0.5.4-4-x86_64 +installed = libavif-0.11.1-1-x86_64 +installed = libb2-0.98.1-2-x86_64 +installed = libblockdev-2.28-1-x86_64 +installed = libbluray-1.3.4-1-x86_64 +installed = libbpf-1.0.1-1-x86_64 +installed = libbs2b-3.1.0-8-x86_64 +installed = libbsd-0.11.7-1-x86_64 +installed = libbytesize-2.7-1-x86_64 +installed = libcamera-0.0.3-1-x86_64 +installed = libcanberra-1:0.30+r2+gc0620e4-2-x86_64 +installed = libcap-2.66-1-x86_64 +installed = libcap-ng-0.8.3-1-x86_64 +installed = libcdio-2.1.0-3-x86_64 +installed = libcdio-paranoia-10.2+2.0.1-2-x86_64 +installed = libcloudproviders-0.3.1+r8+g3a229ee-1-x86_64 +installed = libcolord-1.4.6-1-x86_64 +installed = libcue-2.2.1-2-x86_64 +installed = libcups-1:2.4.2-3-x86_64 +installed = libdaemon-0.14-5-x86_64 +installed = libdatrie-0.2.13-2-x86_64 +installed = libdca-0.0.7-1-x86_64 +installed = libde265-1.0.9-1-x86_64 +installed = libdispatch-5.5.0-1-x86_64 +installed = libdrm-2.4.114-1-x86_64 +installed = libdvbpsi-1:1.3.3-2-x86_64 +installed = libdvdread-6.1.3-1-x86_64 +installed = libebml-1.4.4-1-x86_64 +installed = libedit-20210910_3.1-2-x86_64 +installed = libelf-0.188-1-x86_64 +installed = libepoxy-1.5.10-1-x86_64 +installed = libevdev-1.13.0-1-x86_64 +installed = libevent-2.1.12-4-x86_64 +installed = libexif-0.6.24-1-x86_64 +installed = libffi-3.4.4-1-x86_64 +installed = libfontenc-1.1.7-1-x86_64 +installed = libgcrypt-1.10.1-2-x86_64 +installed = libgexiv2-0.14.0-3-x86_64 +installed = libgit2-1:1.5.0-2-x86_64 +installed = libglvnd-1.6.0-1-x86_64 +installed = libgnomekbd-1:3.28.1-1-x86_64 +installed = libgpg-error-1.46-2-x86_64 +installed = libgrss-0.7.0+16+g971c421-3-x86_64 +installed = libgsf-1.14.50-1-x86_64 +installed = libgtop-2.40.0+2+g31db82ef-2-x86_64 +installed = libgudev-237-2-x86_64 +installed = libgusb-0.4.3-1-x86_64 +installed = libgweather-4-4.2.0-1-x86_64 +installed = libgxps-0.3.2-2-x86_64 +installed = libhandy-1.8.0-1-x86_64 +installed = libheif-1.14.0-1-x86_64 +installed = libibus-1.5.27-1-x86_64 +installed = libical-3.0.16-4-x86_64 +installed = libice-1.1.1-1-x86_64 +installed = libid3tag-0.15.1b-11-x86_64 +installed = libidn-1.41-1-x86_64 +installed = libidn2-2.3.4-3-x86_64 +installed = libiec61883-1.2.0-7-x86_64 +installed = libimobiledevice-1.3.0-5-x86_64 +installed = libinih-56-1-x86_64 +installed = libinput-1.22.0-1-x86_64 +installed = libiptcdata-1.0.5-1-x86_64 +installed = libisl-0.25-1-x86_64 +installed = libjpeg-turbo-2.1.4-2-x86_64 +installed = libjxl-0.7.0-3-x86_64 +installed = libksba-1.6.2-1-x86_64 +installed = libldap-2.6.3-2-x86_64 +installed = libmad-0.15.1b-9-x86_64 +installed = libmalcontent-0.11.0-1-x86_64 +installed = libmanette-0.2.6-3-x86_64 +installed = libmatroska-1.7.1-1-x86_64 +installed = libmd-1.0.4-1-x86_64 +installed = libmfx-22.4.4-1-x86_64 +installed = libmm-glib-1.20.2-1-x86_64 +installed = libmng-2.0.3-3-x86_64 +installed = libmnl-1.0.5-1-x86_64 +installed = libmodplug-0.8.9.0-4-x86_64 +installed = libmpc-1.3.1-1-x86_64 +installed = libmpcdec-1:0.1+r475-3-x86_64 +installed = libmpeg2-0.5.1-7-x86_64 +installed = libnautilus-extension-43.1-1-x86_64 +installed = libnetfilter_conntrack-1.0.9-1-x86_64 +installed = libnfnetlink-1.0.2-1-x86_64 +installed = libnftnl-1.2.4-1-x86_64 +installed = libnghttp2-1.51.0-1-x86_64 +installed = libnl-3.7.0-1-x86_64 +installed = libnm-1.40.8-2-x86_64 +installed = libnma-common-1.10.4-3-x86_64 +installed = libnma-gtk4-1.10.4-3-x86_64 +installed = libnotify-0.8.1-1-x86_64 +installed = libnsl-2.0.0-2-x86_64 +installed = libogg-1.3.5-1-x86_64 +installed = libomxil-bellagio-0.9.3-4-x86_64 +installed = libosinfo-1.10.0-2-x86_64 +installed = libp11-kit-0.24.1-1-x86_64 +installed = libpcap-1.10.1-2-x86_64 +installed = libpciaccess-0.17-1-x86_64 +installed = libpeas-1.34.0-1-x86_64 +installed = libpipeline-1.5.7-1-x86_64 +installed = libplacebo-4.208.0-1-x86_64 +installed = libplist-2.2.0-5-x86_64 +installed = libpng-1.6.39-1-x86_64 +installed = libportal-0.6-1-x86_64 +installed = libportal-gtk4-0.6-1-x86_64 +installed = libproxy-0.4.18-2-x86_64 +installed = libpsl-0.21.1-3-x86_64 +installed = libpulse-16.1-3-x86_64 +installed = libpwquality-1.4.5-1-x86_64 +installed = libraw1394-2.1.2-3-x86_64 +installed = librest-0.9.1-2-x86_64 +installed = librsvg-2:2.55.1-1-x86_64 +installed = libsamplerate-0.2.2-1-x86_64 +installed = libsasl-2.1.28-3-x86_64 +installed = libseccomp-2.5.4-1-x86_64 +installed = libsecret-0.20.5-2-x86_64 +installed = libsigc++-2.12.0-1-x86_64 +installed = libsigc++-3.0-3.4.0-1-x86_64 +installed = libsm-1.2.4-1-x86_64 +installed = libsndfile-1.1.0-3-x86_64 +installed = libsoup-2.74.3-1-x86_64 +installed = libsoup3-3.2.2-1-x86_64 +installed = libsoxr-0.1.3-3-x86_64 +installed = libssh-0.10.4-3-x86_64 +installed = libssh2-1.10.0-3-x86_64 +installed = libstemmer-2.2.0-2-x86_64 +installed = libsysprof-capture-3.46.0-1-x86_64 +installed = libtar-1.2.20-6-x86_64 +installed = libtasn1-4.19.0-1-x86_64 +installed = libthai-0.1.29-2-x86_64 +installed = libtheora-1.1.1-5-x86_64 +installed = libtiff-4.4.0-4-x86_64 +installed = libtirpc-1.3.3-2-x86_64 +installed = libtool-2.4.7-5-x86_64 +installed = libunistring-1.1-2-x86_64 +installed = libunwind-1.6.2-2-x86_64 +installed = libupnp-1.14.15-1-x86_64 +installed = liburcu-0.13.2-1-x86_64 +installed = libusb-1.0.26-1-x86_64 +installed = libusbmuxd-2.0.2-1-x86_64 +installed = libutempter-1.2.1-3-x86_64 +installed = libuv-1.44.2-1-x86_64 +installed = libva-2.16.0-1-x86_64 +installed = libvdpau-1.5-1-x86_64 +installed = libverto-0.3.2-4-x86_64 +installed = libvorbis-1.3.7-3-x86_64 +installed = libvpx-1.12.0-2-x86_64 +installed = libwacom-2.5.0-1-x86_64 +installed = libwbclient-4.17.4-2-x86_64 +installed = libwebp-1.2.4-1-x86_64 +installed = libwpe-1.14.0-1-x86_64 +installed = libx11-1.8.3-3-x86_64 +installed = libxau-1.0.11-1-x86_64 +installed = libxcb-1.15-2-x86_64 +installed = libxcomposite-0.4.6-1-x86_64 +installed = libxcrypt-4.4.33-1-x86_64 +installed = libxcursor-1.2.1-3-x86_64 +installed = libxcvt-0.1.2-1-x86_64 +installed = libxdamage-1.1.6-1-x86_64 +installed = libxdmcp-1.1.4-1-x86_64 +installed = libxext-1.3.5-1-x86_64 +installed = libxfixes-6.0.0-2-x86_64 +installed = libxfont2-2.0.6-1-x86_64 +installed = libxft-2.3.7-1-x86_64 +installed = libxi-1.8-2-x86_64 +installed = libxinerama-1.1.5-1-x86_64 +installed = libxkbcommon-1.4.1-2-x86_64 +installed = libxkbcommon-x11-1.4.1-2-x86_64 +installed = libxkbfile-1.1.2-1-x86_64 +installed = libxklavier-5.4-3-x86_64 +installed = libxml2-2.10.3-2-x86_64 +installed = libxmu-1.1.4-1-x86_64 +installed = libxpm-3.5.14-1-x86_64 +installed = libxrandr-1.5.3-1-x86_64 +installed = libxrender-0.9.11-1-x86_64 +installed = libxshmfence-1.3.2-1-x86_64 +installed = libxslt-1.1.37-2-x86_64 +installed = libxss-1.2.3-4-x86_64 +installed = libxt-1.2.1-1-x86_64 +installed = libxtst-1.2.4-1-x86_64 +installed = libxv-1.0.12-1-x86_64 +installed = libxvmc-1.0.13-1-x86_64 +installed = libxxf86vm-1.1.5-1-x86_64 +installed = libyaml-0.2.5-1-x86_64 +installed = libyuv-r2322+3aebf69d-1-x86_64 +installed = licenses-20220125-1-any +installed = links-2.28-2-x86_64 +installed = linux-6.1.1.arch1-1-x86_64 +installed = linux-api-headers-5.18.15-1-any +installed = linux-firmware-20221214.f3c283e-1-any +installed = linux-firmware-whence-20221214.f3c283e-1-any +installed = llvm-libs-14.0.6-4-x86_64 +installed = lm_sensors-1:3.6.0.r41.g31d1f125-2-x86_64 +installed = lmdb-0.9.29-1-x86_64 +installed = lua52-5.2.4-5-x86_64 +installed = lua53-5.3.6-1-x86_64 +installed = lvm2-2.03.18-1-x86_64 +installed = lz4-1:1.9.4-1-x86_64 +installed = lzo-2.10-4-x86_64 +installed = m4-1.4.19-1-x86_64 +installed = make-4.3-5-x86_64 +installed = man-db-2.11.1-1-x86_64 +installed = man-pages-6.01-1-any +installed = mc-4.8.28-2-x86_64 +installed = md4c-0.4.8-1-x86_64 +installed = mdadm-4.2-2-x86_64 +installed = mesa-22.3.1-1-x86_64 +installed = minizip-1:1.2.13-2-x86_64 +installed = mkinitcpio-34-2-any +installed = mkinitcpio-busybox-1.35.0-1-x86_64 +installed = mobile-broadband-provider-info-20221107-1-any +installed = moc-1:2.5.2-8-x86_64 +installed = mpfr-4.1.1.p1-1-x86_64 +installed = mtdev-1.1.6-2-x86_64 +installed = nautilus-43.1-1-x86_64 +installed = ncurses-6.3-3-x86_64 +installed = ndctl-74-1-x86_64 +installed = netctl-1.28-1-any +installed = nettle-3.8.1-1-x86_64 +installed = nmap-7.93-1-x86_64 +installed = npth-1.6-3-x86_64 +installed = nspr-4.35-1-x86_64 +installed = nss-3.86-1-x86_64 +installed = ocl-icd-2.3.1-1-x86_64 +installed = oniguruma-6.9.8-1-x86_64 +installed = openal-1.22.2-1-x86_64 +installed = opencore-amr-0.1.6-1-x86_64 +installed = openexr-3.1.5-1-x86_64 +installed = openjpeg2-2.5.0-1-x86_64 +installed = openmpi-4.1.4-4-x86_64 +installed = openpmix-4.2.2-1-x86_64 +installed = openresolv-3.12.0-1-any +installed = openssh-9.1p1-3-x86_64 +installed = openssl-3.0.7-4-x86_64 +installed = openssl-1.1-1.1.1.s-4-x86_64 +installed = opus-1.3.1-3-x86_64 +installed = orc-0.4.33-1-x86_64 +installed = osinfo-db-20221130-1-any +installed = p11-kit-0.24.1-1-x86_64 +installed = pacman-6.0.2-5-x86_64 +installed = pacman-mirrorlist-20221204-1-any +installed = pam-1.5.2-1-x86_64 +installed = pambase-20221020-1-any +installed = pango-1:1.50.12-1-x86_64 +installed = pangomm-2.46.3-1-x86_64 +installed = parted-3.5-1-x86_64 +installed = patch-2.7.6-8-x86_64 +installed = pavucontrol-1:5.0+r61+gee77d86-2-x86_64 +installed = pciutils-3.9.0-2-x86_64 +installed = pcre-8.45-3-x86_64 +installed = pcre2-10.40-3-x86_64 +installed = pcsclite-1.9.9-2-x86_64 +installed = perl-5.36.0-3-x86_64 +installed = perl-error-0.17029-4-any +installed = perl-mailtools-2.21-6-any +installed = perl-timedate-2.33-4-any +installed = pinentry-1.2.1-1-x86_64 +installed = pipewire-1:0.3.63-3-x86_64 +installed = pixman-0.42.2-1-x86_64 +installed = pkgconf-1.8.0-1-x86_64 +installed = polkit-122-1-x86_64 +installed = poppler-22.12.0-1-x86_64 +installed = poppler-glib-22.12.0-1-x86_64 +installed = popt-1.19-1-x86_64 +installed = procps-ng-3.3.17-1-x86_64 +installed = protobuf-21.12-1-x86_64 +installed = psmisc-23.6-1-x86_64 +installed = pulseaudio-16.1-3-x86_64 +installed = pulseaudio-alsa-1:1.2.7.1-1-x86_64 +installed = pulseaudio-bluetooth-16.1-3-x86_64 +installed = pulsemixer-1.5.1-3-any +installed = python-3.10.9-1-x86_64 +installed = python-asttokens-2.2.1-1-any +installed = python-backcall-0.2.0-7-any +installed = python-decorator-5.1.1-2-any +installed = python-executing-1.2.0-1-any +installed = python-gobject-3.42.2-1-x86_64 +installed = python-jedi-0.18.2-1-any +installed = python-matplotlib-inline-0.1.6-2-any +installed = python-parso-1:0.8.3-1-any +installed = python-pexpect-4.8.0-6-any +installed = python-pickleshare-0.7.5-8-any +installed = python-prompt_toolkit-3.0.36-1-any +installed = python-ptyprocess-0.7.0-4-any +installed = python-pure-eval-0.2.2-2-any +installed = python-pygments-2.13.0-1-any +installed = python-six-1.16.0-6-any +installed = python-stack-data-0.6.2-1-any +installed = python-traitlets-5.8.0-1-any +installed = python-wcwidth-0.2.5-6-any +installed = qt5-base-5.15.7+kde+r177-1-x86_64 +installed = qt5-declarative-5.15.7+kde+r25-1-x86_64 +installed = qt5-svg-5.15.7+kde+r9-1-x86_64 +installed = qt5-translations-5.15.7-1-any +installed = qt5-wayland-5.15.7+kde+r58-1-x86_64 +installed = qt5-x11extras-5.15.7-1-x86_64 +installed = qt6-5compat-6.4.1-1-x86_64 +installed = qt6-base-6.4.1-1-x86_64 +installed = qt6-declarative-6.4.1-1-x86_64 +installed = qt6-imageformats-6.4.1-2-x86_64 +installed = qt6-svg-6.4.1-1-x86_64 +installed = qt6-translations-6.4.1-1-any +installed = qt6-wayland-6.4.1-1-x86_64 +installed = rav1e-0.6.1-1-x86_64 +installed = readline-8.2.001-1-x86_64 +installed = rhash-1.4.3-1-x86_64 +installed = rnnoise-0.4.1-1-x86_64 +installed = rtkit-0.13-2-x86_64 +installed = sbc-2.0-1-x86_64 +installed = sdl2-2.26.1-1-x86_64 +installed = seatd-0.7.0-2-x86_64 +installed = sed-4.9-1-x86_64 +installed = shaderc-2022.1-4-x86_64 +installed = shadow-4.12.3-2-x86_64 +installed = shared-mime-info-2.0+155+gf4e7cbc-1-x86_64 +installed = slang-2.3.3-2-x86_64 +installed = smbclient-4.17.4-2-x86_64 +installed = socat-1.7.4.4-1-x86_64 +installed = sound-theme-freedesktop-0.8-5-any +installed = speex-1.2.1-1-x86_64 +installed = speexdsp-1.2.1-1-x86_64 +installed = spirv-tools-2022.1-1-x86_64 +installed = sqlite-3.40.0-2-x86_64 +installed = srt-1.5.1-3-x86_64 +installed = sudo-1.9.12.p1-1-x86_64 +installed = svt-av1-1.4.1-1-x86_64 +installed = sway-1:1.7-10-x86_64 +installed = swaybg-1.2.0-1-x86_64 +installed = swayidle-1.8.0-1-x86_64 +installed = swayimg-1.9-2-x86_64 +installed = swaylock-1.7-1-x86_64 +installed = sysfsutils-2.1.1-1-x86_64 +installed = systemd-252.4-2-x86_64 +installed = systemd-libs-252.4-2-x86_64 +installed = systemd-sysvcompat-252.4-2-x86_64 +installed = taglib-1.13-1-x86_64 +installed = talloc-2.3.4-1-x86_64 +installed = tar-1.34-1-x86_64 +installed = tdb-1.4.7-1-x86_64 +installed = telegram-desktop-4.4.1-3-x86_64 +installed = terminus-font-4.49.1-2-any +installed = tevent-1:0.13.0-1-x86_64 +installed = texinfo-7.0.1-1-x86_64 +installed = thin-provisioning-tools-0.9.0-1-x86_64 +installed = tmux-3.3_a-2-x86_64 +installed = totem-pl-parser-3.26.6-2-x86_64 +installed = tpm2-tss-3.2.0-3-x86_64 +installed = tracker3-3.4.2-1-x86_64 +installed = tracker3-miners-3.4.2-1-x86_64 +installed = tree-2.1.0-1-x86_64 +installed = tslib-1.22-1-x86_64 +installed = ttf-liberation-2.1.5-1-any +installed = ttf-opensans-1.101-2-any +installed = tzdata-2022g-1-x86_64 +installed = udisks2-2.9.4-1-x86_64 +installed = upower-1.90.0-1-x86_64 +installed = usbmuxd-1.1.1-1-x86_64 +installed = util-linux-2.38.1-1-x86_64 +installed = util-linux-libs-2.38.1-1-x86_64 +installed = v4l-utils-1.22.1-1-x86_64 +installed = vid.stab-1.1-3-x86_64 +installed = vim-9.0.1046-1-x86_64 +installed = vim-runtime-9.0.1046-1-x86_64 +installed = vlc-3.0.18-4-x86_64 +installed = vmaf-2.3.1-1-x86_64 +installed = volume_key-0.3.12-7-x86_64 +installed = vte-common-0.70.2-1-x86_64 +installed = vte3-0.70.2-1-x86_64 +installed = vulkan-headers-1:1.3.235-1-any +installed = vulkan-icd-loader-1.3.235-1-x86_64 +installed = wavpack-5.6.0-1-x86_64 +installed = wayland-1.21.0-2-x86_64 +installed = wayland-protocols-1.31-1-any +installed = webkit2gtk-4.1-2.38.3-1-x86_64 +installed = webp-pixbuf-loader-0.0.7-1-x86_64 +installed = webrtc-audio-processing-0.3.1-3-x86_64 +installed = weston-11.0.0-1-x86_64 +installed = which-2.21-5-x86_64 +installed = wl-clipboard-1:2.1.0-2-x86_64 +installed = wlroots-0.15.1-6-x86_64 +installed = woff2-1.0.2-4-x86_64 +installed = wpa_supplicant-2:2.10-8-x86_64 +installed = wpebackend-fdo-1.14.0-1-x86_64 +installed = x264-3:0.164.r3095.baee400-4-x86_64 +installed = x265-3.5-3-x86_64 +installed = xcb-proto-1.15.2-2-any +installed = xcb-util-0.4.1-1-x86_64 +installed = xcb-util-cursor-0.1.4-1-x86_64 +installed = xcb-util-errors-1.0.1-1-x86_64 +installed = xcb-util-image-0.4.1-2-x86_64 +installed = xcb-util-keysyms-0.4.1-4-x86_64 +installed = xcb-util-renderutil-0.3.10-1-x86_64 +installed = xcb-util-wm-0.4.2-1-x86_64 +installed = xdg-dbus-proxy-0.1.4-1-x86_64 +installed = xdg-utils-1.1.3+25+g8ae0263-1-any +installed = xf86-input-libinput-1.2.1-1-x86_64 +installed = xf86-video-intel-1:2.99.917+916+g31486f40-2-x86_64 +installed = xfsprogs-6.0.0-2-x86_64 +installed = xkeyboard-config-2.37-1-any +installed = xorg-fonts-encodings-1.0.6-1-any +installed = xorg-server-21.1.6-1-x86_64 +installed = xorg-server-common-21.1.6-1-x86_64 +installed = xorg-setxkbmap-1.3.3-1-x86_64 +installed = xorg-xauth-1.1.2-1-x86_64 +installed = xorg-xinit-1.4.2-1-x86_64 +installed = xorg-xkbcomp-1.4.6-1-x86_64 +installed = xorg-xmodmap-1.0.11-1-x86_64 +installed = xorg-xprop-1.2.6-1-x86_64 +installed = xorg-xrandr-1.5.2-1-x86_64 +installed = xorg-xrdb-1.2.1-1-x86_64 +installed = xorg-xset-1.2.5-1-x86_64 +installed = xorgproto-2022.2-1-any +installed = xvidcore-1.3.7-2-x86_64 +installed = xxhash-0.8.1-3-x86_64 +installed = xz-5.4.0-1-x86_64 +installed = yay-11.3.1-1-x86_64 +installed = zimg-3.0.4-1-x86_64 +installed = zlib-1:1.2.13-2-x86_64 +installed = zsh-5.9-2-x86_64 +installed = zstd-1.5.2-7-x86_64 diff --git a/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.MTREE b/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.MTREE new file mode 100644 index 0000000000000000000000000000000000000000..46d54a1605037baff1b41233d5b70ceb99b9f80d GIT binary patch literal 359 zcmV-t0hsquj5kbqJv9fP9` z>vu&if7`iaX}QMUZDcCJT+lETQezuYtePT1%biE5l>pUAv>7Ev>sQ3DA3wYXm}`25 z2bj^__b~y=sba!rJ=d~xilmo#(ldc5c|kEIgkfZl?-djX|H)_G57txyz8bK#mq zDvbGR@Uou&LH49rm~S8O`Fv}h+Wh1H+9!LwJj~0yy|#AqaJ}`piJl!tWK%Zp1-gYX zAmeV_g6yS^JsSh F0033*ulfK0 literal 0 KcmV+b0RR6000031 diff --git a/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.PKGINFO b/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.PKGINFO new file mode 100644 index 0000000..bef2df8 --- /dev/null +++ b/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/.PKGINFO @@ -0,0 +1,16 @@ +# Generated by makepkg 6.0.2 +# using fakeroot version 1.30.1 +pkgname = cpulimit-git +pkgbase = cpulimit-git +pkgver = 1-1 +pkgdesc = Limit cpu usage in %. Actualy sends SIGSTOP/SIGCONT +url = https://github.com/opsengine/cpulimit +builddate = 1672505075 +packager = Unknown Packager +size = 30920 +arch = x86_64 +license = GPL +conflict = cpulimit +provides = cpulimit +depend = glibc +makedepend = git diff --git a/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/usr/bin/cpulimit b/deps/cpulimit-fork/pacman-package/pkg/cpulimit-git/usr/bin/cpulimit new file mode 100755 index 0000000000000000000000000000000000000000..8885ff945a8e6db54dce29983b483f8f41f80989 GIT binary patch literal 30920 zcmV;(csGZCMNCEl0RaF2000000000306qW#0001RDF6Tf0000$000000001paR2}S z000000000$05|{*06+j802}}Y000040000$000000000$000000000$000000002k z0ssI20002k0ssI2000080000000003000040000O0{{R30000O0{{R30000O0{{R3 z0000S000000000S00000000010000000001000040000000000000000000000000 z000000002s5dZ)H0002s5dZ)H000005C8xG000010000500000AOHXW00000AOHXW z00000AOHXW0002tB>(^b0002tB>(^b000005C8xG000010000400000Pyhe`00000 zPyhe`00000Pyhe`0001Z5C8xG0001Z5C8xG000005C8xG00001000060002EYybcN z0002Ed;kCd0002Ed;kCd000260{{R30001pFaQ7m000005C8xG00002000060002U zYybcN0002Ud;kCd0002Ud;kCd0002s0RR910002s0RR9100008000000000400004 z0000u0{{R30000u0{{R30000u0{{R30000$000000000$00000000080000000004 z000040001Z0{{R30001Z0{{R30001Z0{{R30000)000000000)000000000400000 z0000}<#c2O0000u0{{R30000u0{{R30000u0{{R30000$000000000$0000000008 z000000000`<#c2O0000OSpWb40000OSpWb40000OSpWb40000~0RR910000~0RR91 z00004000000000{<#c2Q000000000000000000000000000000000000000000000 z000000000G000000000|<#c2O0002EYybcN0002Ed;kCd0002Ed;kCd0000;0{{R3 z0000;0{{R300001000000000lY-wUPG%svqEo^CSb$Bg!I5sUdG%j;*E;0ZB00004 z0000m000050000-PE`N`fB?V*00001000000000100F=R00009000000000200F=R z0000100000000040000K000030000-PE`P>)X;qYWdc^HMAgsECfV)3m~Wp10000G z000010000-PE`N^00004000040000000000000030000g00002000070001>0Z>E| z0gSc)0zeV~1PGui0000j0000r0000e9gG~F`)&_wPQto|@Roca&k6lJtvL;Ri*pbD z?1U6PewKU|>URD)@{1fY#P<@&IY1w?qW2O2000000000000000000000000000000 z0001o0000I000000000000000000000000C0RR9J000000000000000000000001p z0RR9J000000000000000000000000<0RR9J000000000000000000000001*0RR9J z000000000000000000000002&0RR9X000000000000000000000000E0000I00000 z0000000000000000000e0000I000000000000000000000001%0000I0000000000 z00000000000002b0000I000000000000000000000001T0RR9J000000000000000 z000000002U0000I000000000000000000000001v0RR9J00000000000000000000 z0000L0000I000000000000000000000001;0000I000000000000000000000001R z0000I000000000000000000000000j0000I000000000000000000000001f0000I z00000000000000000000000100RR9J000000000000000000000001M0RR9J00000 z0000000000000000000V0000I00000000000000000000000080ssIY0000000000 z0000000000000270000I000000000000000000000001b0RR9J000000000000000 z000000000y0RR9J000000000000000000000002K0000I00000000000000000000 z0002_0000I000000000000000000000000%0RR9J000000000000000000000001w z0000I00000000000000000000000140000I000000000000000000000001@0RR9J z000000000000000000000001E0RR9J00000000000000000000000200000I00000 z0000000000000000002w0000I00000000000000000000000000RR9J0000000000 z00000000000000q0RR9J000000000000000000000002%0000I000000000000000 z000000000N0ssIY000000000000000000000000P0000I00000000000000000000 z0000b0RR9Z000000000000000000000002P0000I000000000000000000000002i z0000H02%;*fB*mh0000800000000080000I000000000000000000000000$0000I z000000000000000000000001H0000I00000000000000000000000170RR9J00000 z000000000000000000050RR9J000000000000000000000002E0000I0000000000 z00000000000000v0000I000000000000000000000001M0000I000000000000000 z000000001i0RR9J000000000000000000000000U0RR9I02%@r2aAk6GZ*l;0d2?fLZe{>qUvqR}V{2by zXlq|)VQFjtUte%?X>N38Ut?%%0A_M!WdLP(X>{ zasY63bYo~?asXy#Y;|*J0CRM5bZ=w;XJvGBX>Db1W@KS`0CRM5bZ=__b98caZ)^Z& zZ*XO90CZ_>WdLSxa%%u{baHHEZUARxbZ}{80CRL?Z*_D4Z*X*Ba%TW#cx7XDZ~$Ll zW^i(8Zggf}V`ystb97;JW^({xbZ=<@ZDDL|Z({&oUu4o&a%Ev;WNC5$XJvG7a%pdJX>@r2 zZDnm^ZEyf)V{C78WdL_!X>@RDWB_w%XKrC^0B>+*Ze(e40BvP$V{mx@W_NOFbY%cx zVsCPE0B2=%Z*X*9Y;SI70CRM5Zewk50BvP$a${(60BmVuV=i-VE;ay1Oi4mRUotK; zE;Il~Oi4mRUotK+Gyq3TNkT(kGA=X#M@&gVLtip3Gc*84Oi4mRUotK-E;RsONmNZ= zWMy(?XK8bEWpY$aLu_wuWmI8eY-IpnUuSJ^ZeMeBVRCd|UjSc8R83!UWoKz~bY*f> zO+##NZe>(qVr*pq0000200RI500IC40096300IC400IC400IC400IC400IC400IC4 z00IC40096300jU700IC400IC400sa800IC400IC400IC80096300IC400IC400IC4 z00IC400IC400IC400IC400aO6000000000100jW50RR9H000000001V8EFXs00scG z0RR9H0001#k(LGk00jWR0RR9H0000KX=x1r00aQb0RR9H0002Ak(LGk00RKk0RR9H z0001W8fggt00IEu0RR910002Ed;kCd00008000000001BDgXcg0002Md;kCd00008 z000000000GDgXcg0001BfB*mh00008000000001BfB*mh0001}egFUf000060000j z000000000000026egFUf000060000100000000000002EegFUf000060000200000 z000000002MegFUf000060000300000000000002UegFUf00006000040000000000 z0002cegFUf000060000500000000000002kegFUf000060000600000000000002s zegFUf000060000800000000000002!egFUf000060000A00000000000002+egFUf z000060000k00000000000002^egFUf000060000C000000000000000e*gdg00006 z0000s000000000000008e*gdg000060000D00000000000000Ge*gdg000060000E z00000000000000Oe*gdg000060000F00000000000000We*gdg000060000G00000 z000000000ee*gdg000060000H00000000000000me*gdg000060000h0000000000 z0000ue*gdg000060000K00000000000000$e*gdg000060000L00000000000000; ze*gdg000060000M00000000000000`e*gdg000060000N000000000000013e*gdg z000060000O00000000000001Be*gdg000060000P00000000000001Je*gdg00006 z0000l00000000000001Re*gdg000060000T00000000000001Ze*gdg000060000U z00000000000001he*gdg000060000V00000000000001pe*gdg000060000W00000 z000000001xe*gdg000060000m00000000000001(e*gdg000060000n0000000000 z0001>e*gdg000060000i00000000000001}e*gdg000060000Y000000000000026 ze*gdg000060000o00000000000002Ee*gdg000060000p00000000000002Me*gdg z000060000b00000000000002Ue*gdg000060000c00000000000002ce*gdg00006 z0000d00000000000002ke*gdg000060000e00000000000002se*gdg000060000f z00000000000001hfB*mh000050000g00000000000001pfB*mh000050000r00000 z000000001>fB*mh000050000t00000000000002MfB*mh000050000q0000000000 z00000fB*mh0000700007000000000000008fB*mh000070000900000000000000G zfB*mh000070000B00000000000000OfB*mh000070000I00000000000000WfB*mh z000070000J00000000000000efB*mh000070000Q00000000000000mfB*mh00007 z0000R00000000000000ufB*mh000070000S00000000000000$fB*mh000070000X z00000000000000;fB*mh000070000Z00000000000000`fB*mh000070000a00000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000002<4<7nRgX{=Miv>Af002mZ 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 zgX{=MgTx5K0000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000001 z00IC200010b75y?Iv^!;AX`sRR7p=xQ!XwpT_99JQb$Ep3IG5gARr(hAT4YxAT2Fy zX>DnAJx(AXARr(hARr(haAk61Wo~p~XJsI7W*}p5bs%AEY;SjEWFTg8Z*3qjAarja zC1fBda%FLKX>w&`DGC4}ARr(hAT4$*AT2F+WpZL~b7dePARr(hARr(hb7*gOAY*TC zbaHQOAaitKbZK*RX=8H=0000WARr(hAT4?pZ*m}MW*}*FAY^G}a|!?;ARr(h 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 z-v9s51ONbm-v9sb1ONal-~ay*1pojR;{X3N1poj~Pw;1^@uq z>;L}@2LJ$A?En8L2LJ#70000K0000000001dQt!Zcn|>_3qKGbADa z0000K000170000G#{d6N00000000000000K0001V0001p&;S2s00000Ob!r(0ssIM z0001t0002s&;S2S0RR91K@Jdu0ssIg0001_0000O(f|K&00000MGg>#0#6PYg9Ahk zAOc7V4j4fW5J3(IK??vd0002c00017(f|J)1poj5Mh*~<0zwWLjsr&yAdLh^4k(NT zK@Kp620;!ug9k?r&;bB2000040RRBV#sB{%2mk;8Mh*~<0zwWLjsrptAdLh<4k(NT zL=G^921E`xg9k?rkOKf90000u0RRAm#sB{X000004v+(b2ZjcW1&sub1CIg#0000S z000170RRB))&KuK00000K@Jdx0z(Z3c?<^#0000S0001d0RR9C*8l&Y00000K@Jdx z0z(Z30-Fp62mk;a0001-0RRAt*8l(F00000K@Jdx0z(Z30^JM;2mk;a0002I0RR9^ z*Z==O00000K@Jdx0z(Z3dkhB%0000S0002o0RRAP*Z=<+00000K@Jdx0z(Z3R160Q z0000S0002|0RRAI*Z=000000K@Jdx0z(Z30(cAu2mk;a0002I0ssJj*Z==4 z00000K@Jdx0z(Z3XAB1j0000S0002o0ssJv*Z==V00000K@Jdx0z(Z30zwQ22mk;a z0002|0ssKB*Z==400000K@Jdx0z(Z3XAB1j0000S0000S0{{TO*Z==z00000K@Jdx z0z(Z30$>aW2mk;a0000y0{{R7*#G~300000K@Jdx0z(Z30(uMw2mk;a000170{{SH z*#G|k0RR91K@Jdx0z(Z30{aXH2mk;a0001d0{{R++5i7$00000K@Jdx0z(Z30$~gX z2mk;a0001-0{{St+5i8l00000K@Jdx0z(Z30;LQG2mk;e0002I0{{RM+W-IS0ssI2 zK@Jdx0z(Z3MS}wa;Q|Z?2mk;a0002s0{{Tp-2eYM0RR91K@Jdx0z(Z312h2)2M7Qh z000001ONc@-T(hT00000K@Jdx0z(Z3dJG2$0000S0000W1ONaM-v9r40RR91K@Jdx z0z(Z319brm2M7Ql0000$1ONbR-~azq00000K@Jdx0z(Z30#6JF2mk;80000O0001F z1ONc2-~ay}00000MGg>y0$2_R0000;0001h1ONc6-~ay>0RR91Mh*~;0zwWLjRQgs zAdCb-4k(5NK@Kp321gFCAWROhKuHdeK?1W14lqFuC_xS&LJk;04iG{P2t^Ah0002Y z1ONbl;Q#+_00000Mh*~+0z?iNh66|rAcF(~SPmFL4iG{P2mk;O0002^1ONcU;Q#*x z000000000`0000C1polR;Q#-n0RR91Mh*~<0zwWLjsrptAdLh<4k(NTK@Kp620;!u zg9k?rxFAUmkRbzh0SXQ{K@KoM4k$tnAVLlpLJkl@4hTUD0000~0001B1pojX;{X5k z0ssI2Mh*~<0zwWLjsrptAdLh<4k(NTK@Kp620;!ug9k?rxFAdpxIjz}z(E6d0tyZ| zK@KoM4k$tnAVLlpLJkl@4hTUD0000O0002E1polVy0s?dn2mk;u z0002g1pojj<^TU=00000MGg>#0!a=Sg9A|xFmVbF7(osYK@JE;3q%eWMh*}`4hR4M z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z000000000000000000000001BDgXcg0000GDgXcg0000100000000200RR910000C z0000000000AOHXW0000D000000002gMF0Q*0000P000000002Ed;kCd0000R00000 z00008000000000Q000000002Md;kCd0000S0000000008000000002>{{L?P0002M z0{{R300005000000001J2><{900006000000000e1ONa40000A000000000n0ssI2 z0000B000000000O000000000L00000000000000000003000000002!e*gdg00002 z00000000080RR910000K0000000007000000000N000000002k5C8xG0000700000 z0001R3;+NC00008000000001J1ONa400009000000000O000000002{|Nn0Q00000 z000O80002~|Nn0Q0000G3;+NC00030|Nn0Q00001000000002+|Nn0Q0001*3jhEB z0002_|Nn0Q0000300000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z0002Ud;kCd000000000000000000000000sAOHXW0000+AOHXW00011AOHXW0001H zAOHXW0001XAOHXW0001nAOHXW0001%AOHXW0001{AOHXW0002CAOHXW0002SAOHXW z0002iAOHXW00000000000001BfB*mh0000-Lqj?sC`V3JDIhU2E;24K001s?XmfOO zbYWruE@^IbWpZ!;E^cphWiDrKbuMsnZ*XODba?V>{asV!JWo%(CWO;4?E^=jTVJ>iNbO0`CZfSG?E^usgE@y9a04{W8 zcys_RW@&C|04{QGWMOn+04`-{UuJS)ZDn6*WO4v5WoTb!a$#*{04`~6X>?y<{90001J2><{90000n0ssI20000000000000010000000000000000001C00030 z|Nn0S000000001*3jhEB0001*3jhEB0001R000000000600000000020000000002 z000000001P0002~|Nn0S000000000G3;+NC0000G3;+NC0001B000000000700001 z000080000000000000000001e0000400002000000001R3;+NC0001R3;+NC0001J z1ONa4000060000000008000000000O000000001o000040000&000000002k5C8xG z0002k5C8xG000080RR91000060000O00008000000000O000000001y0000100006 z0000000000AOHXW00000AOHXW0000R00000000000000000004000000000000000 z0001t0000100006000000000WAOHXW0000WAOHXW0002M0000000000000000000G z000000000G000000001&0000100006000000002sAOHXW0002sAOHXW0000`00000 z0000000000000080000000008000000001>0000100006000000000mApigX0000m zApigX0001_Bme*a00000000000000G0000000000000000001{000010000600000 z0002gMF0Q*0002gMF0Q*0000D0000000000000000000400000000000000000022 z00001000020000000000Pyhe`00000Pyhe`0000O2><{900000000000000G00000 z00000000000002A0000100002000000000OSpWb40000OSpWb40000~0RR9100000 z00000000040000000000000000002O0000100002000000001RS^xk50001RS^xk5 z000081^@s60000000000000080000000000000000002Y0000E00003000000002E zd;kCd0002EYybcN00008000000000000000000080000000008000000002k0000F z00003000000002Md;kCd0002MYybcN00008000000000000000000080000000008 z000000002w0000600003000000002Ud;kCd0002UYybcN0002s0RR910000700000 z00008000000000G000000001+0000100003000000001}egFUf0001}ZU6uP0000$ z0RR910000000000000080000000008000000002(0000100003000000002!e*gdg z0002!ZvX%Q0001R000000000000000000080000000008000000002?0000100003 z0000000013fB*mh00013Z~y=R0000G00000000000000000008000000000000000 z0002|0000800003000000001hfB*mh0001JZ~y=R0002MEC2ui00000000000000W z000000000000000000010RR920000m0000000000000000001JZ~y=R0000I00000 z0000000000000010000000001000000000100003000000000000000000000001b qZ~y=R0000A0RR910000000000000010000000000000000000~RvqX7 literal 0 KcmV+b0RR6000031 diff --git a/deps/cpulimit-fork/pacman-package/src/cpulimit-git b/deps/cpulimit-fork/pacman-package/src/cpulimit-git new file mode 120000 index 0000000..0746dfa --- /dev/null +++ b/deps/cpulimit-fork/pacman-package/src/cpulimit-git @@ -0,0 +1 @@ +/home/nartes/Documents/current/freelance-project-34-marketing-blog/deps/cpulimit-fork/pacman-package/src/../.. \ No newline at end of file diff --git a/deps/cpulimit-fork/src/Makefile b/deps/cpulimit-fork/src/Makefile new file mode 100644 index 0000000..86fbfbd --- /dev/null +++ b/deps/cpulimit-fork/src/Makefile @@ -0,0 +1,28 @@ +CC?=gcc +CFLAGS?=-Wall -g -D_GNU_SOURCE +TARGETS=cpulimit +LIBS=list.o process_iterator.o process_group.o + +UNAME := $(shell uname) + +ifeq ($(UNAME), FreeBSD) +LIBS+=-lkvm +endif + +all:: $(TARGETS) $(LIBS) + +cpulimit: cpulimit.c $(LIBS) + $(CC) -o cpulimit cpulimit.c $(LIBS) $(CFLAGS) + +process_iterator.o: process_iterator.c process_iterator.h + $(CC) -c process_iterator.c $(CFLAGS) + +list.o: list.c list.h + $(CC) -c list.c $(CFLAGS) + +process_group.o: process_group.c process_group.h process_iterator.o list.o + $(CC) -c process_group.c $(CFLAGS) + +clean: + rm -f *~ *.o $(TARGETS) + diff --git a/deps/cpulimit-fork/src/cpulimit.c b/deps/cpulimit-fork/src/cpulimit.c new file mode 100644 index 0000000..aa5d82d --- /dev/null +++ b/deps/cpulimit-fork/src/cpulimit.c @@ -0,0 +1,555 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + ************************************************************** + * + * This is a simple program to limit the cpu usage of a process + * If you modify this code, send me a copy please + * + * Get the latest version at: http://github.com/opsengine/cpulimit + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ || __FREEBSD__ +#include +#endif + +#include "process_group.h" +#include "list.h" + +#ifdef HAVE_SYS_SYSINFO_H +#include +#endif + +#ifdef __APPLE__ +#include "memrchr.c" +#endif + +//some useful macro +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +//control time slot in microseconds +//each slot is splitted in a working slice and a sleeping slice +//TODO: make it adaptive, based on the actual system load +#define TIME_SLOT 100000 + +#define MAX_PRIORITY -10 + +/* GLOBAL VARIABLES */ + +//the "family" +struct process_group pgroup; +//pid of cpulimit +pid_t cpulimit_pid; +//name of this program (maybe cpulimit...) +char *program_name; + +//number of cpu +int NCPU; + +/* CONFIGURATION VARIABLES */ + +//verbose mode +int verbose = 0; +//lazy mode (exits if there is no process) +int lazy = 0; + +//SIGINT and SIGTERM signal handler +static void quit(int sig) +{ + //let all the processes continue if stopped + struct list_node *node = NULL; + if (pgroup.proclist != NULL) + { + for (node = pgroup.proclist->first; node != NULL; node = node->next) { + struct process *p = (struct process*)(node->data); + kill(p->pid, SIGCONT); + } + close_process_group(&pgroup); + } + //fix ^C little problem + printf("\r"); + fflush(stdout); + exit(0); +} + +//return t1-t2 in microseconds (no overflow checks, so better watch out!) +static inline unsigned long timediff(const struct timeval *t1,const struct timeval *t2) +{ + return (t1->tv_sec - t2->tv_sec) * 1000000 + (t1->tv_usec - t2->tv_usec); +} + +static void print_usage(FILE *stream, int exit_code) +{ + fprintf(stream, "Usage: %s [OPTIONS...] TARGET\n", program_name); + fprintf(stream, " OPTIONS\n"); + fprintf(stream, " -l, --limit=N percentage of cpu allowed from 0 to %d (required)\n", 100*NCPU); + fprintf(stream, " -v, --verbose show control statistics\n"); + fprintf(stream, " -z, --lazy exit if there is no target process, or if it dies\n"); + fprintf(stream, " -i, --include-children limit also the children processes\n"); + fprintf(stream, " -h, --help display this help and exit\n"); + fprintf(stream, " TARGET must be exactly one of these:\n"); + fprintf(stream, " -p, --pid=N pid of the process (implies -z)\n"); + fprintf(stream, " -e, --exe=FILE name of the executable program file or path name\n"); + fprintf(stream, " COMMAND [ARGS] run this command and limit it (implies -z)\n"); + fprintf(stream, "\nReport bugs to .\n"); + exit(exit_code); +} + +static void increase_priority() { + //find the best available nice value + int old_priority = getpriority(PRIO_PROCESS, 0); + int priority = old_priority; + while (setpriority(PRIO_PROCESS, 0, priority-1) == 0 && priority>MAX_PRIORITY) { + priority--; + } + if (priority != old_priority) { + if (verbose) printf("Priority changed to %d\n", priority); + } + else { + if (verbose) printf("Warning: Cannot change priority. Run as root or renice for best results.\n"); + } +} + +/* Get the number of CPUs */ +static int get_ncpu() { + int ncpu; +#ifdef _SC_NPROCESSORS_ONLN + ncpu = sysconf(_SC_NPROCESSORS_ONLN); +#elif defined __APPLE__ + int mib[2] = {CTL_HW, HW_NCPU}; + size_t len = sizeof(ncpu); + sysctl(mib, 2, &ncpu, &len, NULL, 0); +#elif defined _GNU_SOURCE + ncpu = get_nprocs(); +#else + ncpu = -1; +#endif + return ncpu; +} + +int get_pid_max() +{ +#ifdef __linux__ + //read /proc/sys/kernel/pid_max + static char buffer[1024]; + FILE *fd = fopen("/proc/sys/kernel/pid_max", "r"); + if (fd==NULL) return -1; + if (fgets(buffer, sizeof(buffer), fd)==NULL) { + fclose(fd); + return -1; + } + fclose(fd); + return atoi(buffer); +#elif defined __FreeBSD__ + return 99998; +#elif defined __APPLE__ + return 99998; +#endif +} + +void limit_process(pid_t pid, double limit, int include_children) +{ + //slice of the slot in which the process is allowed to run + struct timespec twork; + //slice of the slot in which the process is stopped + struct timespec tsleep; + //when the last twork has started + struct timeval startwork; + //when the last twork has finished + struct timeval endwork; + //initialization + memset(&twork, 0, sizeof(struct timespec)); + memset(&tsleep, 0, sizeof(struct timespec)); + memset(&startwork, 0, sizeof(struct timeval)); + memset(&endwork, 0, sizeof(struct timeval)); + //last working time in microseconds + unsigned long workingtime = 0; + //generic list item + struct list_node *node; + //counter + int c = 0; + + //get a better priority + increase_priority(); + + //build the family + init_process_group(&pgroup, pid, include_children); + + #define group_stat() \ + printf( \ + "Members in the process group owned by %d: %d\n", \ + pgroup.target_pid, \ + pgroup.proclist->count \ + ) + + //if (verbose) group_stat(); + + //rate at which we are keeping active the processes (range 0-1) + //1 means that the process are using all the twork slice + double workingrate = -1; + while(1) { +#ifdef __linux__ + if (c % 100 == 0) + { + update_process_group(&pgroup); + } + else + { + update_process_group_fast(&pgroup, c, verbose); + } +#else + update_process_group(&pgroup); +#endif + if (c % 100 == 0) + { + if (verbose) { + group_stat(); + } + } + + if (pgroup.proclist->count==0) { + if (verbose) printf("No more processes.\n"); + //break; + } + + //total cpu actual usage (range 0-1) + //1 means that the processes are using 100% cpu + double pcpu = -1; + + //estimate how much the controlled processes are using the cpu in the working interval + for (node = pgroup.proclist->first; node != NULL; node = node->next) { + struct process *proc = (struct process*)(node->data); + + if (proc->cpu_usage < 0) { + continue; + } + if (pcpu < 0) pcpu = 0; + pcpu += proc->cpu_usage; + } + + //adjust work and sleep time slices + if (pcpu < 0) { + //it's the 1st cycle, initialize workingrate + pcpu = limit; + workingrate = limit; + twork.tv_nsec = TIME_SLOT * limit * 1000; + } + else + { + //adjust workingrate + workingrate = MIN(workingrate / pcpu * limit, 1); + twork.tv_nsec = TIME_SLOT * 1000 * workingrate; + } + tsleep.tv_nsec = TIME_SLOT * 1000 - twork.tv_nsec; + + if (verbose) { + if (c%200==0) + printf("\n%%CPU\twork quantum\tsleep quantum\tactive rate\n"); + if (c%10==0 && c>0) + printf("%0.2lf%%\t%6ld us\t%6ld us\t%0.2lf%%\n", pcpu*100, twork.tv_nsec/1000, tsleep.tv_nsec/1000, workingrate*100); + } + + //resume processes + node = pgroup.proclist->first; + while (node != NULL) + { + struct list_node *next_node = node->next; + struct process *proc = (struct process*)(node->data); + if (kill(proc->pid,SIGCONT) != 0) { + //process is dead, remove it from family + if (verbose) fprintf(stderr, "SIGCONT failed. Process %d dead!\n", proc->pid); + //remove process from group + delete_node(pgroup.proclist, node); + remove_process(&pgroup, proc->pid); + } + node = next_node; + } + + //now processes are free to run (same working slice for all) + gettimeofday(&startwork, NULL); + nanosleep(&twork, NULL); + gettimeofday(&endwork, NULL); + workingtime = timediff(&endwork, &startwork); + + long delay = workingtime - twork.tv_nsec/1000; + if (c>0 && delay>10000) { + //delay is too much! signal to user? + //fprintf(stderr, "%d %ld us\n", c, delay); + } + + if (tsleep.tv_nsec>0) { + //stop processes only if tsleep>0 + node = pgroup.proclist->first; + while (node != NULL) + { + struct list_node *next_node = node->next; + struct process *proc = (struct process*)(node->data); + if (kill(proc->pid,SIGSTOP)!=0) { + //process is dead, remove it from family + if (verbose) fprintf(stderr, "SIGSTOP failed. Process %d dead!\n", proc->pid); + //remove process from group + delete_node(pgroup.proclist, node); + remove_process(&pgroup, proc->pid); + } + node = next_node; + } + //now the processes are sleeping + nanosleep(&tsleep,NULL); + } + c++; + } + close_process_group(&pgroup); +} + +int main(int argc, char **argv) { + //argument variables + const char *exe = NULL; + int perclimit = 0; + int exe_ok = 0; + int pid_ok = 0; + int limit_ok = 0; + pid_t pid = 0; + int include_children = 0; + + //get program name + char *p = (char*)memrchr(argv[0], (unsigned int)'/', strlen(argv[0])); + program_name = p==NULL ? argv[0] : (p+1); + //get current pid + cpulimit_pid = getpid(); + //get cpu count + NCPU = get_ncpu(); + + //parse arguments + int next_option; + int option_index = 0; + //A string listing valid short options letters + const char* short_options = "+p:e:l:vzih"; + //An array describing valid long options + const struct option long_options[] = { + { "pid", required_argument, NULL, 'p' }, + { "exe", required_argument, NULL, 'e' }, + { "limit", required_argument, NULL, 'l' }, + { "verbose", no_argument, NULL, 'v' }, + { "lazy", no_argument, NULL, 'z' }, + { "include-children", no_argument, NULL, 'i' }, + { "help", no_argument, NULL, 'h' }, + { 0, 0, 0, 0 } + }; + + do { + next_option = getopt_long(argc, argv, short_options,long_options, &option_index); + switch(next_option) { + case 'p': + pid = atoi(optarg); + pid_ok = 1; + break; + case 'e': + exe = optarg; + exe_ok = 1; + break; + case 'l': + perclimit = atoi(optarg); + limit_ok = 1; + break; + case 'v': + verbose = 1; + break; + case 'z': + lazy = 1; + break; + case 'i': + include_children = 1; + break; + case 'h': + print_usage(stdout, 1); + break; + case '?': + print_usage(stderr, 1); + break; + case -1: + break; + default: + abort(); + } + } while(next_option != -1); + + if (pid_ok && (pid <= 1 || pid >= get_pid_max())) { + fprintf(stderr,"Error: Invalid value for argument PID\n"); + print_usage(stderr, 1); + exit(1); + } + if (pid != 0) { + lazy = 1; + } + + if (!limit_ok) { + fprintf(stderr,"Error: You must specify a cpu limit percentage\n"); + print_usage(stderr, 1); + exit(1); + } + double limit = perclimit / 100.0; + if (limit<0 || limit >NCPU) { + fprintf(stderr,"Error: limit must be in the range 0-%d00\n", NCPU); + print_usage(stderr, 1); + exit(1); + } + + int command_mode = optind < argc; + if (exe_ok + pid_ok + command_mode == 0) { + fprintf(stderr,"Error: You must specify one target process, either by name, pid, or command line\n"); + print_usage(stderr, 1); + exit(1); + } + + if (exe_ok + pid_ok + command_mode > 1) { + fprintf(stderr,"Error: You must specify exactly one target process, either by name, pid, or command line\n"); + print_usage(stderr, 1); + exit(1); + } + + //all arguments are ok! + signal(SIGINT, quit); + signal(SIGTERM, quit); + + //print the number of available cpu + if (verbose) printf("%d cpu detected\n", NCPU); + + if (command_mode) { + int i; + //executable file + const char *cmd = argv[optind]; + //command line arguments + char **cmd_args = (char**)malloc((argc-optind + 1) * sizeof(char*)); + if (cmd_args==NULL) exit(2); + for (i=0; i 0) { + //parent + int status_process; + int status_limiter; + waitpid(child, &status_process, 0); + waitpid(limiter, &status_limiter, 0); + if (WIFEXITED(status_process)) { + if (verbose) printf("Process %d terminated with exit status %d\n", child, (int)WEXITSTATUS(status_process)); + exit(WEXITSTATUS(status_process)); + } + printf("Process %d terminated abnormally\n", child); + exit(status_process); + } + else { + //limiter code + if (verbose) printf("Limiting process %d\n",child); + limit_process(child, limit, include_children); + exit(0); + } + } + } + + while(1) { + //look for the target process..or wait for it + pid_t ret = 0; + if (pid_ok) { + //search by pid + ret = find_process_by_pid(pid); + if (ret == 0) { + printf("No process found\n"); + } + else if (ret < 0) { + printf("Process found but you aren't allowed to control it\n"); + } + } + else { + //search by file or path name + ret = find_process_by_name(exe); + if (ret == 0) { + printf("No process found\n"); + } + else if (ret < 0) { + printf("Process found but you aren't allowed to control it\n"); + } + else { + pid = ret; + } + } + if (ret > 0) { + if (ret == cpulimit_pid) { + printf("Target process %d is cpulimit itself! Aborting because it makes no sense\n", ret); + exit(1); + } + printf("Process %d found\n", pid); + //control + limit_process(pid, limit, include_children); + } + if (lazy) break; + sleep(2); + }; + + exit(0); +} diff --git a/deps/cpulimit-fork/src/list.c b/deps/cpulimit-fork/src/list.c new file mode 100644 index 0000000..2a78358 --- /dev/null +++ b/deps/cpulimit-fork/src/list.c @@ -0,0 +1,148 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "list.h" + +#define EMPTYLIST NULL + +void init_list(struct list *l,int keysize) { + l->first=l->last=NULL; + l->keysize=keysize; + l->count=0; +} + +struct list_node *add_elem(struct list *l,void *elem) { + struct list_node *newnode=(struct list_node*)malloc(sizeof(struct list_node)); + newnode->data=elem; + newnode->previous=l->last; + newnode->next=NULL; + if (l->count==0) { + l->first=l->last=newnode; + } + else { + l->last->next=newnode; + l->last=newnode; + } + l->count++; + return newnode; +} + +void delete_node(struct list *l,struct list_node *node) { + if (l->count==1) { + l->first=l->last=NULL; + } + else if (node==l->first) { + node->next->previous=NULL; + l->first=node->next; + } + else if (node==l->last) { + node->previous->next=NULL; + l->last=node->previous; + } + else { + node->previous->next=node->next; + node->next->previous=node->previous; + } + l->count--; + free(node); +} + +void destroy_node(struct list *l,struct list_node *node) { + free(node->data); + node->data=NULL; + delete_node(l,node); +} + +int is_empty_list(struct list *l) { + return (l->count==0?TRUE:FALSE); +} + +int get_list_count(struct list *l) { + return l->count; +} + +void *first_elem(struct list *l) { + return l->first->data; +} + +struct list_node *first_node(struct list *l) { + return l->first; +} + +void *last_elem(struct list *l) { + return l->last->data; +} + +struct list_node *last_node(struct list *l) { + return l->last; +} + +struct list_node *xlocate_node(struct list *l,void *elem,int offset,int length) { + struct list_node *tmp; + tmp=l->first; + while(tmp!=NULL) { + if(!memcmp((char*)tmp->data+offset,elem,length==0?l->keysize:length)) return (tmp); + tmp=tmp->next; + } + return EMPTYLIST; +} + +struct list_node *locate_node(struct list *l,void *elem) { + return(xlocate_node(l,elem,0,0)); +} + +void *xlocate_elem(struct list *l,void *elem,int offset,int length) { + struct list_node *node=xlocate_node(l,elem,offset,length); + return(node==NULL?NULL:node->data); +} + +void *locate_elem(struct list *l,void *elem) { + return(xlocate_elem(l,elem,0,0)); +} + +void clear_list(struct list *l) { + while(l->first!=EMPTYLIST) { + struct list_node *tmp; + tmp=l->first; + l->first=l->first->next; + free(tmp); + tmp=NULL; + } + l->last=EMPTYLIST; + l->count=0; +} + +void destroy_list(struct list *l) { + while(l->first!=EMPTYLIST) { + struct list_node *tmp; + tmp=l->first; + l->first=l->first->next; + free(tmp->data); + tmp->data=NULL; + free(tmp); + tmp=NULL; + } + l->last=EMPTYLIST; + l->count=0; +} diff --git a/deps/cpulimit-fork/src/list.h b/deps/cpulimit-fork/src/list.h new file mode 100644 index 0000000..0b43a2b --- /dev/null +++ b/deps/cpulimit-fork/src/list.h @@ -0,0 +1,138 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __LIST__ + +#define __LIST__ + +#ifndef TRUE + #define TRUE 1 + #define FALSE 0 +#endif + +struct list_node { + //pointer to the content of the node + void *data; + //pointer to previous node + struct list_node *previous; + //pointer to next node + struct list_node *next; +}; + +struct list { + //first node + struct list_node *first; + //last node + struct list_node *last; + //size of the search key in bytes + int keysize; + //element count + int count; +}; + +/* + * Initialize a list, with a specified key size + */ +void init_list(struct list *l,int keysize); + +/* + * Add a new element at the end of the list + * return the pointer to the new node + */ +struct list_node *add_elem(struct list *l,void *elem); + +/* + * Delete a node + */ +void delete_node(struct list *l,struct list_node *node); + +/* + * Delete a node from the list, even the content pointed by it + * Use only when the content is a dynamically allocated pointer + */ +void destroy_node(struct list *l,struct list_node *node); + +/* + * Check whether a list is empty or not + */ +int is_empty_list(struct list *l); + +/* + * Return the element count of the list + */ +int get_list_count(struct list *l); + +/* + * Return the first element (content of the node) from the list + */ +void *first_elem(struct list *l); + +/* + * Return the first node from the list + */ +struct list_node *first_node(struct list *l); + +/* + * Return the last element (content of the node) from the list + */ +void *last_elem(struct list *l); + +/* + * Return the last node from the list + */ +struct list_node *last_node(struct list *l); + +/* + * Search an element of the list by content + * the comparison is done from the specified offset and for a specified length + * if offset=0, the comparison starts from the address pointed by data + * if length=0, default keysize is used for length + * if the element is found, return the node address + * else return NULL + */ +struct list_node *xlocate_node(struct list *l,void *elem,int offset,int length); + +/* + * The same of xlocate_node(), but return the content of the node + */ +void *xlocate_elem(struct list *l,void *elem,int offset,int length); + +/* + * The same of calling xlocate_node() with offset=0 and length=0 + */ +struct list_node *locate_node(struct list *l,void *elem); + +/* + * The same of locate_node, but return the content of the node + */ +void *locate_elem(struct list *l,void *elem); + +/* + * Delete all the elements in the list + */ +void clear_list(struct list *l); + +/* + * Delete every element in the list, and free the memory pointed by all the node data + */ +void destroy_list(struct list *l); + +#endif diff --git a/deps/cpulimit-fork/src/memrchr.c b/deps/cpulimit-fork/src/memrchr.c new file mode 100644 index 0000000..1f37870 --- /dev/null +++ b/deps/cpulimit-fork/src/memrchr.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2007 Todd C. Miller + * + * Permission to use, copy, modify, and 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 + +/* + * Reverse memchr() + * Find the last occurrence of 'c' in the buffer 's' of size 'n'. + */ +void * +memrchr(s, c, n) + const void *s; + int c; + size_t n; +{ + if (n != 0) { + const unsigned char *cp; + cp = (unsigned char *)s + n; + do { + if (*(--cp) == (unsigned char)c) + return((void *)cp); + } while (--n != 0); + } + return((void *)0); +} diff --git a/deps/cpulimit-fork/src/process_group.c b/deps/cpulimit-fork/src/process_group.c new file mode 100644 index 0000000..17a2cd4 --- /dev/null +++ b/deps/cpulimit-fork/src/process_group.c @@ -0,0 +1,251 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "process_iterator.h" +#include "process_group.h" +#include "list.h" + +// look for a process by pid +// search_pid : pid of the wanted process +// return: pid of the found process, if successful +// negative pid, if the process does not exist or if the signal fails +int find_process_by_pid(pid_t pid) +{ + return (kill(pid,0)==0) ? pid : -pid; +} + +// look for a process with a given name +// process: the name of the wanted process. it can be an absolute path name to the executable file +// or just the file name +// return: pid of the found process, if it is found +// 0, if it's not found +// negative pid, if it is found but it's not possible to control it +int find_process_by_name(const char *process_name) +{ + //pid of the target process + pid_t pid = -1; + + //process iterator + struct process_iterator it; + struct process proc; + struct process_filter filter; + filter.pid = 0; + filter.include_children = 0; + init_process_iterator(&it, &filter); + while (get_next_process(&it, &proc) != -1) + { + //process found + if (strncmp(basename(proc.command), process_name, strlen(process_name))==0 && kill(pid,SIGCONT)==0) { + //process is ok! + pid = proc.pid; + break; + } + } + if (close_process_iterator(&it) != 0) exit(1); + if (pid >= 0) { + //ok, the process was found + return pid; + } + else { + //process not found + return 0; + } +} + +int init_process_group(struct process_group *pgroup, int target_pid, int include_children) +{ + //hashtable initialization + memset(&pgroup->proctable, 0, sizeof(pgroup->proctable)); + pgroup->target_pid = target_pid; + pgroup->include_children = include_children; + pgroup->proclist = (struct list*)malloc(sizeof(struct list)); + init_list(pgroup->proclist, 4); + memset(&pgroup->last_update, 0, sizeof(pgroup->last_update)); + update_process_group(pgroup); + return 0; +} + +int close_process_group(struct process_group *pgroup) +{ + int i; + int size = sizeof(pgroup->proctable) / sizeof(struct process*); + for (i=0; iproctable[i] != NULL) { + //free() history for each process + destroy_list(pgroup->proctable[i]); + free(pgroup->proctable[i]); + pgroup->proctable[i] = NULL; + } + } + clear_list(pgroup->proclist); + free(pgroup->proclist); + pgroup->proclist = NULL; + return 0; +} + +void remove_terminated_processes(struct process_group *pgroup) +{ + //TODO +} + +//return t1-t2 in microseconds (no overflow checks, so better watch out!) +static inline unsigned long timediff(const struct timeval *t1,const struct timeval *t2) +{ + return (t1->tv_sec - t2->tv_sec) * 1000000 + (t1->tv_usec - t2->tv_usec); +} + +//parameter in range 0-1 +#define ALFA 0.08 +#define MIN_DT 20 + +void update_process_group_fast(struct process_group *pgroup, int cycle, int verbose) +{ + struct list_node *node; + struct process tmp_process; + struct timeval now; + long dt; + double sample; + + gettimeofday(&now, NULL); + //time elapsed from previous sample (in ms) + dt = timediff(&now, &pgroup->last_update) / 1000; + + //estimate how much the controlled processes are using the cpu in the working interval + for (node = pgroup->proclist->first; node != NULL; node = node->next) { + struct process *proc = (struct process*)(node->data); + + if (read_process_info(proc->pid, &tmp_process) != 0) + { + continue; + } + + sample = 1.0 * (tmp_process.cputime - proc->cputime) / dt; + if (proc->cpu_usage == -1) { + //initialization + proc->cpu_usage = sample; + } + else { + //usage adjustment + proc->cpu_usage = (1.0-ALFA) * proc->cpu_usage + ALFA * sample; + } + proc->cputime = tmp_process.cputime; + + if (verbose && cycle % 10 == 0) + { + printf( + "%d %5.2lf, ", + proc->pid, + proc->cpu_usage * 100 + ); + } + proc->cputime = tmp_process.cputime; + } + pgroup->last_update = now; +} + +void update_process_group(struct process_group *pgroup) +{ + struct process_iterator it; + struct process tmp_process; + struct process_filter filter; + struct timeval now; + gettimeofday(&now, NULL); + //time elapsed from previous sample (in ms) + long dt = timediff(&now, &pgroup->last_update) / 1000; + filter.pid = pgroup->target_pid; + filter.include_children = pgroup->include_children; + init_process_iterator(&it, &filter); + clear_list(pgroup->proclist); + init_list(pgroup->proclist, 4); + + while (get_next_process(&it, &tmp_process) != -1) + { +// struct timeval t; +// gettimeofday(&t, NULL); +// printf("T=%ld.%ld PID=%d PPID=%d START=%d CPUTIME=%d\n", t.tv_sec, t.tv_usec, tmp_process.pid, tmp_process.ppid, tmp_process.starttime, tmp_process.cputime); + int hashkey = pid_hashfn(tmp_process.pid); + if (pgroup->proctable[hashkey] == NULL) + { + //empty bucket + pgroup->proctable[hashkey] = malloc(sizeof(struct list)); + struct process *new_process = malloc(sizeof(struct process)); + tmp_process.cpu_usage = -1; + memcpy(new_process, &tmp_process, sizeof(struct process)); + init_list(pgroup->proctable[hashkey], 4); + add_elem(pgroup->proctable[hashkey], new_process); + add_elem(pgroup->proclist, new_process); + } + else + { + //existing bucket + struct process *p = (struct process*)locate_elem(pgroup->proctable[hashkey], &tmp_process); + if (p == NULL) + { + //process is new. add it + struct process *new_process = malloc(sizeof(struct process)); + tmp_process.cpu_usage = -1; + memcpy(new_process, &tmp_process, sizeof(struct process)); + add_elem(pgroup->proctable[hashkey], new_process); + add_elem(pgroup->proclist, new_process); + } + else + { + assert(tmp_process.pid == p->pid); + assert(tmp_process.starttime == p->starttime); + add_elem(pgroup->proclist, p); + if (dt < MIN_DT) continue; + //process exists. update CPU usage + double sample = 1.0 * (tmp_process.cputime - p->cputime) / dt; + if (p->cpu_usage == -1) { + //initialization + p->cpu_usage = sample; + } + else { + //usage adjustment + p->cpu_usage = (1.0-ALFA) * p->cpu_usage + ALFA * sample; + } + p->cputime = tmp_process.cputime; + } + } + } + close_process_iterator(&it); + if (dt < MIN_DT) return; + pgroup->last_update = now; +} + +int remove_process(struct process_group *pgroup, int pid) +{ + int hashkey = pid_hashfn(pid); + if (pgroup->proctable[hashkey] == NULL) return 1; //nothing to delete + struct list_node *node = (struct list_node*)locate_node(pgroup->proctable[hashkey], &pid); + if (node == NULL) return 2; + delete_node(pgroup->proctable[hashkey], node); + return 0; +} diff --git a/deps/cpulimit-fork/src/process_group.h b/deps/cpulimit-fork/src/process_group.h new file mode 100644 index 0000000..c7f83cb --- /dev/null +++ b/deps/cpulimit-fork/src/process_group.h @@ -0,0 +1,59 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __PROCESS_GROUP_H + +#define __PROCESS_GROUP_H + +#include "process_iterator.h" + +#include "list.h" + +#define PIDHASH_SZ 1024 +#define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1)) + +struct process_group +{ + //hashtable with all the processes (array of struct list of struct process) + struct list *proctable[PIDHASH_SZ]; + struct list *proclist; + pid_t target_pid; + int include_children; + struct timeval last_update; +}; + +#ifdef __linux__ +void update_process_group_fast(struct process_group *pgroup, int cycle, int verbose); +#endif + +int init_process_group(struct process_group *pgroup, int target_pid, int include_children); + +void update_process_group(struct process_group *pgroup); + +int close_process_group(struct process_group *pgroup); + +int find_process_by_pid(pid_t pid); + +int find_process_by_name(const char *process_name); + +int remove_process(struct process_group *pgroup, int pid); + +#endif diff --git a/deps/cpulimit-fork/src/process_iterator.c b/deps/cpulimit-fork/src/process_iterator.c new file mode 100644 index 0000000..8b4019d --- /dev/null +++ b/deps/cpulimit-fork/src/process_iterator.c @@ -0,0 +1,49 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#ifndef __APPLE__ +#include +#endif +#include +#include "process_iterator.h" + +//See this link to port to other systems: http://www.steve.org.uk/Reference/Unix/faq_8.html#SEC85 + +#ifdef __linux__ + +#include "process_iterator_linux.c" + +#elif defined __FreeBSD__ + +#include "process_iterator_freebsd.c" + +#elif defined __APPLE__ + +#include "process_iterator_apple.c" + +#else + +#error Platform not supported + +#endif diff --git a/deps/cpulimit-fork/src/process_iterator.h b/deps/cpulimit-fork/src/process_iterator.h new file mode 100644 index 0000000..b7726a8 --- /dev/null +++ b/deps/cpulimit-fork/src/process_iterator.h @@ -0,0 +1,101 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __PROCESS_ITERATOR_H + +#define __PROCESS_ITERATOR_H + +#include +#include +#include + +//USER_HZ detection, from openssl code +#ifndef HZ +# if defined(_SC_CLK_TCK) \ + && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000) +# define HZ ((double)sysconf(_SC_CLK_TCK)) +# else +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ +# define HZ 100.0 +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +# endif +#endif + +#ifdef __FreeBSD__ +#include +#endif + +// process descriptor +struct process { + //pid of the process + pid_t pid; + //ppid of the process + pid_t ppid; + //start time (unix timestamp) + int starttime; + //cputime used by the process (in milliseconds) + int cputime; + //actual cpu usage estimation (value in range 0-1) + double cpu_usage; + //absolute path of the executable file + char command[PATH_MAX+1]; +}; + +struct process_filter { + int pid; + int include_children; + char program_name[PATH_MAX+1]; +}; + +struct process_iterator { +#ifdef __linux__ + DIR *dip; + int boot_time; +#elif defined __FreeBSD__ + kvm_t *kd; + struct kinfo_proc *procs; + int count; + int i; +#elif defined __APPLE__ + int i; + int count; + int *pidlist; +#endif + struct process_filter *filter; +}; + +#ifdef __linux__ +int read_process_info(pid_t pid, struct process *p); +#endif + +int init_process_iterator(struct process_iterator *i, struct process_filter *filter); + +int get_next_process(struct process_iterator *i, struct process *p); + +int close_process_iterator(struct process_iterator *i); + +#endif diff --git a/deps/cpulimit-fork/src/process_iterator_apple.c b/deps/cpulimit-fork/src/process_iterator_apple.c new file mode 100644 index 0000000..b878ed8 --- /dev/null +++ b/deps/cpulimit-fork/src/process_iterator_apple.c @@ -0,0 +1,148 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Author: Simon Sigurdhsson + * + */ + +#include +#include +#include + +int unique_nonzero_ints(int* arr_in, int len_in, int* arr_out) { + int* source = arr_in; + if (arr_out == NULL) return -1; + if (arr_in == arr_out) { + source = malloc(sizeof(int)*len_in); + memcpy(source, arr_in, sizeof(int)*len_in); + memset(arr_out, -1, sizeof(int)*len_in); + } + int len_out = 0; + int i, j; + for (i=0; ii = 0; + /* Find out how much to allocate for it->pidlist */ + if ((it->count = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0)) <= 0) { + fprintf(stderr, "proc_listpids: %s\n", strerror(errno)); + return -1; + } + /* Allocate and populate it->pidlist */ + if ((it->pidlist = (int *)malloc((it->count)*sizeof(int))) == NULL) { + fprintf(stderr, "malloc: %s\n", strerror(errno)); + } + if ((it->count = proc_listpids(PROC_ALL_PIDS, 0, it->pidlist, it->count)) <= 0) { + fprintf(stderr, "proc_listpids: %s\n", strerror(errno)); + return -1; + } + it->count = unique_nonzero_ints(it->pidlist, it->count, it->pidlist); + it->filter = filter; + return 0; +} + +static int pti2proc(struct proc_taskallinfo *ti, struct process *process) { + int bytes; + process->pid = ti->pbsd.pbi_pid; + process->ppid = ti->pbsd.pbi_ppid; + process->starttime = ti->pbsd.pbi_start_tvsec; + process->cputime = (ti->ptinfo.pti_total_user + ti->ptinfo.pti_total_system) / 1000000; + bytes = strlen(ti->pbsd.pbi_comm); + memcpy(process->command, ti->pbsd.pbi_comm, (bytes < PATH_MAX ? bytes : PATH_MAX) + 1); + return 0; +} + +static int get_process_pti(pid_t pid, struct proc_taskallinfo *ti) { + int bytes; + bytes = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, ti, sizeof(*ti)); + if (bytes <= 0) { + if (!(errno & (EPERM | ESRCH))) { + fprintf(stderr, "proc_pidinfo: %s\n", strerror(errno)); + } + return -1; + } else if (bytes < sizeof(ti)) { + fprintf(stderr, "proc_pidinfo: too few bytes; expected %ld, got %d\n", sizeof(ti), bytes); + return -1; + } + return 0; +} + +int get_next_process(struct process_iterator *it, struct process *p) { + if (it->i == it->count) return -1; + if (it->filter->pid != 0 && !it->filter->include_children) { + struct proc_taskallinfo ti; + if (get_process_pti(it->filter->pid, &ti) != 0) { + it->i = it->count = 0; + return -1; + } + it->i = it->count = 1; + return pti2proc(&ti, p); + } + while (it->i < it->count) { + struct proc_taskallinfo ti; + if (get_process_pti(it->pidlist[it->i], &ti) != 0) { + it->i++; + continue; + } + if (ti.pbsd.pbi_flags & PROC_FLAG_SYSTEM) { + it->i++; + continue; + } + if (it->filter->pid != 0 && it->filter->include_children) { + pti2proc(&ti, p); + it->i++; + if (p->pid != it->pidlist[it->i - 1]) // I don't know why this can happen + continue; + if (p->pid != it->filter->pid && p->ppid != it->filter->pid) + continue; + return 0; + } + else if (it->filter->pid == 0) + { + pti2proc(&ti, p); + it->i++; + return 0; + } + } + return -1; +} + +int close_process_iterator(struct process_iterator *it) { + free(it->pidlist); + it->pidlist = NULL; + it->filter = NULL; + it->count = 0; + it->i = 0; + return 0; +} diff --git a/deps/cpulimit-fork/src/process_iterator_freebsd.c b/deps/cpulimit-fork/src/process_iterator_freebsd.c new file mode 100644 index 0000000..a638112 --- /dev/null +++ b/deps/cpulimit-fork/src/process_iterator_freebsd.c @@ -0,0 +1,119 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +int init_process_iterator(struct process_iterator *it, struct process_filter *filter) { + char errbuf[_POSIX2_LINE_MAX]; + it->i = 0; + /* Open the kvm interface, get a descriptor */ + if ((it->kd = kvm_openfiles(NULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf)) == NULL) { + fprintf(stderr, "kvm_open: %s\n", errbuf); + return -1; + } + /* Get the list of processes. */ + if ((it->procs = kvm_getprocs(it->kd, KERN_PROC_PROC, 0, &it->count)) == NULL) { + kvm_close(it->kd); +// fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(it->kd)); + return -1; + } + it->filter = filter; + return 0; +} + +static int kproc2proc(kvm_t *kd, struct kinfo_proc *kproc, struct process *proc) +{ + proc->pid = kproc->ki_pid; + proc->ppid = kproc->ki_ppid; + proc->cputime = kproc->ki_runtime / 1000; + proc->starttime = kproc->ki_start.tv_sec; + char **args = kvm_getargv(kd, kproc, sizeof(proc->command)); + if (args == NULL) return -1; + memcpy(proc->command, args[0], strlen(args[0]) + 1); + return 0; +} + +static int get_single_process(kvm_t *kd, pid_t pid, struct process *process) +{ + int count; + struct kinfo_proc *kproc = kvm_getprocs(kd, KERN_PROC_PID, pid, &count); + if (count == 0 || kproc == NULL) + { +// fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(kd)); + return -1; + } + kproc2proc(kd, kproc, process); + return 0; +} + +int get_next_process(struct process_iterator *it, struct process *p) { + if (it->i == it->count) + { + return -1; + } + if (it->filter->pid != 0 && !it->filter->include_children) + { + if (get_single_process(it->kd, it->filter->pid, p) != 0) + { + it->i = it->count = 0; + return -1; + } + it->i = it->count = 1; + return 0; + } + while (it->i < it->count) + { + struct kinfo_proc *kproc = &(it->procs[it->i]); + if (kproc->ki_flag & P_SYSTEM) + { + // skip system processes + it->i++; + continue; + } + if (it->filter->pid != 0 && it->filter->include_children) + { + kproc2proc(it->kd, kproc, p); + it->i++; + if (p->pid != it->filter->pid && p->ppid != it->filter->pid) + continue; + return 0; + } + else if (it->filter->pid == 0) + { + kproc2proc(it->kd, kproc, p); + it->i++; + return 0; + } + } + return -1; +} + +int close_process_iterator(struct process_iterator *it) { + if (kvm_close(it->kd) == -1) { + fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(it->kd)); + return -1; + } + return 0; +} + diff --git a/deps/cpulimit-fork/src/process_iterator_linux.c b/deps/cpulimit-fork/src/process_iterator_linux.c new file mode 100644 index 0000000..3f14d6e --- /dev/null +++ b/deps/cpulimit-fork/src/process_iterator_linux.c @@ -0,0 +1,181 @@ +/** + * + * cpulimit - a CPU limiter for Linux + * + * Copyright (C) 2005-2012, by: Angelo Marletta + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +static int get_boot_time() +{ + int uptime = 0; + FILE *fp = fopen ("/proc/uptime", "r"); + if (fp != NULL) + { + char buf[BUFSIZ]; + char *b = fgets(buf, BUFSIZ, fp); + if (b == buf) + { + char *end_ptr; + double upsecs = strtod(buf, &end_ptr); + uptime = (int)upsecs; + } + fclose (fp); + } + time_t now = time(NULL); + return now - uptime; +} + +static int check_proc() +{ + struct statfs mnt; + if (statfs("/proc", &mnt) < 0) + return 0; + if (mnt.f_type!=0x9fa0) + return 0; + return 1; +} + +int init_process_iterator(struct process_iterator *it, struct process_filter *filter) +{ + if (!check_proc()) { + fprintf(stderr, "procfs is not mounted!\nAborting\n"); + exit(-2); + } + //open a directory stream to /proc directory + if ((it->dip = opendir("/proc")) == NULL) + { + perror("opendir"); + return -1; + } + it->filter = filter; + it->boot_time = get_boot_time(); + return 0; +} + +int read_process_info(pid_t pid, struct process *p) +{ + static char buffer[1024]; + static char statfile[32]; + static char exefile[1024]; + p->pid = pid; + //read stat file + sprintf(statfile, "/proc/%d/stat", p->pid); + FILE *fd = fopen(statfile, "r"); + if (fd==NULL) return -1; + if (fgets(buffer, sizeof(buffer), fd)==NULL) { + fclose(fd); + return -1; + } + fclose(fd); + char *token = strtok(buffer, " "); + int i; + for (i=0; i<3; i++) token = strtok(NULL, " "); + p->ppid = atoi(token); + for (i=0; i<10; i++) + token = strtok(NULL, " "); + p->cputime = atoi(token) * 1000 / HZ; + token = strtok(NULL, " "); + p->cputime += atoi(token) * 1000 / HZ; + for (i=0; i<7; i++) + token = strtok(NULL, " "); + p->starttime = atoi(token) / sysconf(_SC_CLK_TCK); + //read command line + sprintf(exefile,"/proc/%d/cmdline", p->pid); + fd = fopen(exefile, "r"); + if (fgets(buffer, sizeof(buffer), fd)==NULL) { + fclose(fd); + return -1; + } + fclose(fd); + strcpy(p->command, buffer); + return 0; +} + +static pid_t getppid_of(pid_t pid) +{ + char statfile[20]; + char buffer[1024]; + sprintf(statfile, "/proc/%d/stat", pid); + FILE *fd = fopen(statfile, "r"); + if (fd==NULL) return -1; + if (fgets(buffer, sizeof(buffer), fd)==NULL) { + fclose(fd); + return -1; + } + fclose(fd); + char *token = strtok(buffer, " "); + int i; + for (i=0; i<3; i++) token = strtok(NULL, " "); + return atoi(token); +} + +static int is_child_of(pid_t child_pid, pid_t parent_pid) +{ + int ppid = child_pid; + while(ppid > 1 && ppid != parent_pid) { + ppid = getppid_of(ppid); + } + return ppid == parent_pid; +} + +int get_next_process(struct process_iterator *it, struct process *p) +{ + if (it->dip == NULL) + { + //end of processes + return -1; + } + if (it->filter->pid != 0 && !it->filter->include_children) + { + int ret = read_process_info(it->filter->pid, p); + //p->starttime += it->boot_time; + closedir(it->dip); + it->dip = NULL; + if (ret != 0) return -1; + return 0; + } + struct dirent *dit = NULL; + //read in from /proc and seek for process dirs + while ((dit = readdir(it->dip)) != NULL) { + if(strtok(dit->d_name, "0123456789") != NULL) + continue; + p->pid = atoi(dit->d_name); + if (it->filter->pid != 0 && it->filter->pid != p->pid && !is_child_of(p->pid, it->filter->pid)) continue; + read_process_info(p->pid, p); + //p->starttime += it->boot_time; + break; + } + if (dit == NULL) + { + //end of processes + closedir(it->dip); + it->dip = NULL; + return -1; + } + return 0; +} + +int close_process_iterator(struct process_iterator *it) { + if (it->dip != NULL && closedir(it->dip) == -1) { + perror("closedir"); + return 1; + } + it->dip = NULL; + return 0; +} diff --git a/deps/cpulimit-fork/tests/Makefile b/deps/cpulimit-fork/tests/Makefile new file mode 100644 index 0000000..764db87 --- /dev/null +++ b/deps/cpulimit-fork/tests/Makefile @@ -0,0 +1,23 @@ +CC?=gcc +CFLAGS?=-Wall -g +TARGETS=busy process_iterator_test +SRC=../src +SYSLIBS?=-lpthread +LIBS=$(SRC)/list.o $(SRC)/process_iterator.o $(SRC)/process_group.o +UNAME := $(shell uname) + +ifeq ($(UNAME), FreeBSD) +LIBS+=-lkvm +endif + +all:: $(TARGETS) + +busy: busy.c + $(CC) -o busy busy.c $(SYSLIBS) $(CFLAGS) + +process_iterator_test: process_iterator_test.c $(LIBS) + $(CC) -I$(SRC) -o process_iterator_test process_iterator_test.c $(LIBS) $(SYSLIBS) $(CFLAGS) + +clean: + rm -f *~ *.o $(TARGETS) + diff --git a/deps/cpulimit-fork/tests/busy.c b/deps/cpulimit-fork/tests/busy.c new file mode 100644 index 0000000..b3afb7c --- /dev/null +++ b/deps/cpulimit-fork/tests/busy.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +void *loop() +{ + while(1); +} + +int main(int argc, char **argv) { + + int i = 0; + int num_threads = 1; + if (argc == 2) num_threads = atoi(argv[1]); + for (i=0; i + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ || __FREEBSD__ +#include +#endif + +#include +#include + +volatile sig_atomic_t child; + +void kill_child(int sig) +{ + kill(child, SIGINT); +} + +void test_single_process() +{ + struct process_iterator it; + struct process process; + struct process_filter filter; + int count; + //don't iterate children + filter.pid = getpid(); + filter.include_children = 0; + count = 0; +// time_t now = time(NULL); + init_process_iterator(&it, &filter); + while (get_next_process(&it, &process) == 0) + { + assert(process.pid == getpid()); + assert(process.ppid == getppid()); + assert(process.cputime < 100); +// assert(process.starttime == now || process.starttime == now - 1); + count++; + } + assert(count == 1); + close_process_iterator(&it); + //iterate children + filter.pid = getpid(); + filter.include_children = 0; + count = 0; +// now = time(NULL); + init_process_iterator(&it, &filter); + while (get_next_process(&it, &process) == 0) + { + assert(process.pid == getpid()); + assert(process.ppid == getppid()); + assert(process.cputime < 100); +// assert(process.starttime == now || process.starttime == now - 1); + count++; + } + assert(count == 1); + close_process_iterator(&it); +} + +void test_multiple_process() +{ + struct process_iterator it; + struct process process; + struct process_filter filter; + pid_t child = fork(); + if (child == 0) + { + //child is supposed to be killed by the parent :/ + sleep(1); + exit(1); + } + filter.pid = getpid(); + filter.include_children = 1; + init_process_iterator(&it, &filter); + int count = 0; +// time_t now = time(NULL); + while (get_next_process(&it, &process) == 0) + { + if (process.pid == getpid()) assert(process.ppid == getppid()); + else if (process.pid == child) assert(process.ppid == getpid()); + else assert(0); + assert(process.cputime < 100); +// assert(process.starttime == now || process.starttime == now - 1); + count++; + } + assert(count == 2); + close_process_iterator(&it); + kill(child, SIGINT); +} + +void test_all_processes() +{ + struct process_iterator it; + struct process process; + struct process_filter filter; + filter.pid = 0; + filter.include_children = 0; + init_process_iterator(&it, &filter); + int count = 0; +// time_t now = time(NULL); + while (get_next_process(&it, &process) == 0) + { + if (process.pid == getpid()) + { + assert(process.ppid == getppid()); + assert(process.cputime < 100); +// assert(process.starttime == now || process.starttime == now - 1); + } + count++; + } + assert(count >= 10); + close_process_iterator(&it); +} + +void test_process_group_all() +{ + struct process_group pgroup; + assert(init_process_group(&pgroup, 0, 0) == 0); + update_process_group(&pgroup); + struct list_node *node = NULL; + int count = 0; + for (node=pgroup.proclist->first; node!= NULL; node=node->next) { + count++; + } + assert(count > 10); + update_process_group(&pgroup); + assert(close_process_group(&pgroup) == 0); +} + +void test_process_group_single(int include_children) +{ + struct process_group pgroup; + child = fork(); + if (child == 0) + { + //child is supposed to be killed by the parent :/ + while(1); + exit(1); + } + signal(SIGABRT, &kill_child); + signal(SIGTERM, &kill_child); + assert(init_process_group(&pgroup, child, include_children) == 0); + int i; + double tot_usage = 0; + for (i=0; i<100; i++) + { + update_process_group(&pgroup); + struct list_node *node = NULL; + int count = 0; + for (node=pgroup.proclist->first; node!= NULL; node=node->next) { + struct process *p = (struct process*)(node->data); + assert(p->pid == child); + assert(p->ppid == getpid()); + assert(p->cpu_usage <= 1.2); + tot_usage += p->cpu_usage; + count++; + } + assert(count == 1); + struct timespec interval; + interval.tv_sec = 0; + interval.tv_nsec = 50000000; + nanosleep(&interval, NULL); + } + assert(tot_usage / i < 1.1 && tot_usage / i > 0.8); + assert(close_process_group(&pgroup) == 0); + kill(child, SIGINT); +} + +void test_process_name(const char * command) +{ + struct process_iterator it; + struct process process; + struct process_filter filter; + filter.pid = getpid(); + filter.include_children = 0; + init_process_iterator(&it, &filter); + assert(get_next_process(&it, &process) == 0); + assert(process.pid == getpid()); + assert(process.ppid == getppid()); + #ifdef __APPLE__ + // proc_pidinfo only gives us the first 15 chars + // of the basename of the command on OSX. + assert(strncmp(basename((char*)command), process.command, 15) == 0); + #else + assert(strncmp(command, process.command, strlen(process.command)) == 0); + #endif + assert(get_next_process(&it, &process) != 0); + close_process_iterator(&it); +} + +void test_process_group_wrong_pid() +{ + struct process_group pgroup; + assert(init_process_group(&pgroup, -1, 0) == 0); + assert(pgroup.proclist->count == 0); + update_process_group(&pgroup); + assert(pgroup.proclist->count == 0); + assert(init_process_group(&pgroup, 9999999, 0) == 0); + assert(pgroup.proclist->count == 0); + update_process_group(&pgroup); + assert(pgroup.proclist->count == 0); + assert(close_process_group(&pgroup) == 0); +} + +int main(int argc, char **argv) +{ +// printf("Pid %d\n", getpid()); + test_single_process(); + test_multiple_process(); + test_all_processes(); + test_process_group_all(); + test_process_group_single(0); + test_process_group_single(1); + test_process_group_wrong_pid(); + test_process_name(argv[0]); + return 0; +} diff --git a/deps/cpulimit-fork/tests/run_tests.sh b/deps/cpulimit-fork/tests/run_tests.sh new file mode 100644 index 0000000..e69de29