From: Jong Hyuk Choi Date: Tue, 14 Dec 2004 17:25:35 +0000 (+0000) Subject: adaptive caching code X-Git-Tag: OPENLDAP_REL_ENG_2_3_0ALPHA~44 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5162c4477b9b53872a236dafbd761bf347afd0ec;p=openldap adaptive caching code --- diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 5d238d0328..13fee4fc28 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -596,7 +596,11 @@ int entry_encode(Entry *e, struct berval *bv) * you can not free individual attributes or names from this * structure. Attempting to do so will likely corrupt memory. */ +#ifdef SLAP_ZONE_ALLOC +int entry_decode(struct berval *bv, Entry **e, void *ctx) +#else int entry_decode(struct berval *bv, Entry **e) +#endif { int i, j, count; int rc; @@ -613,7 +617,15 @@ int entry_decode(struct berval *bv, Entry **e) "entry_decode: entry length was zero\n", 0, 0, 0); return LDAP_OTHER; } +#ifdef SLAP_ZONE_ALLOC + x = slap_zn_calloc(1, i + bv->bv_len, ctx); + AC_MEMCPY((char*)x + i, bv->bv_val, bv->bv_len); + bv->bv_val = (char*)x + i; + ptr = (unsigned char *)bv->bv_val; + i = entry_getlen(&ptr); +#else x = ch_calloc(1, i); +#endif i = entry_getlen(&ptr); x->e_name.bv_val = (char *) ptr; x->e_name.bv_len = i; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 1aeab3f09c..9237cc7629 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -620,7 +620,13 @@ LDAP_SLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len )); LDAP_SLAPD_F (void) entry_flatsize LDAP_P(( Entry *e, ber_len_t *siz, ber_len_t *len, int norm )); -LDAP_SLAPD_F (int) entry_decode LDAP_P(( struct berval *bv, Entry **e )); +#ifdef SLAP_ZONE_ALLOC +LDAP_SLAPD_F (int) entry_decode LDAP_P(( + struct berval *bv, Entry **e, void *ctx )); +#else +LDAP_SLAPD_F (int) entry_decode LDAP_P(( + struct berval *bv, Entry **e )); +#endif LDAP_SLAPD_F (int) entry_encode LDAP_P(( Entry *e, struct berval *bv )); LDAP_SLAPD_F (void) entry_clean LDAP_P(( Entry *e )); @@ -1342,6 +1348,30 @@ LDAP_SLAPD_F (int) value_add_one LDAP_P(( /* assumes (x) > (y) returns 1 if true, 0 otherwise */ #define SLAP_PTRCMP(x, y) ((x) < (y) ? -1 : (x) > (y)) +#ifdef SLAP_ZONE_ALLOC +/* + * zn_malloc.c + */ +LDAP_SLAPD_F (void *) slap_zn_malloc LDAP_P((ber_len_t, void *)); +LDAP_SLAPD_F (void *) slap_zn_realloc LDAP_P((void *, ber_len_t, void *)); +LDAP_SLAPD_F (void *) slap_zn_calloc LDAP_P((ber_len_t, ber_len_t, void *)); +LDAP_SLAPD_F (void) slap_zn_free LDAP_P((void *, void *)); + +LDAP_SLAPD_F (void *) slap_zn_mem_create LDAP_P(( + ber_len_t, ber_len_t, ber_len_t, ber_len_t)); +LDAP_SLAPD_F (void) slap_zn_mem_destroy LDAP_P((void *)); +LDAP_SLAPD_F (int) slap_zn_validate LDAP_P((void *, void *, int)); +LDAP_SLAPD_F (int) slap_zn_invalidate LDAP_P((void *, void *)); +LDAP_SLAPD_F (int) slap_zh_rlock LDAP_P((void*)); +LDAP_SLAPD_F (int) slap_zh_runlock LDAP_P((void*)); +LDAP_SLAPD_F (int) slap_zh_wlock LDAP_P((void*)); +LDAP_SLAPD_F (int) slap_zh_wunlock LDAP_P((void*)); +LDAP_SLAPD_F (int) slap_zn_rlock LDAP_P((void*, void*)); +LDAP_SLAPD_F (int) slap_zn_runlock LDAP_P((void*, void*)); +LDAP_SLAPD_F (int) slap_zn_wlock LDAP_P((void*, void*)); +LDAP_SLAPD_F (int) slap_zn_wunlock LDAP_P((void*, void*)); +#endif + /* * Other... */ diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 785f72cf59..3dd62fcfdd 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -2860,6 +2860,7 @@ struct slab_heap { #define SLAP_ZONE_SIZE 0x80000 /* 512KB */ #define SLAP_ZONE_SHIFT 19 #define SLAP_ZONE_INITSIZE 0x800000 /* 8MB */ +#define SLAP_ZONE_MAXSIZE 0x80000000/* 2GB */ #define SLAP_ZONE_DELTA 0x800000 /* 8MB */ #define SLAP_ZONE_ZOBLOCK 256 @@ -2871,6 +2872,11 @@ struct zone_object { LDAP_LIST_ENTRY(zone_object) zo_link; }; +struct zone_latency_history { + double zlh_latency; + LDAP_STAILQ_ENTRY(zone_latency_history) zlh_next; +}; + struct zone_heap { int zh_fd; int zh_zonesize; @@ -2887,6 +2893,13 @@ struct zone_heap { LDAP_LIST_HEAD( zh_so, zone_object ) zh_zopool; ldap_pvt_thread_mutex_t zh_mutex; ldap_pvt_thread_rdwr_t zh_lock; + double zh_ema_latency; + unsigned long zh_ema_samples; + LDAP_STAILQ_HEAD( zh_latency_history, zone_latency_history ) + zh_latency_history_queue; + int zh_latency_history_qlen; + int zh_latency_jump; + int zh_swapping; }; #endif diff --git a/servers/slapd/zn_malloc.c b/servers/slapd/zn_malloc.c index c2e8d20f96..328616d19b 100644 --- a/servers/slapd/zn_malloc.c +++ b/servers/slapd/zn_malloc.c @@ -220,6 +220,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 +893,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/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 */