X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fzn_malloc.c;h=ff9a25bf5a971972aadb6a9ad8cf60bcc20bd3fe;hb=021443bd5d355b8171dcbe4650c67507b9e1b83b;hp=c2e8d20f967dbba003601d28367294d9562ec1a4;hpb=d6410c9207d16f55afce5b30b2c8c05b5432f757;p=openldap diff --git a/servers/slapd/zn_malloc.c b/servers/slapd/zn_malloc.c index c2e8d20f96..ff9a25bf5a 100644 --- a/servers/slapd/zn_malloc.c +++ b/servers/slapd/zn_malloc.c @@ -2,7 +2,7 @@ /* $OpenLDAP$*/ /* This work is part of OpenLDAP Software . * - * Copyright 2003-2004 The OpenLDAP Foundation. + * Copyright 2003-2005 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,13 +29,14 @@ #include #include #include -#include #include #include "slap.h" #ifdef SLAP_ZONE_ALLOC +#include + static int slap_zone_cmp(const void *v1, const void *v2); void * slap_replenish_zopool(void *ctx); @@ -220,6 +221,7 @@ slap_zn_mem_create( ldap_pvt_thread_rdwr_init(&zh->zh_znlock[i]); } + LDAP_STAILQ_INIT(&zh->zh_latency_history_queue); ldap_pvt_thread_mutex_init(&zh->zh_mutex); ldap_pvt_thread_rdwr_init(&zh->zh_lock); @@ -892,4 +894,79 @@ int slap_zn_wunlock( } } +#define T_SEC_IN_USEC 1000000 + +static int +slap_timediff(struct timeval *tv_begin, struct timeval *tv_end) +{ + uint64_t t_begin, t_end, t_diff; + + t_begin = T_SEC_IN_USEC * tv_begin->tv_sec + tv_begin->tv_usec; + t_end = T_SEC_IN_USEC * tv_end->tv_sec + tv_end->tv_usec; + t_diff = t_end - t_begin; + + if ( t_diff < 0 ) + t_diff = 0; + + return (int)t_diff; +} + +void +slap_set_timing(struct timeval *tv_set) +{ + gettimeofday(tv_set, (struct timezone *)NULL); +} + +int +slap_measure_timing(struct timeval *tv_set, struct timeval *tv_measure) +{ + gettimeofday(tv_measure, (struct timezone *)NULL); + return(slap_timediff(tv_set, tv_measure)); +} + +#define EMA_WEIGHT 0.999000 +#define SLAP_ZN_LATENCY_HISTORY_QLEN 500 +int +slap_zn_latency_history(void* ctx, int ea_latency) +{ +/* TODO: monitor /proc/stat (swap) as well */ + struct zone_heap* zh = ctx; + double t_diff = 0.0; + + zh->zh_ema_latency = (double)ea_latency * (1.0 - EMA_WEIGHT) + + zh->zh_ema_latency * EMA_WEIGHT; + if (!zh->zh_swapping && zh->zh_ema_samples++ % 100 == 99) { + struct zone_latency_history *zlh_entry; + zlh_entry = ch_calloc(1, sizeof(struct zone_latency_history)); + zlh_entry->zlh_latency = zh->zh_ema_latency; + LDAP_STAILQ_INSERT_TAIL( + &zh->zh_latency_history_queue, zlh_entry, zlh_next); + zh->zh_latency_history_qlen++; + while (zh->zh_latency_history_qlen > SLAP_ZN_LATENCY_HISTORY_QLEN) { + struct zone_latency_history *zlh; + zlh = LDAP_STAILQ_FIRST(&zh->zh_latency_history_queue); + LDAP_STAILQ_REMOVE_HEAD( + &zh->zh_latency_history_queue, zlh_next); + zh->zh_latency_history_qlen--; + ch_free(zlh); + } + if (zh->zh_latency_history_qlen == SLAP_ZN_LATENCY_HISTORY_QLEN) { + struct zone_latency_history *zlh_first, *zlh_last; + zlh_first = LDAP_STAILQ_FIRST(&zh->zh_latency_history_queue); + zlh_last = LDAP_STAILQ_LAST(&zh->zh_latency_history_queue, + zone_latency_history, zlh_next); + t_diff = zlh_last->zlh_latency - zlh_first->zlh_latency; + } + if (t_diff >= 2000) { + zh->zh_latency_jump++; + } else { + zh->zh_latency_jump = 0; + } + if (zh->zh_latency_jump > 3) { + zh->zh_latency_jump = 0; + zh->zh_swapping = 1; + } + } + return zh->zh_swapping; +} #endif /* SLAP_ZONE_ALLOC */