diff --git a/doc/libpmemobj/pmemobj_ctl_get.3.md b/doc/libpmemobj/pmemobj_ctl_get.3.md index 00a599883ff..58f533df013 100644 --- a/doc/libpmemobj/pmemobj_ctl_get.3.md +++ b/doc/libpmemobj/pmemobj_ctl_get.3.md @@ -320,6 +320,18 @@ The required class identifier will be stored in the `class_id` field of the This function returns 0 if the allocation class has been successfully created, -1 otherwise. +stats.enabled | rw | - | int | int | - | boolean + +Enables or disables runtime collection of statistics. The statistics are never +altered after enabling. + +Always returns 0. + +stats.heap.allocated_curr | r- | - | int | - | - | - + +Returns the number of bytes currently allocated in the heap. If statistics were +disabled at any time in the lifetime of the heap, this value might be +inaccurate. # CTL EXTERNAL CONFIGURATION # diff --git a/src/benchmarks/pmembench.vcxproj b/src/benchmarks/pmembench.vcxproj index 038a6d9dd45..c1250db8169 100644 --- a/src/benchmarks/pmembench.vcxproj +++ b/src/benchmarks/pmembench.vcxproj @@ -115,6 +115,10 @@ CompileAsC CompileAsC + + CompileAsC + CompileAsC + CompileAsC CompileAsC diff --git a/src/libpmemobj/Makefile b/src/libpmemobj/Makefile index 84c6de8d514..26c4e083425 100644 --- a/src/libpmemobj/Makefile +++ b/src/libpmemobj/Makefile @@ -61,7 +61,8 @@ SOURCE +=\ redo.c\ ringbuf.c\ sync.c\ - tx.c + tx.c\ + stats.c include ../Makefile.inc diff --git a/src/libpmemobj/heap.c b/src/libpmemobj/heap.c index c5d8be25d21..cb289c3e193 100644 --- a/src/libpmemobj/heap.c +++ b/src/libpmemobj/heap.c @@ -1170,7 +1170,8 @@ heap_buckets_init(struct palloc_heap *heap) */ int heap_boot(struct palloc_heap *heap, void *heap_start, uint64_t heap_size, - uint64_t run_id, void *base, struct pmem_ops *p_ops) + uint64_t run_id, void *base, struct pmem_ops *p_ops, + struct stats *stats) { struct heap_rt *h = Malloc(sizeof(*h)); int err; @@ -1207,6 +1208,7 @@ heap_boot(struct palloc_heap *heap, void *heap_start, uint64_t heap_size, heap->rt = h; heap->size = heap_size; heap->base = base; + heap->stats = stats; VALGRIND_DO_CREATE_MEMPOOL(heap->layout, 0, 0); for (unsigned i = 0; i < h->narenas; ++i) diff --git a/src/libpmemobj/heap.h b/src/libpmemobj/heap.h index 8d36feb5f35..5d8557e9fb8 100644 --- a/src/libpmemobj/heap.h +++ b/src/libpmemobj/heap.h @@ -56,7 +56,8 @@ #define BIT_IS_CLR(a, i) (!((a) & (1ULL << (i)))) int heap_boot(struct palloc_heap *heap, void *heap_start, uint64_t heap_size, - uint64_t run_id, void *base, struct pmem_ops *p_ops); + uint64_t run_id, void *base, struct pmem_ops *p_ops, + struct stats *stats); int heap_init(void *heap_start, uint64_t heap_size, struct pmem_ops *p_ops); void heap_cleanup(struct palloc_heap *heap); int heap_check(void *heap_start, uint64_t heap_size); diff --git a/src/libpmemobj/libpmemobj.vcxproj b/src/libpmemobj/libpmemobj.vcxproj index c1cc081bc23..c1fea0d3b61 100644 --- a/src/libpmemobj/libpmemobj.vcxproj +++ b/src/libpmemobj/libpmemobj.vcxproj @@ -48,6 +48,7 @@ + @@ -104,6 +105,7 @@ + diff --git a/src/libpmemobj/libpmemobj.vcxproj.filters b/src/libpmemobj/libpmemobj.vcxproj.filters index 0c52df76ce3..bc953d412a7 100644 --- a/src/libpmemobj/libpmemobj.vcxproj.filters +++ b/src/libpmemobj/libpmemobj.vcxproj.filters @@ -112,6 +112,9 @@ Source Files + + Source Files + Source Files @@ -264,6 +267,9 @@ Header Files + + Header Files + Header Files diff --git a/src/libpmemobj/obj.c b/src/libpmemobj/obj.c index d6dd207ecd3..411b33351e2 100644 --- a/src/libpmemobj/obj.c +++ b/src/libpmemobj/obj.c @@ -173,6 +173,7 @@ obj_ctl_init_and_load(PMEMobjpool *pop) if (pop) { tx_ctl_register(pop); pmalloc_ctl_register(pop); + stats_ctl_register(pop); } char *env_config = os_getenv(OBJ_CONFIG_ENV_VARIABLE); @@ -1097,6 +1098,13 @@ obj_runtime_init(PMEMobjpool *pop, int rdonly, int boot, unsigned nlanes) return -1; } + pop->stats = stats_new(pop); + if (pop->stats == NULL) { + tx_params_delete(pop->tx_params); + errno = ENOMEM; + return -1; + } + VALGRIND_REMOVE_PMEM_MAPPING(&pop->mutex_head, sizeof(pop->mutex_head)); VALGRIND_REMOVE_PMEM_MAPPING(&pop->rwlock_head, @@ -1109,8 +1117,7 @@ obj_runtime_init(PMEMobjpool *pop, int rdonly, int boot, unsigned nlanes) if (boot) { if ((errno = obj_boot(pop)) != 0) - return -1; - + goto err; #ifdef USE_VG_MEMCHECK if (On_valgrind) { @@ -1152,6 +1159,7 @@ obj_runtime_init(PMEMobjpool *pop, int rdonly, int boot, unsigned nlanes) return 0; err: + stats_delete(pop, pop->stats); tx_params_delete(pop->tx_params); return -1; @@ -1789,6 +1797,7 @@ obj_pool_cleanup(PMEMobjpool *pop) { LOG(3, "pop %p", pop); + stats_delete(pop, pop->stats); tx_params_delete(pop->tx_params); ctl_delete(pop->ctl); diff --git a/src/libpmemobj/obj.h b/src/libpmemobj/obj.h index 367877d3cef..461dedd5ffd 100644 --- a/src/libpmemobj/obj.h +++ b/src/libpmemobj/obj.h @@ -47,6 +47,7 @@ #include "ctl.h" #include "ringbuf.h" #include "sync.h" +#include "stats.h" #define PMEMOBJ_LOG_PREFIX "libpmemobj" #define PMEMOBJ_LOG_LEVEL_VAR "PMEMOBJ_LOG_LEVEL" @@ -135,7 +136,9 @@ struct pmemobjpool { */ uint64_t conversion_flags; - char pmem_reserved[512]; /* must be zeroed */ + struct stats_persistent stats_persistent; + + char pmem_reserved[504]; /* must be zeroed */ /* some run-time state, allocated out of memory pool... */ void *addr; /* mapped region */ @@ -148,6 +151,7 @@ struct pmemobjpool { int is_dev_dax; /* true if mapped on device dax */ struct ctl *ctl; + struct stats *stats; struct ringbuf *tx_postcommit_tasks; struct pool_set *set; /* pool set info */ @@ -191,7 +195,7 @@ struct pmemobjpool { /* padding to align size of this structure to page boundary */ /* sizeof(unused2) == 8192 - offsetof(struct pmemobjpool, unused2) */ - char unused2[1012]; + char unused2[996]; }; /* diff --git a/src/libpmemobj/palloc.c b/src/libpmemobj/palloc.c index c9d57b6ded2..69338ed1f02 100644 --- a/src/libpmemobj/palloc.c +++ b/src/libpmemobj/palloc.c @@ -288,8 +288,18 @@ palloc_finalize_heap_action(struct palloc_heap *heap, const struct pobj_action_internal *act, int canceled) { if (act->new_state == MEMBLOCK_ALLOCATED) { + STATS_INC(heap->stats, persistent, heap_curr_allocated, + act->m.m_ops->get_real_size(&act->m)); + palloc_reservation_finalize(heap, act, canceled); } else if (!canceled && act->new_state == MEMBLOCK_FREE) { + if (heap->stats->enabled) { + struct memory_block m = + memblock_from_offset(heap, act->offset); + STATS_SUB(heap->stats, persistent, heap_curr_allocated, + m.m_ops->get_real_size(&m)); + } + heap_memblock_on_free(heap, &act->m); } } @@ -682,9 +692,11 @@ palloc_is_allocated(struct palloc_heap *heap, uint64_t off) */ int palloc_boot(struct palloc_heap *heap, void *heap_start, uint64_t heap_size, - uint64_t run_id, void *base, struct pmem_ops *p_ops) + uint64_t run_id, void *base, struct pmem_ops *p_ops, + struct stats *stats) { - return heap_boot(heap, heap_start, heap_size, run_id, base, p_ops); + return heap_boot(heap, heap_start, heap_size, run_id, base, p_ops, + stats); } /* diff --git a/src/libpmemobj/palloc.h b/src/libpmemobj/palloc.h index 29955d65660..16002b3f60b 100644 --- a/src/libpmemobj/palloc.h +++ b/src/libpmemobj/palloc.h @@ -44,6 +44,7 @@ #include "memops.h" #include "redo.h" #include "valgrind_internal.h" +#include "stats.h" struct palloc_heap { struct pmem_ops p_ops; @@ -51,6 +52,8 @@ struct palloc_heap { struct heap_rt *rt; uint64_t size; + struct stats *stats; + void *base; }; @@ -93,7 +96,8 @@ uint16_t palloc_flags(struct palloc_heap *heap, uint64_t off); int palloc_is_allocated(struct palloc_heap *heap, uint64_t off); int palloc_boot(struct palloc_heap *heap, void *heap_start, uint64_t run_id, - uint64_t heap_size, void *base, struct pmem_ops *p_ops); + uint64_t heap_size, void *base, struct pmem_ops *p_ops, + struct stats *stats); int palloc_buckets_init(struct palloc_heap *heap); int palloc_init(void *heap_start, uint64_t heap_size, struct pmem_ops *p_ops); diff --git a/src/libpmemobj/pmalloc.c b/src/libpmemobj/pmalloc.c index 3fcc9b493c0..6e7f70e2e20 100644 --- a/src/libpmemobj/pmalloc.c +++ b/src/libpmemobj/pmalloc.c @@ -273,7 +273,8 @@ static int pmalloc_boot(PMEMobjpool *pop) { int ret = palloc_boot(&pop->heap, (char *)pop + pop->heap_offset, - pop->heap_size, pop->run_id, pop, &pop->p_ops); + pop->heap_size, pop->run_id, pop, &pop->p_ops, + pop->stats); if (ret) return ret; diff --git a/src/libpmemobj/stats.c b/src/libpmemobj/stats.c new file mode 100644 index 00000000000..d22b4c3cdf9 --- /dev/null +++ b/src/libpmemobj/stats.c @@ -0,0 +1,126 @@ +/* + * Copyright 2017, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * stats.c -- implementation of statistics + */ + +#include "obj.h" +#include "stats.h" + +STATS_CTL_HANDLER(persistent, curr_allocated, heap_curr_allocated); + +static const struct ctl_node CTL_NODE(heap)[] = { + STATS_CTL_LEAF(persistent, curr_allocated), + + CTL_NODE_END +}; + +/* + * CTL_READ_HANDLER(enabled) -- returns whether or not statistics are enabled + */ +static int +CTL_READ_HANDLER(enabled)(PMEMobjpool *pop, + enum ctl_query_source source, void *arg, + struct ctl_indexes *indexes) +{ + int *arg_out = arg; + + *arg_out = pop->stats->enabled; + + return 0; +} + +/* + * CTL_WRITE_HANDLER(enabled) -- enables or disables statistics counting + */ +static int +CTL_WRITE_HANDLER(enabled)(PMEMobjpool *pop, + enum ctl_query_source source, void *arg, + struct ctl_indexes *indexes) +{ + int arg_in = *(int *)arg; + + pop->stats->enabled = arg_in; + + return 0; +} + +static struct ctl_argument CTL_ARG(enabled) = CTL_ARG_BOOLEAN; + +static const struct ctl_node CTL_NODE(stats)[] = { + CTL_CHILD(heap), + CTL_LEAF_RW(enabled), + + CTL_NODE_END +}; + +/* + * stats_new -- allocates and initializes statistics instance + */ +struct stats * +stats_new(PMEMobjpool *pop) +{ + struct stats *s = Malloc(sizeof(*s)); + s->enabled = 0; + s->persistent = &pop->stats_persistent; + s->transient = Zalloc(sizeof(struct stats_transient)); + if (s->transient == NULL) + goto error_transient_alloc; + + return s; + +error_transient_alloc: + Free(s); + return NULL; +} + +/* + * stats_delete -- deletes statistics instance + */ +void +stats_delete(PMEMobjpool *pop, struct stats *s) +{ + pmemops_persist(&pop->p_ops, s->persistent, + sizeof(struct stats_persistent)); + Free(s->transient); + Free(s); +} + +/* + * stats_ctl_register -- registers ctl nodes for statistics + */ +void +stats_ctl_register(PMEMobjpool *pop) +{ + CTL_REGISTER_MODULE(pop->ctl, stats); +} diff --git a/src/libpmemobj/stats.h b/src/libpmemobj/stats.h new file mode 100644 index 00000000000..b6c143235f9 --- /dev/null +++ b/src/libpmemobj/stats.h @@ -0,0 +1,92 @@ +/* + * Copyright 2017, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * stats.h -- definitions of statistics + */ + +#ifndef LIBPMEMOBJ_STATS_H +#define LIBPMEMOBJ_STATS_H 1 + +#include "ctl.h" + +struct stats_transient { + int unused; +}; + +struct stats_persistent { + uint64_t heap_curr_allocated; +}; + +struct stats { + int enabled; + struct stats_transient *transient; + struct stats_persistent *persistent; +}; + +#define STATS_INC(stats, type, name, value) do {\ + if (stats->enabled)\ + util_fetch_and_add64((&stats->type->name), (value));\ +} while (0) + +#define STATS_SUB(stats, type, name, value) do {\ + if (stats->enabled)\ + util_fetch_and_sub64((&stats->type->name), (value));\ +} while (0) + +#define STATS_SET(stats, type, name, value) do {\ + if (stats->enabled)\ + util_atomic_store_explicit64((&stats->type->name), (value),\ + memory_order_release);\ +} while (0) + +#define STATS_CTL_LEAF(type, name)\ +{CTL_STR(name), CTL_NODE_LEAF,\ +{CTL_READ_HANDLER(type##_##name), NULL, NULL},\ +NULL, NULL} + +#define STATS_CTL_HANDLER(type, name, varname)\ +static int CTL_READ_HANDLER(type##_##name)(PMEMobjpool *pop,\ + enum ctl_query_source source, void *arg, struct ctl_indexes *indexes)\ +{\ + uint64_t *argv = arg;\ + util_atomic_load_explicit64(&pop->stats->type->varname,\ + argv, memory_order_acquire);\ + return 0;\ +} + +void stats_ctl_register(PMEMobjpool *pop); + +struct stats *stats_new(PMEMobjpool *pop); +void stats_delete(PMEMobjpool *pop, struct stats *stats); + +#endif diff --git a/src/test/Makefile.inc b/src/test/Makefile.inc index 1a309db6ff5..a8a46ffcad5 100644 --- a/src/test/Makefile.inc +++ b/src/test/Makefile.inc @@ -126,7 +126,8 @@ OBJS += $(TOP)/src/debug/libpmemobj/alloc_class.o\ $(TOP)/src/debug/libpmemobj/redo.o\ $(TOP)/src/debug/libpmemobj/ringbuf.o\ $(TOP)/src/debug/libpmemobj/sync.o\ - $(TOP)/src/debug/libpmemobj/tx.o + $(TOP)/src/debug/libpmemobj/tx.o\ + $(TOP)/src/debug/libpmemobj/stats.o LIBS += $(LIBDL) INCS += -I$(TOP)/src/libpmemobj @@ -157,7 +158,8 @@ OBJS += $(TOP)/src/nondebug/libpmemobj/alloc_class.o\ $(TOP)/src/nondebug/libpmemobj/redo.o\ $(TOP)/src/nondebug/libpmemobj/ringbuf.o\ $(TOP)/src/nondebug/libpmemobj/sync.o\ - $(TOP)/src/nondebug/libpmemobj/tx.o + $(TOP)/src/nondebug/libpmemobj/tx.o\ + $(TOP)/src/nondebug/libpmemobj/stats.o INCS += -I$(TOP)/src/libpmemobj LIBPMEM=y diff --git a/src/test/obj_bucket/obj_bucket.vcxproj b/src/test/obj_bucket/obj_bucket.vcxproj index e66930f9f60..4023df184fb 100644 --- a/src/test/obj_bucket/obj_bucket.vcxproj +++ b/src/test/obj_bucket/obj_bucket.vcxproj @@ -48,6 +48,7 @@ + NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL @@ -106,4 +107,4 @@ - \ No newline at end of file + diff --git a/src/test/obj_ctl_prefault/obj_ctl_prefault.c b/src/test/obj_ctl_prefault/obj_ctl_prefault.c index 650d965c17a..1498c07941c 100644 --- a/src/test/obj_ctl_prefault/obj_ctl_prefault.c +++ b/src/test/obj_ctl_prefault/obj_ctl_prefault.c @@ -99,7 +99,7 @@ main(int argc, char *argv[]) if ((pop = pmemobj_open(path, LAYOUT)) == NULL) UT_FATAL("!pmemobj_open: %s", path); } else { - if ((pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL, + if ((pop = pmemobj_create(path, LAYOUT, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); } diff --git a/src/test/obj_ctl_stats/.gitignore b/src/test/obj_ctl_stats/.gitignore new file mode 100644 index 00000000000..9ff0d30364c --- /dev/null +++ b/src/test/obj_ctl_stats/.gitignore @@ -0,0 +1 @@ +obj_ctl_stats diff --git a/src/test/obj_ctl_stats/Makefile b/src/test/obj_ctl_stats/Makefile new file mode 100644 index 00000000000..93fae506c24 --- /dev/null +++ b/src/test/obj_ctl_stats/Makefile @@ -0,0 +1,42 @@ +# +# Copyright 2017, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# +# src/test/obj_ctl_stats/Makefile -- build obj_ctl_stats test +# +TARGET = obj_ctl_stats +OBJS = obj_ctl_stats.o + +LIBPMEM=y +LIBPMEMOBJ=y + +include ../Makefile.inc diff --git a/src/test/obj_ctl_stats/TEST0 b/src/test/obj_ctl_stats/TEST0 new file mode 100755 index 00000000000..aafbf71fccf --- /dev/null +++ b/src/test/obj_ctl_stats/TEST0 @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Copyright 2017, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +export UNITTEST_NAME=obj_ctl_stats/TEST0 +export UNITTEST_NUM=0 + +# standard unit test setup +. ../unittest/unittest.sh + +require_test_type short +require_fs_type any + +setup + +expect_normal_exit ./obj_ctl_stats$EXESUFFIX $DIR/testfile1 + +pass diff --git a/src/test/obj_ctl_stats/obj_ctl_stats.c b/src/test/obj_ctl_stats/obj_ctl_stats.c new file mode 100644 index 00000000000..25082558796 --- /dev/null +++ b/src/test/obj_ctl_stats/obj_ctl_stats.c @@ -0,0 +1,88 @@ +/* + * Copyright 2017, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_ctl_stats.c -- tests for the libpmemobj statistics module + */ + +#include "unittest.h" + +int +main(int argc, char *argv[]) +{ + START(argc, argv, "obj_ctl_stats"); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + PMEMobjpool *pop; + if ((pop = pmemobj_create(path, "ctl", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR)) == NULL) + UT_FATAL("!pmemobj_create: %s", path); + + int enabled; + int ret = pmemobj_ctl_get(pop, "stats.enabled", &enabled); + UT_ASSERTeq(enabled, 0); + UT_ASSERTeq(ret, 0); + + ret = pmemobj_alloc(pop, NULL, 1, 0, NULL, NULL); + UT_ASSERTeq(ret, 0); + + size_t allocated; + ret = pmemobj_ctl_get(pop, "stats.heap.curr_allocated", &allocated); + UT_ASSERTeq(allocated, 0); + + enabled = 1; + ret = pmemobj_ctl_set(pop, "stats.enabled", &enabled); + UT_ASSERTeq(ret, 0); + + PMEMoid oid; + ret = pmemobj_alloc(pop, &oid, 1, 0, NULL, NULL); + UT_ASSERTeq(ret, 0); + size_t oid_size = pmemobj_alloc_usable_size(oid) + 16; + + ret = pmemobj_ctl_get(pop, "stats.heap.curr_allocated", &allocated); + UT_ASSERTeq(ret, 0); + UT_ASSERTeq(allocated, oid_size); + + pmemobj_free(&oid); + + ret = pmemobj_ctl_get(pop, "stats.heap.curr_allocated", &allocated); + UT_ASSERTeq(ret, 0); + UT_ASSERTeq(allocated, 0); + + pmemobj_close(pop); + + DONE(NULL); +} diff --git a/src/test/obj_heap/obj_heap.c b/src/test/obj_heap/obj_heap.c index 3deb60fcc7b..e005eb718bc 100644 --- a/src/test/obj_heap/obj_heap.c +++ b/src/test/obj_heap/obj_heap.c @@ -215,6 +215,9 @@ test_heap(void) pop->p_ops.base = pop; pop->p_ops.pool_size = pop->size; + struct stats *s = stats_new(pop); + UT_ASSERTne(s, NULL); + void *heap_start = (char *)pop + pop->heap_offset; uint64_t heap_size = pop->heap_size; struct palloc_heap *heap = &pop->heap; @@ -223,7 +226,7 @@ test_heap(void) UT_ASSERT(heap_check(heap_start, heap_size) != 0); UT_ASSERT(heap_init(heap_start, heap_size, p_ops) == 0); UT_ASSERT(heap_boot(heap, heap_start, heap_size, TEST_RUN_ID, - pop, p_ops) == 0); + pop, p_ops, s) == 0); UT_ASSERT(heap_buckets_init(heap) == 0); UT_ASSERT(pop->heap.rt != NULL); @@ -282,6 +285,7 @@ test_heap(void) heap_bucket_release(heap, b_run); + stats_delete(pop, s); UT_ASSERT(heap_check(heap_start, heap_size) == 0); heap_cleanup(heap); UT_ASSERT(heap->rt == NULL); @@ -309,10 +313,13 @@ test_recycler(void) struct palloc_heap *heap = &pop->heap; struct pmem_ops *p_ops = &pop->p_ops; + struct stats *s = stats_new(pop); + UT_ASSERTne(s, NULL); + UT_ASSERT(heap_check(heap_start, heap_size) != 0); UT_ASSERT(heap_init(heap_start, heap_size, p_ops) == 0); UT_ASSERT(heap_boot(heap, heap_start, heap_size, TEST_RUN_ID, - pop, p_ops) == 0); + pop, p_ops, s) == 0); UT_ASSERT(heap_buckets_init(heap) == 0); UT_ASSERT(pop->heap.rt != NULL); @@ -424,6 +431,7 @@ test_recycler(void) recycler_delete(r); + stats_delete(pop, s); heap_cleanup(heap); UT_ASSERT(heap->rt == NULL); diff --git a/src/test/obj_heap/obj_heap.vcxproj b/src/test/obj_heap/obj_heap.vcxproj index 261709c3eb1..dcf18ecce41 100644 --- a/src/test/obj_heap/obj_heap.vcxproj +++ b/src/test/obj_heap/obj_heap.vcxproj @@ -22,6 +22,8 @@ + + diff --git a/src/test/obj_heap_interrupt/obj_heap_interrupt.vcxproj b/src/test/obj_heap_interrupt/obj_heap_interrupt.vcxproj index f3d9b053e2c..2e77ff1b971 100644 --- a/src/test/obj_heap_interrupt/obj_heap_interrupt.vcxproj +++ b/src/test/obj_heap_interrupt/obj_heap_interrupt.vcxproj @@ -37,6 +37,7 @@ + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL @@ -111,4 +112,4 @@ - \ No newline at end of file + diff --git a/src/test/obj_list/obj_list.vcxproj b/src/test/obj_list/obj_list.vcxproj index a52adf64272..697b241d2cf 100644 --- a/src/test/obj_list/obj_list.vcxproj +++ b/src/test/obj_list/obj_list.vcxproj @@ -63,6 +63,7 @@ + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) NDEBUG;_CONSOLE;%(PreprocessorDefinitions) @@ -139,4 +140,4 @@ - \ No newline at end of file + diff --git a/src/test/obj_memblock/obj_memblock.vcxproj b/src/test/obj_memblock/obj_memblock.vcxproj index 9ddd9f1a962..769e4972fc0 100644 --- a/src/test/obj_memblock/obj_memblock.vcxproj +++ b/src/test/obj_memblock/obj_memblock.vcxproj @@ -46,6 +46,7 @@ + @@ -108,4 +109,4 @@ - \ No newline at end of file + diff --git a/src/test/obj_persist_count/obj_persist_count.vcxproj b/src/test/obj_persist_count/obj_persist_count.vcxproj index 874870794ee..bbfa4878466 100644 --- a/src/test/obj_persist_count/obj_persist_count.vcxproj +++ b/src/test/obj_persist_count/obj_persist_count.vcxproj @@ -56,6 +56,7 @@ + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL diff --git a/src/test/obj_pmalloc_basic/obj_pmalloc_basic.c b/src/test/obj_pmalloc_basic/obj_pmalloc_basic.c index c6f85cce088..9cadbc0398f 100644 --- a/src/test/obj_pmalloc_basic/obj_pmalloc_basic.c +++ b/src/test/obj_pmalloc_basic/obj_pmalloc_basic.c @@ -314,9 +314,12 @@ test_mock_pool_allocs(void) void *heap_start = (char *)mock_pop + mock_pop->heap_offset; uint64_t heap_size = mock_pop->heap_size; + struct stats *s = stats_new(mock_pop); + UT_ASSERTne(s, NULL); + heap_init(heap_start, heap_size, &mock_pop->p_ops); heap_boot(&mock_pop->heap, heap_start, heap_size, MOCK_RUN_ID, mock_pop, - &mock_pop->p_ops); + &mock_pop->p_ops, s); heap_buckets_init(&mock_pop->heap); /* initialize runtime lanes structure */ @@ -364,6 +367,7 @@ test_mock_pool_allocs(void) test_realloc(TEST_SMALL_ALLOC_SIZE, TEST_MEDIUM_ALLOC_SIZE); test_realloc(TEST_HUGE_ALLOC_SIZE, TEST_MEGA_ALLOC_SIZE); + stats_delete(mock_pop, s); lane_cleanup(mock_pop); redo_log_config_delete(mock_pop->redo); heap_cleanup(&mock_pop->heap); diff --git a/src/test/obj_pmalloc_basic/obj_pmalloc_basic.vcxproj b/src/test/obj_pmalloc_basic/obj_pmalloc_basic.vcxproj index 0c32e17d4fe..98a0bd7f113 100644 --- a/src/test/obj_pmalloc_basic/obj_pmalloc_basic.vcxproj +++ b/src/test/obj_pmalloc_basic/obj_pmalloc_basic.vcxproj @@ -45,6 +45,7 @@ + @@ -100,4 +101,4 @@ - \ No newline at end of file + diff --git a/src/test/obj_pmalloc_mt/obj_pmalloc_mt.vcxproj b/src/test/obj_pmalloc_mt/obj_pmalloc_mt.vcxproj index 23d95f7c6db..b27bfbc5245 100644 --- a/src/test/obj_pmalloc_mt/obj_pmalloc_mt.vcxproj +++ b/src/test/obj_pmalloc_mt/obj_pmalloc_mt.vcxproj @@ -45,6 +45,7 @@ + @@ -100,4 +101,4 @@ - \ No newline at end of file + diff --git a/src/test/obj_pvector/obj_pvector.vcxproj b/src/test/obj_pvector/obj_pvector.vcxproj index abf5dafa1c4..993fe4ae19e 100644 --- a/src/test/obj_pvector/obj_pvector.vcxproj +++ b/src/test/obj_pvector/obj_pvector.vcxproj @@ -84,6 +84,7 @@ + @@ -106,4 +107,4 @@ - \ No newline at end of file + diff --git a/src/test/obj_realloc/obj_realloc.vcxproj b/src/test/obj_realloc/obj_realloc.vcxproj index 55950f671cc..6c47c31e92c 100644 --- a/src/test/obj_realloc/obj_realloc.vcxproj +++ b/src/test/obj_realloc/obj_realloc.vcxproj @@ -149,6 +149,10 @@ CompileAsC CompileAsC + + CompileAsC + CompileAsC + CompileAsC CompileAsC diff --git a/src/test/obj_ringbuf/obj_ringbuf.vcxproj b/src/test/obj_ringbuf/obj_ringbuf.vcxproj index 550790b17d6..42b1b8c5510 100644 --- a/src/test/obj_ringbuf/obj_ringbuf.vcxproj +++ b/src/test/obj_ringbuf/obj_ringbuf.vcxproj @@ -84,6 +84,7 @@ + @@ -106,4 +107,4 @@ - \ No newline at end of file + diff --git a/src/test/obj_ringbuf/obj_ringbuf.vcxproj.filters b/src/test/obj_ringbuf/obj_ringbuf.vcxproj.filters index b2226432fcd..8b14a7be872 100644 --- a/src/test/obj_ringbuf/obj_ringbuf.vcxproj.filters +++ b/src/test/obj_ringbuf/obj_ringbuf.vcxproj.filters @@ -7,6 +7,9 @@ Source Files + + Source Files + Source Files @@ -90,4 +93,4 @@ Test Scripts - \ No newline at end of file + diff --git a/src/tools/pmempool/pmempool.vcxproj b/src/tools/pmempool/pmempool.vcxproj index 0c4a722323c..535e7f114eb 100644 --- a/src/tools/pmempool/pmempool.vcxproj +++ b/src/tools/pmempool/pmempool.vcxproj @@ -15,6 +15,7 @@ + diff --git a/src/tools/pmempool/pmempool.vcxproj.filters b/src/tools/pmempool/pmempool.vcxproj.filters index b0af7648604..4459573843d 100644 --- a/src/tools/pmempool/pmempool.vcxproj.filters +++ b/src/tools/pmempool/pmempool.vcxproj.filters @@ -65,6 +65,9 @@ libs + + libs + libs