mirror of
https://github.com/X11Libre/xserver.git
synced 2026-10-28 02:21:08 +00:00
Merge 1b5cf6a6d2 into a8192aa709
This commit is contained in:
commit
0f76375cb9
12 changed files with 280 additions and 12 deletions
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <dix-config.h>
|
#include <dix-config.h>
|
||||||
|
|
||||||
|
#include "dix/dix_priv.h"
|
||||||
#include "dix/screenint_priv.h"
|
#include "dix/screenint_priv.h"
|
||||||
#include "include/mipict.h"
|
#include "include/mipict.h"
|
||||||
#include "include/misc.h"
|
#include "include/misc.h"
|
||||||
|
|
@ -692,3 +693,15 @@ void SetGlyphPicture(GlyphPtr glyph, ScreenPtr pScreen, PicturePtr picture)
|
||||||
{
|
{
|
||||||
GlyphPicture(glyph)[pScreen->myNum] = picture;
|
GlyphPicture(glyph)[pScreen->myNum] = picture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dixTrimGlyphHash(void)
|
||||||
|
{
|
||||||
|
int fdepth;
|
||||||
|
|
||||||
|
for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) {
|
||||||
|
if (globalGlyphs[fdepth].hashSet && globalGlyphs[fdepth].table) {
|
||||||
|
ResizeGlyphHash(&globalGlyphs[fdepth], 0, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -885,4 +885,20 @@ x_rpcbuf_t dixBuildConnectionBlock(int maxscreens);
|
||||||
*/
|
*/
|
||||||
char *dixNewConnectionInfoBlock(ClientPtr pClient, size_t *sz, size_t *scrOffset);
|
char *dixNewConnectionInfoBlock(ClientPtr pClient, size_t *sz, size_t *scrOffset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* empty the font pattern cache
|
||||||
|
*/
|
||||||
|
void dixEmptyFontPatternCache(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* trim resource tables for idle clients
|
||||||
|
*/
|
||||||
|
void dixTrimResourceTables(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* trim global glyph hash tables
|
||||||
|
*/
|
||||||
|
void dixTrimGlyphHash(void);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _XSERVER_DIX_PRIV_H */
|
#endif /* _XSERVER_DIX_PRIV_H */
|
||||||
|
|
|
||||||
|
|
@ -2095,3 +2095,12 @@ InitFonts(void)
|
||||||
fontPatternCache = xfont2_make_font_pattern_cache();
|
fontPatternCache = xfont2_make_font_pattern_cache();
|
||||||
xfont2_init(&xfont2_client_funcs);
|
xfont2_init(&xfont2_client_funcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dixEmptyFontPatternCache(void)
|
||||||
|
{
|
||||||
|
if (patternCache)
|
||||||
|
xfont2_empty_font_pattern_cache(patternCache);
|
||||||
|
if (fontPatternCache)
|
||||||
|
xfont2_empty_font_pattern_cache(fontPatternCache);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -887,6 +887,60 @@ RebuildTable(int client)
|
||||||
clientTable[client].resources = resources;
|
clientTable[client].resources = resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ShrinkClientResourceTable(int client)
|
||||||
|
{
|
||||||
|
int j, new_buckets;
|
||||||
|
ResourcePtr **tails, *resources;
|
||||||
|
|
||||||
|
if (clientTable[client].buckets <= INITBUCKETS ||
|
||||||
|
clientTable[client].hashsize <= INITHASHSIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
new_buckets = clientTable[client].buckets / 2;
|
||||||
|
j = new_buckets;
|
||||||
|
tails = calloc(j, sizeof(ResourcePtr *));
|
||||||
|
if (!tails)
|
||||||
|
return;
|
||||||
|
resources = calloc(j, sizeof(ResourcePtr));
|
||||||
|
if (!resources) {
|
||||||
|
free(tails);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (ResourcePtr *rptr = resources, **tptr = tails; --j >= 0; rptr++, tptr++) {
|
||||||
|
*rptr = NULL;
|
||||||
|
*tptr = rptr;
|
||||||
|
}
|
||||||
|
clientTable[client].hashsize--;
|
||||||
|
j = clientTable[client].buckets;
|
||||||
|
for (ResourcePtr *rptr = clientTable[client].resources, **tptr; --j >= 0; rptr++) {
|
||||||
|
for (ResourcePtr res = *rptr, next; res; res = next) {
|
||||||
|
next = res->next;
|
||||||
|
res->next = NULL;
|
||||||
|
tptr = &tails[HashResourceID(res->id, clientTable[client].hashsize)];
|
||||||
|
**tptr = res;
|
||||||
|
*tptr = &res->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(tails);
|
||||||
|
clientTable[client].buckets = new_buckets;
|
||||||
|
free(clientTable[client].resources);
|
||||||
|
clientTable[client].resources = resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dixTrimResourceTables(void)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < currentMaxClients; i++) {
|
||||||
|
if (!clientTable[i].resources || !clientTable[i].buckets)
|
||||||
|
continue;
|
||||||
|
while (clientTable[i].buckets > INITBUCKETS &&
|
||||||
|
clientTable[i].elements <= (clientTable[i].buckets / 2)) {
|
||||||
|
ShrinkClientResourceTable(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
doFreeResource(ResourcePtr res, Bool skip)
|
doFreeResource(ResourcePtr res, Bool skip)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,12 @@ conf_data.set('HAVE_WALKCONTEXT', cc.has_function('walkcontext') ? '1' : false)
|
||||||
conf_data.set('HAVE_XUCRED_CR_PID', cc.has_member('struct xucred', 'cr_pid', prefix : '#include <sys/ucred.h>') ? '1' : false)
|
conf_data.set('HAVE_XUCRED_CR_PID', cc.has_member('struct xucred', 'cr_pid', prefix : '#include <sys/ucred.h>') ? '1' : false)
|
||||||
conf_data.set('LOCK_SERVER', host_machine.system() != 'windows' ? '1' : false)
|
conf_data.set('LOCK_SERVER', host_machine.system() != 'windows' ? '1' : false)
|
||||||
|
|
||||||
|
if get_option('background_memory_trim')
|
||||||
|
conf_data.set('HAVE_MALLOC_TRIM', cc.has_function('malloc_trim', prefix: '#include <malloc.h>') ? '1' : false)
|
||||||
|
conf_data.set('HAVE_MALLOPT', cc.has_function('mallopt', prefix: '#include <malloc.h>') ? '1' : false)
|
||||||
|
conf_data.set('HAVE_MALLOC_H', cc.has_header('malloc.h') ? '1' : false)
|
||||||
|
endif
|
||||||
|
|
||||||
# Don't let X dependencies typedef 'pointer'
|
# Don't let X dependencies typedef 'pointer'
|
||||||
conf_data.set('_XTYPEDEF_POINTER', '1')
|
conf_data.set('_XTYPEDEF_POINTER', '1')
|
||||||
conf_data.set('_XITYPEDEF_POINTER', '1')
|
conf_data.set('_XITYPEDEF_POINTER', '1')
|
||||||
|
|
|
||||||
|
|
@ -185,3 +185,6 @@ option('test_rendercheck_triangles', type: 'boolean', value: false,
|
||||||
description: 'testsuite: run rendercheck triangles tests (might fail on Xephyr)')
|
description: 'testsuite: run rendercheck triangles tests (might fail on Xephyr)')
|
||||||
option('test_xephyr_gles', type: 'boolean', value: true,
|
option('test_xephyr_gles', type: 'boolean', value: true,
|
||||||
description: 'testsuite: run gles2/gles3 tests on Xephyr (might fail w/o DRI)')
|
description: 'testsuite: run gles2/gles3 tests on Xephyr (might fail w/o DRI)')
|
||||||
|
|
||||||
|
option('background_memory_trim', type: 'boolean', value: true,
|
||||||
|
description: 'Trim memory heap and buffers when X server is idle in the background')
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ void miStepDash(int dist, int * pDashIndex, unsigned char * pDash,
|
||||||
|
|
||||||
Bool mieqInit(void);
|
Bool mieqInit(void);
|
||||||
void mieqFini(void);
|
void mieqFini(void);
|
||||||
|
void mieqTrimQueue(void);
|
||||||
void mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e);
|
void mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e);
|
||||||
void mieqSwitchScreen(DeviceIntPtr pDev, ScreenPtr pScreen, Bool set_dequeue_screen);
|
void mieqSwitchScreen(DeviceIntPtr pDev, ScreenPtr pScreen, Bool set_dequeue_screen);
|
||||||
void mieqProcessDeviceEvent(DeviceIntPtr dev, InternalEvent *event, ScreenPtr screen);
|
void mieqProcessDeviceEvent(DeviceIntPtr dev, InternalEvent *event, ScreenPtr screen);
|
||||||
|
|
|
||||||
27
mi/mieq.c
27
mi/mieq.c
|
|
@ -195,6 +195,33 @@ mieqFini(void)
|
||||||
free(miEventQueue.events);
|
free(miEventQueue.events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mieqTrimQueue(void)
|
||||||
|
{
|
||||||
|
input_lock();
|
||||||
|
if (miEventQueue.events && miEventQueue.nevents > QUEUE_INITIAL_SIZE &&
|
||||||
|
mieqNumEnqueued(&miEventQueue) == 0) {
|
||||||
|
EventRec *new_events = calloc(QUEUE_INITIAL_SIZE, sizeof(EventRec));
|
||||||
|
if (new_events) {
|
||||||
|
for (size_t i = 0; i < QUEUE_INITIAL_SIZE; i++) {
|
||||||
|
new_events[i] = miEventQueue.events[i];
|
||||||
|
}
|
||||||
|
for (size_t i = QUEUE_INITIAL_SIZE; i < miEventQueue.nevents; i++) {
|
||||||
|
if (miEventQueue.events[i].events != NULL) {
|
||||||
|
FreeEventList(miEventQueue.events[i].events, 1);
|
||||||
|
miEventQueue.events[i].events = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(miEventQueue.events);
|
||||||
|
miEventQueue.events = new_events;
|
||||||
|
miEventQueue.nevents = QUEUE_INITIAL_SIZE;
|
||||||
|
miEventQueue.head = 0;
|
||||||
|
miEventQueue.tail = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be reentrant with ProcessInputEvents. Assumption: mieqEnqueue
|
* Must be reentrant with ProcessInputEvents. Assumption: mieqEnqueue
|
||||||
* will never be interrupted. Must be called with input_lock held
|
* will never be interrupted. Must be called with input_lock held
|
||||||
|
|
|
||||||
84
os/WaitFor.c
84
os/WaitFor.c
|
|
@ -54,6 +54,10 @@ SOFTWARE.
|
||||||
|
|
||||||
#include <dix-config.h>
|
#include <dix-config.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_MALLOC_H
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -67,6 +71,7 @@ SOFTWARE.
|
||||||
#include "dix/dixstruct_priv.h"
|
#include "dix/dixstruct_priv.h"
|
||||||
#include "dix/screensaver_priv.h"
|
#include "dix/screensaver_priv.h"
|
||||||
#include "include/misc.h"
|
#include "include/misc.h"
|
||||||
|
#include "mi/mi_priv.h"
|
||||||
#include "os/busfault.h"
|
#include "os/busfault.h"
|
||||||
#include "os/client_priv.h"
|
#include "os/client_priv.h"
|
||||||
#include "os/mathx_priv.h"
|
#include "os/mathx_priv.h"
|
||||||
|
|
@ -165,6 +170,60 @@ check_timers(void)
|
||||||
* pClientsReady is an array to store ready client->index values into.
|
* pClientsReady is an array to store ready client->index values into.
|
||||||
*****************/
|
*****************/
|
||||||
|
|
||||||
|
#ifdef HAVE_MALLOC_TRIM
|
||||||
|
#define IDLE_TRIM_DELAY 5000 /* 5 seconds */
|
||||||
|
#define IDLE_TRIM_INTERVAL 60000 /* 60 seconds */
|
||||||
|
|
||||||
|
static OsTimerPtr IdleTrimTimer = NULL;
|
||||||
|
static Bool initial_idle_armed = FALSE;
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#if defined(MADV_DONTNEED)
|
||||||
|
|
||||||
|
static void
|
||||||
|
OsTrimCleanLibraries(void)
|
||||||
|
{
|
||||||
|
FILE *f = fopen("/proc/self/maps", "r");
|
||||||
|
if (!f)
|
||||||
|
return;
|
||||||
|
char line[1024];
|
||||||
|
while (fgets(line, sizeof(line), f)) {
|
||||||
|
unsigned long start, end, offset;
|
||||||
|
char perms[16], path[512] = "";
|
||||||
|
int n = sscanf(line, "%lx-%lx %15s %lx %*x:%*x %*u %511s", &start, &end, perms, &offset, path);
|
||||||
|
if (n >= 5 && path[0] == '/') {
|
||||||
|
Bool is_clean = (strncmp(perms, "r-xp", 4) == 0) ||
|
||||||
|
(strncmp(perms, "r--p", 4) == 0 && offset == 0);
|
||||||
|
if (is_clean &&
|
||||||
|
(strstr(path, "libLLVM") || strstr(path, "libz3") ||
|
||||||
|
strstr(path, "libstdc++") || strstr(path, "libxml2") ||
|
||||||
|
strstr(path, "dri/"))) {
|
||||||
|
madvise((void *) start, end - start, MADV_DONTNEED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static CARD32
|
||||||
|
IdleTrimCallback(OsTimerPtr timer, CARD32 now, void *arg)
|
||||||
|
{
|
||||||
|
ResetOsBuffers();
|
||||||
|
dixEmptyFontPatternCache();
|
||||||
|
dixTrimResourceTables();
|
||||||
|
dixTrimGlyphHash();
|
||||||
|
mieqTrimQueue();
|
||||||
|
malloc_trim(0);
|
||||||
|
#if defined(__linux__) && defined(MADV_DONTNEED)
|
||||||
|
OsTrimCleanLibraries();
|
||||||
|
#endif
|
||||||
|
return IDLE_TRIM_INTERVAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
WaitForSomething(Bool are_ready)
|
WaitForSomething(Bool are_ready)
|
||||||
{
|
{
|
||||||
|
|
@ -177,7 +236,18 @@ WaitForSomething(Bool are_ready)
|
||||||
if (were_ready && !are_ready) {
|
if (were_ready && !are_ready) {
|
||||||
timer_is_running = FALSE;
|
timer_is_running = FALSE;
|
||||||
SmartScheduleStopTimer();
|
SmartScheduleStopTimer();
|
||||||
|
#ifdef HAVE_MALLOC_TRIM
|
||||||
|
IdleTrimTimer = TimerSet(IdleTrimTimer, 0, IDLE_TRIM_DELAY,
|
||||||
|
IdleTrimCallback, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_MALLOC_TRIM
|
||||||
|
else if (!initial_idle_armed && !are_ready) {
|
||||||
|
initial_idle_armed = TRUE;
|
||||||
|
IdleTrimTimer = TimerSet(IdleTrimTimer, 0, IDLE_TRIM_DELAY,
|
||||||
|
IdleTrimCallback, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
were_ready = FALSE;
|
were_ready = FALSE;
|
||||||
|
|
||||||
|
|
@ -222,6 +292,10 @@ WaitForSomething(Bool are_ready)
|
||||||
|
|
||||||
if (are_ready) {
|
if (are_ready) {
|
||||||
were_ready = TRUE;
|
were_ready = TRUE;
|
||||||
|
#ifdef HAVE_MALLOC_TRIM
|
||||||
|
if (IdleTrimTimer)
|
||||||
|
TimerCancel(IdleTrimTimer);
|
||||||
|
#endif
|
||||||
if (!timer_is_running)
|
if (!timer_is_running)
|
||||||
SmartScheduleStartTimer();
|
SmartScheduleStartTimer();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
@ -458,6 +532,9 @@ ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetOsBuffers(); /* not ideal, but better than nothing */
|
ResetOsBuffers(); /* not ideal, but better than nothing */
|
||||||
|
#ifdef HAVE_MALLOC_TRIM
|
||||||
|
malloc_trim(0);
|
||||||
|
#endif
|
||||||
dixSaveScreens(serverClient, SCREEN_SAVER_ON, ScreenSaverActive);
|
dixSaveScreens(serverClient, SCREEN_SAVER_ON, ScreenSaverActive);
|
||||||
|
|
||||||
if (ScreenSaverInterval > 0) {
|
if (ScreenSaverInterval > 0) {
|
||||||
|
|
@ -477,6 +554,13 @@ FreeScreenSaverTimer(void)
|
||||||
TimerFree(ScreenSaverTimer);
|
TimerFree(ScreenSaverTimer);
|
||||||
ScreenSaverTimer = NULL;
|
ScreenSaverTimer = NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_MALLOC_TRIM
|
||||||
|
if (IdleTrimTimer) {
|
||||||
|
TimerFree(IdleTrimTimer);
|
||||||
|
IdleTrimTimer = NULL;
|
||||||
|
}
|
||||||
|
initial_idle_armed = FALSE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -899,20 +899,28 @@ static int _XSERVTransSocketUNIXCreateListener (
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't blindly unlink a pre-existing socket file: it may belong to a
|
* Try to bind directly without unlinking first. If the socket file does
|
||||||
* server that's still running (see unix_socket_is_live()). Only clean
|
* not exist, bind() will succeed immediately, avoiding races between
|
||||||
* up and rebind if nobody answers there.
|
* concurrent servers.
|
||||||
|
* Only if bind() fails with EADDRINUSE / TRANS_ADDR_IN_USE do we check
|
||||||
|
* whether the socket is actually live; if dead/stale, unlink and retry.
|
||||||
*/
|
*/
|
||||||
if (unix_socket_is_live(sockname.sun_path)) {
|
status = _XSERVTransSocketCreateListener (ciptr,
|
||||||
prmsg (1, "SocketUNIXCreateListener: %s already in use\n",
|
(struct sockaddr *) &sockname, namelen, flags);
|
||||||
sockname.sun_path);
|
if (status < 0) {
|
||||||
(void) umask (oldUmask);
|
if (status == TRANS_ADDR_IN_USE || errno == EADDRINUSE) {
|
||||||
return TRANS_ADDR_IN_USE;
|
if (unix_socket_is_live(sockname.sun_path)) {
|
||||||
|
prmsg (1, "SocketUNIXCreateListener: %s already in use\n",
|
||||||
|
sockname.sun_path);
|
||||||
|
(void) umask (oldUmask);
|
||||||
|
return TRANS_ADDR_IN_USE;
|
||||||
|
}
|
||||||
|
unlink (sockname.sun_path);
|
||||||
|
status = _XSERVTransSocketCreateListener (ciptr,
|
||||||
|
(struct sockaddr *) &sockname, namelen, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unlink (sockname.sun_path);
|
if (status < 0)
|
||||||
|
|
||||||
if ((status = _XSERVTransSocketCreateListener (ciptr,
|
|
||||||
(struct sockaddr *) &sockname, namelen, flags)) < 0)
|
|
||||||
{
|
{
|
||||||
prmsg (1,
|
prmsg (1,
|
||||||
"SocketUNIXCreateListener: ...SocketCreateListener() failed\n");
|
"SocketUNIXCreateListener: ...SocketCreateListener() failed\n");
|
||||||
|
|
|
||||||
31
os/io.c
31
os/io.c
|
|
@ -1110,6 +1110,37 @@ ResetOsBuffers(void)
|
||||||
{
|
{
|
||||||
ConnectionInputPtr oci;
|
ConnectionInputPtr oci;
|
||||||
ConnectionOutputPtr oco;
|
ConnectionOutputPtr oco;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (AvailableInput) {
|
||||||
|
ConnectionInputPtr aci = AvailableInput->input;
|
||||||
|
if (aci) {
|
||||||
|
free(aci->buffer);
|
||||||
|
free(aci);
|
||||||
|
AvailableInput->input = NULL;
|
||||||
|
}
|
||||||
|
AvailableInput = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < currentMaxClients; i++) {
|
||||||
|
ClientPtr client = clients[i];
|
||||||
|
if (client && !client->clientGone && client->osPrivate) {
|
||||||
|
OsCommPtr oc = (OsCommPtr) client->osPrivate;
|
||||||
|
if ((oci = oc->input)) {
|
||||||
|
int gotnow = oci->bufcnt + oci->buffer - (oci->bufptr + oci->lenLastReq);
|
||||||
|
if (gotnow <= 0 && oci->ignoreBytes == 0) {
|
||||||
|
free(oci->buffer);
|
||||||
|
free(oci);
|
||||||
|
oc->input = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((oco = oc->output) && oco->count == 0) {
|
||||||
|
free(oco->buf);
|
||||||
|
free(oco);
|
||||||
|
oc->output = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while ((oci = FreeInputs)) {
|
while ((oci = FreeInputs)) {
|
||||||
FreeInputs = oci->next;
|
FreeInputs = oci->next;
|
||||||
|
|
|
||||||
16
os/osinit.c
16
os/osinit.c
|
|
@ -46,6 +46,10 @@ SOFTWARE.
|
||||||
|
|
||||||
#include <dix-config.h>
|
#include <dix-config.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_MALLOC_H
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
@ -182,6 +186,18 @@ OsInit(void)
|
||||||
}
|
}
|
||||||
#endif /* !WIN32 || __CYGWIN__ */
|
#endif /* !WIN32 || __CYGWIN__ */
|
||||||
busfault_init();
|
busfault_init();
|
||||||
|
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_TRIM) && defined(HAVE_MALLOPT)
|
||||||
|
/* Prevent runaway dynamic mmap/trim thresholds and limit arena fragmentation */
|
||||||
|
#ifdef M_TRIM_THRESHOLD
|
||||||
|
mallopt(M_TRIM_THRESHOLD, 128 * 1024);
|
||||||
|
#endif
|
||||||
|
#ifdef M_MMAP_THRESHOLD
|
||||||
|
mallopt(M_MMAP_THRESHOLD, 128 * 1024);
|
||||||
|
#endif
|
||||||
|
#ifdef M_ARENA_MAX
|
||||||
|
mallopt(M_ARENA_MAX, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
server_poll = ospoll_create();
|
server_poll = ospoll_create();
|
||||||
if (!server_poll)
|
if (!server_poll)
|
||||||
FatalError("failed to allocate poll structure");
|
FatalError("failed to allocate poll structure");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue