aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Knechtges <philipp-dev@knechtges.com>2011-05-21 12:32:30 (GMT)
committerPhilipp Knechtges <philipp-dev@knechtges.com>2011-08-17 16:10:46 (GMT)
commit66b2cc4d31e380e3b2bc7e47477029fc39fb7ac7 (patch)
tree24810d85a84fa1d62606b16f011cda7ee889d3bf
parent51bdd3bcd1cad9662149413035bd21ea4e59bc0c (diff)
libkworkspace: tuning glibc allocator
Some applications like kwin suffer from heap fragmentation when using the raster graphicssystem. This patch provides a function that forces glibc to shrink the heap more often. Now 5*pagesize(=20kB on a typical x86 system) of unused space at the end of the heap are enough to force free() to release this space. The default threshold is 128kB which is too much for an average kworkspace application. REVIEW: 101385 (cherry picked from commit d8949d77b5bc33d540dc7f791cee3691ee9dbb85)
-rw-r--r--ConfigureChecks.cmake2
-rw-r--r--config-workspace.h.cmake3
-rw-r--r--kwin/main.cpp3
-rw-r--r--libs/kworkspace/kworkspace.cpp29
-rw-r--r--libs/kworkspace/kworkspace.h9
5 files changed, 46 insertions, 0 deletions
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index e8b64a2..b5767b5 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -60,6 +60,8 @@ check_include_files("sys/stat.h;sys/statvfs.h" HAVE_SYS_STATVFS_H) # statvfs for
check_include_files(sys/param.h HAVE_SYS_PARAM_H)
check_include_files("sys/param.h;sys/mount.h" HAVE_SYS_MOUNT_H)
check_include_files("sys/types.h;sys/statfs.h" HAVE_SYS_STATFS_H)
+check_include_files(unistd.h HAVE_UNISTD_H)
+check_include_files(malloc.h HAVE_MALLOC_H)
check_function_exists(statfs HAVE_STATFS)
macro_bool_to_01(FONTCONFIG_FOUND HAVE_FONTCONFIG) # kcontrol/{fonts,kfontinst}
macro_bool_to_01(FREETYPE_FOUND HAVE_FREETYPE) # kcontrol/fonts
diff --git a/config-workspace.h.cmake b/config-workspace.h.cmake
index fabe7fa..f482085 100644
--- a/config-workspace.h.cmake
+++ b/config-workspace.h.cmake
@@ -99,6 +99,9 @@
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
+/* Define to 1 if you have the <malloc.h> header file. */
+#cmakedefine HAVE_MALLOC_H 1
+
/* Define if you have unsetenv */
#cmakedefine HAVE_UNSETENV 1
diff --git a/kwin/main.cpp b/kwin/main.cpp
index f767f54..b92bee6 100644
--- a/kwin/main.cpp
+++ b/kwin/main.cpp
@@ -51,6 +51,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QLabel>
#include <KComboBox>
#include <QVBoxLayout>
+#include <kworkspace.h>
#include <ksmserver_interface.h>
@@ -404,6 +405,8 @@ KDE_EXPORT int kdemain(int argc, char * argv[])
}
}
+ KWorkSpace::trimMalloc();
+
Display* dpy = XOpenDisplay(NULL);
if (!dpy) {
fprintf(stderr, "%s: FATAL ERROR while trying to open display %s\n",
diff --git a/libs/kworkspace/kworkspace.cpp b/libs/kworkspace/kworkspace.cpp
index 5e9afb9..0b4146e 100644
--- a/libs/kworkspace/kworkspace.cpp
+++ b/libs/kworkspace/kworkspace.cpp
@@ -47,7 +47,16 @@
#define DISPLAY "QWS_DISPLAY"
#endif
+#include "config-workspace.h"
+
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif // HAVE_UNISTD_H
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif // HAVE_MALLOC_H
+
#include <pwd.h>
#include <sys/types.h>
@@ -252,6 +261,26 @@ void propagateSessionManager()
#endif
}
+void trimMalloc()
+{
+#ifndef Q_WS_WIN
+#ifdef M_TRIM_THRESHOLD
+ // Prevent fragmentation of the heap by malloc (glibc).
+ //
+ // The default threshold is 128*1024, which can result in a large memory usage
+ // due to fragmentation especially if we use the raster graphicssystem. On the
+ // otherside if the threshold is too low, free() starts to permanently ask the kernel
+ // about shrinking the heap.
+#ifdef HAVE_UNISTD_H
+ const int pagesize = sysconf(_SC_PAGESIZE);
+#else
+ const int pagesize = 4*1024;
+#endif // HAVE_UNISTD_H
+ mallopt(M_TRIM_THRESHOLD, 5*pagesize);
+#endif // M_TRIM_THRESHOLD
+#endif // Q_WS_WIN
+}
+
} // end namespace
#include "kworkspace_p.moc"
diff --git a/libs/kworkspace/kworkspace.h b/libs/kworkspace/kworkspace.h
index f24ea42..2516c3a 100644
--- a/libs/kworkspace/kworkspace.h
+++ b/libs/kworkspace/kworkspace.h
@@ -147,6 +147,15 @@ namespace KWorkSpace
*/
KDE_EXPORT void propagateSessionManager();
+ /**
+ * This function should be called at startup to prevent heap fragmentation
+ * in applications that perform many low-level pixmap operations (e.g. kwin).
+ *
+ * It lowers the threshold above which the glibc returns the memory to the kernel
+ * from 120 kB of free space at the end of the heap to 5*pagesize (= 20 kB for x86-64).
+ */
+ KDE_EXPORT void trimMalloc();
+
}
#endif