X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fzn_malloc.c;h=7f8694763fb94b9130787712341ad46ba5cd9aa5;hb=703531fe5c39e839b74dfbb6760dd8f39dac56b3;hp=c2e8d20f967dbba003601d28367294d9562ec1a4;hpb=d6410c9207d16f55afce5b30b2c8c05b5432f757;p=openldap diff --git a/servers/slapd/zn_malloc.c b/servers/slapd/zn_malloc.c index c2e8d20f96..7f8694763f 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-2012 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,15 +13,15 @@ * top-level directory of the distribution or, alternatively, at * . */ -/* Copyright 2004 IBM Corporation +/* Portions Copyright 2004 IBM Corporation * All rights reserved. - * Redisribution and use in source and binary forms, with or without - * modification, are permitted only as authorizd by the OpenLADP + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP * Public License. */ /* ACKNOWLEDGEMENTS - * This work originally developed by Jong-Hyuk Choi - * 2004/12/09 jongchoi@OpenLDAP.org + * This work originally developed by Jong-Hyuk Choi for inclusion in + * OpenLDAP Software. */ #include "portable.h" @@ -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); @@ -327,7 +329,7 @@ retry: if ( zh->zh_maxzones < zh->zh_numzones + zh->zh_deltazones ) { ldap_pvt_thread_mutex_unlock( &zh->zh_mutex ); Debug( LDAP_DEBUG_TRACE, - "slap_zn_malloc of %lu bytes failed, using ch_malloc\n", + "zn_malloc %lu: ch_malloc\n", (long)size, 0, 0); Debug(LDAP_DEBUG_NONE, "slap_zn_malloc: returning 0x%x, 0x%x\n", @@ -540,7 +542,7 @@ slap_zn_free(void *ptr, void *ctx) Debug(LDAP_DEBUG_ANY, "slap_zn_free: " "free object not found while bit is clear.\n", 0, 0, 0); - assert(zo); + assert(zo != NULL); } } else { @@ -602,7 +604,7 @@ slap_zn_free(void *ptr, void *ctx) Debug(LDAP_DEBUG_ANY, "slap_zn_free: " "free object not found while bit is clear.\n", 0, 0, 0 ); - assert( zo ); + assert(zo != NULL); } } else { @@ -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 */