Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

common: core_log_set/get_threshold MT unit tests #6035

Merged
merged 1 commit into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 7 additions & 20 deletions src/core/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ _Atomic
void *Core_log_function_context;

/* threshold levels */
#ifdef ATOMIC_OPERATIONS_SUPPORTED
_Atomic
#endif /* ATOMIC_OPERATIONS_SUPPORTED */
enum core_log_level Core_log_threshold[] = {
CORE_LOG_THRESHOLD_DEFAULT,
CORE_LOG_THRESHOLD_AUX_DEFAULT
Expand Down Expand Up @@ -114,6 +111,7 @@ core_log_lib_info(void)
CORE_LOG_HARK("compiled with libndctl 63+");
#endif
}

/*
* core_log_set_function -- set the log function pointer either to
* a user-provided function pointer or to the default logging function.
Expand Down Expand Up @@ -164,21 +162,15 @@ core_log_set_threshold(enum core_log_threshold threshold,
if (level < CORE_LOG_LEVEL_HARK || level > CORE_LOG_LEVEL_DEBUG)
return EINVAL;

#ifdef ATOMIC_OPERATIONS_SUPPORTED
atomic_store_explicit(&Log_threshold[threshold], level,
__ATOMIC_SEQ_CST);
return 0;
#else
enum core_log_level level_old;
while (EAGAIN == core_log_get_threshold(threshold, &level_old))
;
(void) core_log_get_threshold(threshold, &level_old);

if (__sync_bool_compare_and_swap(&Core_log_threshold[threshold],
level_old, level))
return 0;
else
if (!__sync_bool_compare_and_swap(&Core_log_threshold[threshold],
level_old, level)) {
return EAGAIN;
#endif /* ATOMIC_OPERATIONS_SUPPORTED */
}

return 0;
}

/*
Expand All @@ -195,12 +187,7 @@ core_log_get_threshold(enum core_log_threshold threshold,
if (level == NULL)
return EINVAL;

#ifdef ATOMIC_OPERATIONS_SUPPORTED
*level = atomic_load_explicit(&Log_threshold[threshold],
__ATOMIC_SEQ_CST);
#else
*level = Core_log_threshold[threshold];
#endif /* ATOMIC_OPERATIONS_SUPPORTED */

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions src/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ OTHER_TESTS = \
arch_flags\
core_log_internal\
core_log_max\
core_log_mt\
checksum\
compat_incompat_features\
ctl_prefault\
Expand Down
1 change: 1 addition & 0 deletions src/test/core_log_mt/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
core_log_mt
12 changes: 12 additions & 0 deletions src/test/core_log_mt/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2024, Intel Corporation

TARGET = core_log_mt
OBJS = core_log_mt.o

BUILD_STATIC_DEBUG=n
BUILD_STATIC_NONDEBUG=n

LIBPMEMCORE=nondebug

include ../Makefile.inc
45 changes: 45 additions & 0 deletions src/test/core_log_mt/TESTS.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!../env.py
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2024, Intel Corporation
#


import testframework as t
from testframework import granularity as g


@g.require_granularity(g.ANY)
@t.require_build('nondebug')
class CORE_LOG_MT(t.BaseTest):
test_type = t.Short

def run(self, ctx):
ctx.exec('core_log_mt', self.test_case)


class THRESHOLD(CORE_LOG_MT):
test_case = 'test_threshold'


class THRESHOLD_AUX(CORE_LOG_MT):
test_case = 'test_threshold_aux'


@t.require_valgrind_enabled('helgrind')
class TEST0(THRESHOLD):
pass


@t.require_valgrind_enabled('drd')
class TEST1(THRESHOLD):
pass


@t.require_valgrind_enabled('helgrind')
class TEST2(THRESHOLD_AUX):
pass


@t.require_valgrind_enabled('drd')
class TEST3(THRESHOLD_AUX):
pass
105 changes: 105 additions & 0 deletions src/test/core_log_mt/core_log_mt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2024, Intel Corporation */

/*
* core_log_internal.c -- unit test to CORE_LOG_...
*/

#include "unittest.h"
#include "log_internal.h"

#define NO_ARGS_CONSUMED 0

#define THREADS_IN_GROUP 10
#define TOTAL_THREADS (THREADS_IN_GROUP * 2)
#define OP_REDO 4096

struct test_threshold_helper_ctx {
enum core_log_threshold threshold;
enum core_log_level level;
} threshold_helper_ [TOTAL_THREADS];

static void *
test_threshold_helper_set(void *arg)
{
struct test_threshold_helper_ctx *ctx =
(struct test_threshold_helper_ctx *)arg;
for (int i = 0; i < OP_REDO; ++i) {
core_log_set_threshold(ctx->threshold, ctx->level);
}
return NULL;
}

static void *
test_threshold_helper_get(void *arg)
{
struct test_threshold_helper_ctx *ctx =
(struct test_threshold_helper_ctx *)arg;
for (int i = 0; i < OP_REDO; ++i) {
core_log_get_threshold(ctx->threshold, &ctx->level);
}
(void) ctx->level;
return NULL;
}

static void
test_threshold_helper(enum core_log_threshold threshold)
{
os_thread_t threads[TOTAL_THREADS];

/* core_log_set_threshold() threads */
for (int idx = 0; idx < THREADS_IN_GROUP; idx++) {
threshold_helper_[idx].threshold = threshold;
threshold_helper_[idx].level =
(enum core_log_level)(idx % CORE_LOG_LEVEL_MAX);
THREAD_CREATE(&threads[idx], 0, test_threshold_helper_set,
(void *)&threshold_helper_[idx]);
}

/* core_log_get_threshold() threads */
for (int idx = THREADS_IN_GROUP; idx < TOTAL_THREADS; idx++) {
threshold_helper_[idx].threshold = threshold;
THREAD_CREATE(&threads[idx], 0, test_threshold_helper_get,
(void *)&threshold_helper_[idx]);
}

for (int idx = 0; idx < TOTAL_THREADS; idx++) {
void *retval;
THREAD_JOIN(&threads[idx], &retval);
}
}

/* Run core_log_set/get_threshold(CORE_LOG_THRESHOLD, ...) in parallel. */
static int
test_threshold(const struct test_case *tc, int argc, char *argv[])
{
test_threshold_helper(CORE_LOG_THRESHOLD);
return NO_ARGS_CONSUMED;
}

/* Run core_log_set/get_threshold(CORE_LOG_THRESHOLD_AUX, ...) in parallel. */
static int
test_threshold_aux(const struct test_case *tc, int argc, char *argv[])
{
test_threshold_helper(CORE_LOG_THRESHOLD_AUX);
return NO_ARGS_CONSUMED;
}

/*
* A Valgrind tool external to the test binary is assumed to monitor
* the execution and assess synchronisation correctness.
*/
static struct test_case test_cases[] = {
TEST_CASE(test_threshold),
TEST_CASE(test_threshold_aux),
};

#define NTESTS ARRAY_SIZE(test_cases)

int
main(int argc, char *argv[])
{
START(argc, argv, "core_log_mt");
TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS);
DONE(NULL);
}
Loading