Skip to content

Commit

Permalink
Added proper platform fallback, a sanity test, and some documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanHenson committed Oct 11, 2023
1 parent bc220a4 commit 70d38a6
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 18 deletions.
9 changes: 7 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,26 @@ else ()
# Don't add the exact path to CoreFoundation as this would hardcode the SDK version
list(APPEND PLATFORM_LIBS dl Threads::Threads "-framework CoreFoundation")
list (APPEND AWS_COMMON_OS_SRC "source/darwin/*.c") # OS specific includes
list (APPEND AWS_COMMON_OS_SRC "source/linux/*.c") # just for the moment

list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c")
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") # Android does not link to libpthread nor librt, so this is fine
list(APPEND PLATFORM_LIBS dl m Threads::Threads rt)
list (APPEND AWS_COMMON_OS_SRC "source/linux/*.c") # OS specific includes
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
list(APPEND PLATFORM_LIBS dl m thr execinfo)
list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c")
elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
list(APPEND PLATFORM_LIBS dl m Threads::Threads execinfo)
list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c")
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
list(APPEND PLATFORM_LIBS m Threads::Threads execinfo)
list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
list(APPEND PLATFORM_LIBS log)
file(GLOB ANDROID_SRC "source/android/*.c")
list(APPEND AWS_COMMON_OS_SRC "${ANDROID_SRC}")
list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c")
else()
list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c")
endif()

endif()
Expand Down
7 changes: 0 additions & 7 deletions bin/system_info/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,3 @@ target_include_directories(${SI_PROJECT_NAME} PUBLIC
$<INSTALL_INTERFACE:include>)

target_link_libraries(${SI_PROJECT_NAME} PRIVATE aws-c-common)

install(TARGETS ${SI_PROJECT_NAME}
EXPORT ${SI_PROJECT_NAME}-targets
COMPONENT Runtime
RUNTIME
DESTINATION bin
COMPONENT Runtime)
13 changes: 12 additions & 1 deletion include/aws/common/private/system_info_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* SPDX-License-Identifier: Apache-2.0.
*/

#include <aws/common/system_info.h>
#include <aws/common/byte_buf.h>
#include <aws/common/string.h>
#include <aws/common/system_info.h>

struct aws_system_environment {
struct aws_allocator *allocator;
Expand All @@ -19,7 +19,18 @@ struct aws_system_environment {
void *additional_impl_data;
};

/**
* For internal implementors. Fill in info in env that you're able to grab, such as dmi info, os version strings etc...
* in here. The default just returns AWS_OP_SUCCESS. This is currently only implemented for linux.
*
* Returns AWS_OP_ERR if the implementation wasn't able to fill in required information for the platform.
*/
int aws_system_environment_load_platform_impl(struct aws_system_environment *env);

/**
* For internal implementors. Cleans up anything allocated in aws_system_environment_load_platform_impl,
* but does not release the memory for env.
*/
void aws_system_environment_destroy_platform_impl(struct aws_system_environment *env);

#endif /* AWS_COMMON_SYSTEM_INFO_PRIV_H */
21 changes: 20 additions & 1 deletion include/aws/common/system_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,41 @@ struct aws_system_environment;

AWS_EXTERN_C_BEGIN

/**
* Allocates and initializes information about the system the current process is executing on.
* If successful returns an instance of aws_system_environment. If it fails, it will return NULL.
*/
AWS_COMMON_API
struct aws_system_environment *aws_system_environment_load(struct aws_allocator *allocator);

AWS_COMMON_API
void aws_system_environment_destroy(struct aws_system_environment *env);


/**
* Returns the virtualization vendor for the specified compute environment, e.g. "Xen, Amazon EC2, etc..."
*
* The return value may be empty and in that case no vendor was detected.
*/
AWS_COMMON_API
struct aws_byte_cursor aws_system_environment_get_virtualization_vendor(const struct aws_system_environment *env);

/**
* Returns the product name for the specified compute environment. For example, the Amazon EC2 Instance type.
*
* The return value may be empty and in that case no vendor was detected.
*/
AWS_COMMON_API
struct aws_byte_cursor aws_system_environment_get_virtualization_product_name(const struct aws_system_environment *env);

/**
* Returns the number of processors for the specified compute environment.
*/
AWS_COMMON_API
size_t aws_system_environment_get_processor_count(struct aws_system_environment *env);

/**
* Returns the number of separate cpu groupings (multi-socket configurations or NUMA).
*/
AWS_COMMON_API
size_t aws_system_environment_get_cpu_group_count(struct aws_system_environment *env);

Expand Down
10 changes: 7 additions & 3 deletions source/linux/system_info.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@

#include <aws/common/private/system_info_priv.h>
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/common/file.h>
#include <aws/common/private/system_info_priv.h>

int aws_system_environment_load_platform_impl(struct aws_system_environment *env) {
aws_byte_buf_init_from_file(&env->virtualization_vendor, env->allocator, "/sys/devices/virtual/dmi/id/sys_vendor");
/* whether this one works depends on if this is a sysfs filesystem. If it fails, it will just be empty
* and these APIs are a best effort at the moment. We can add fallbacks as the loaders get more complicated. */
aws_byte_buf_init_from_file(&env->product_name, env->allocator, "/sys/devices/virtual/dmi/id/product_name");

return AWS_OP_SUCCESS;
Expand All @@ -13,4 +18,3 @@ void aws_system_environment_destroy_platform_impl(struct aws_system_environment
aws_byte_buf_clean_up(&env->virtualization_vendor);
aws_byte_buf_clean_up(&env->product_name);
}

21 changes: 21 additions & 0 deletions source/platform_fallback_stubs/system_info.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/common/private/system_info_priv.h>

#include <aws/common/logging.h>

int aws_system_environment_load_platform_impl(struct aws_system_environment *env) {
(void)env;
AWS_LOGF_DEBUG(
AWS_LS_COMMON_GENERAL,
"id=%p: platform specific environment loading is not implemented for this platform.",
(void *)env);

return AWS_OP_SUCCESS;
}

void aws_system_environment_destroy_platform_impl(struct aws_system_environment *env) {
(void)env;
}
27 changes: 23 additions & 4 deletions source/system_info.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/common/private/system_info_priv.h>

#include <aws/common/logging.h>

struct aws_system_environment *aws_system_environment_load(struct aws_allocator *allocator) {
struct aws_system_environment *env = aws_mem_calloc(allocator, 1, sizeof(struct aws_system_environment));
env->allocator = allocator;

if (aws_system_environment_load_platform_impl(env)) {
AWS_LOGF_ERROR(
AWS_LS_COMMON_GENERAL,
"id=%p: failed to load system environment with error %s.",
(void *)env,
aws_error_debug_str(aws_last_error()));
goto error;
}

AWS_LOGF_TRACE(
AWS_LS_COMMON_GENERAL,
"id=%p: virtualization vendor detected as \"" PRInSTR "\"",
(void *)env,
AWS_BYTE_CURSOR_PRI(aws_system_environment_get_virtualization_vendor(env)));
AWS_LOGF_TRACE(
AWS_LS_COMMON_GENERAL,
"id=%p: virtualization product name detected as \"" PRInSTR " \"",
(void *)env,
AWS_BYTE_CURSOR_PRI(aws_system_environment_get_virtualization_vendor(env)));

env->os = aws_get_platform_build_os();
env->cpu_count = aws_system_info_processor_count();
env->cpu_group_count = aws_get_cpu_group_count();
Expand All @@ -35,7 +53,8 @@ struct aws_byte_cursor aws_system_environment_get_virtualization_vendor(const st
return aws_byte_cursor_trim_pred(&vendor_string, aws_char_is_space);
}

struct aws_byte_cursor aws_system_environment_get_virtualization_product_name(const struct aws_system_environment *env) {
struct aws_byte_cursor aws_system_environment_get_virtualization_product_name(
const struct aws_system_environment *env) {
struct aws_byte_cursor product_name_str = aws_byte_cursor_from_buf(&env->product_name);
return aws_byte_cursor_trim_pred(&product_name_str, aws_char_is_space);
}
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ add_test_case(test_cpu_count_at_least_works_superficially)
add_test_case(test_stack_trace_decoding)
add_test_case(test_platform_build_os)
add_test_case(test_sanity_check_numa_discovery)
add_test_case(test_sanity_check_environment_loader)

add_test_case(test_realloc_fallback)
add_test_case(test_realloc_passthrough)
Expand Down
19 changes: 19 additions & 0 deletions tests/system_info_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,22 @@ static int s_test_sanity_check_numa_discovery(struct aws_allocator *allocator, v
}

AWS_TEST_CASE(test_sanity_check_numa_discovery, s_test_sanity_check_numa_discovery)

static int s_test_sanity_check_environment_loader(struct aws_allocator *allocator, void *ctx) {
(void)ctx;

aws_common_library_init(allocator);
struct aws_system_environment *env = aws_system_environment_load(allocator);
ASSERT_NOT_NULL(env);
struct aws_byte_cursor virt_vendor = aws_system_environment_get_virtualization_vendor(env);
ASSERT_TRUE(aws_byte_cursor_is_valid(&virt_vendor));
struct aws_byte_cursor virt_product = aws_system_environment_get_virtualization_product_name(env);
ASSERT_TRUE(aws_byte_cursor_is_valid(&virt_product));

aws_system_environment_destroy(env);

aws_common_library_clean_up();
return 0;
}

AWS_TEST_CASE(test_sanity_check_environment_loader, s_test_sanity_check_environment_loader)

0 comments on commit 70d38a6

Please sign in to comment.