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

Factor out code that should move to cxplat #82

Merged
merged 15 commits into from
Aug 20, 2023
Merged

Factor out code that should move to cxplat #82

merged 15 commits into from
Aug 20, 2023

Conversation

dthaler
Copy link
Contributor

@dthaler dthaler commented Aug 18, 2023

  • Move leak detection and fault injection to cxplat_winuser
  • Add tests for memory realloc
  • Add cxplat_test to CI/CD

@dthaler dthaler marked this pull request as draft August 18, 2023 00:55
Signed-off-by: Dave Thaler <[email protected]>
cxplat/inc/cxplat.h Outdated Show resolved Hide resolved
cxplat/inc/cxplat/common.h Outdated Show resolved Hide resolved
NTSTATUS
usersim_fault_injection_initialize(size_t stack_depth) noexcept;
int
cxplat_fault_injection_initialize(size_t stack_depth) NOEXCEPT;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already extern "c" all these functions. Why do you have the NOEXCEPT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://stackoverflow.com/questions/24362616/does-the-c-standard-mandate-that-c-linkage-functions-are-noexcept

"it's a good idea that user defined extern "C" functions be also specified with noexcept, unless it is handed a pointer to C++ function as callback argument like qsort and the likes"

#endif

#ifdef _DEBUG
#define cxplat_assert(x) assert(x)
Copy link
Member

@nibanks nibanks Aug 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For MsQuic, we generally follow the pattern that #define macros are always all upper case: CXPLAT_ASSERT. Additionally, we have several types of asserts:

#define CXPLAT_DBG_ASSERT(_exp) 
#define CXPLAT_DBG_ASSERTMSG(_exp, _msg)
#define CXPLAT_TEL_ASSERT(_exp)
#define CXPLAT_TEL_ASSERTMSG(_exp, _msg)
#define CXPLAT_TEL_ASSERTMSG_ARGS(_exp, _msg, _origin, _bucketArg1, _bucketArg2)
#define CXPLAT_FRE_ASSERT(_exp)
#define CXPLAT_FRE_ASSERTMSG(_exp, _msg)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FRE is super confusing and not cross-platform as a term. I propose using _RUNTIME_

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm definitely open to other terms. Not sure how I feel about RUNTIME though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to other terms too :)

cxplat/inc/cxplat.h Outdated Show resolved Hide resolved
* @param[in] size Size of memory to allocate.
* @returns Pointer to memory block allocated, or null on failure.
*/
_Must_inspect_result_ _Ret_writes_maybenull_(size) void* cxplat_allocate(size_t size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super happy to see the SAL annotations, but you will need a stub file for posix platforms. Feel free to steal quic_sal_stub.h and rename to cxplat_sal_stub.h or whatever you'd like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed. not needed for this PR but agree it will be needed eventually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose we do this after moving code to the cxplat repo, since a stub file isn't needed for the usersim project which does not support posix platforms.

cxplat/inc/cxplat/common.h Outdated Show resolved Hide resolved
Signed-off-by: Dave Thaler <[email protected]>
Signed-off-by: Dave Thaler <[email protected]>
Signed-off-by: Dave Thaler <[email protected]>
#pragma once
// Do not add anything else to this file.
// Actual platform-specific definitions go in the file below.
#include "cxplat_winuser.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "cxplat_winuser.h"
#ifdef _KERNEL_MODE
#error "Windows kernel platform is unsupported"
#elif _WIN32
#include "cxplat_winuser.h"
#else
#error "Unknown unsupported Platform"
#endif

Maybe make this a bit explicit right off the bat?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a general distaste for ifdefs, they clutter the code and can easily leave dead code sections.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel strongly about this, so may adopt this suggestion in the next PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can discuss more in a follow up PR, but I don't want each consumer of cxplat to be required to have platforms specific logic to change the include path. They should include one path, and just #include <cxplat_platform.h> and be good to go.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #83 to track

// SPDX-License-Identifier: MIT
#pragma once
#include <winerror.h>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also recommend:

#define CXPLAT_FAILED(X) FAILED(X)
#define CXPLAT_SUCCEEDED(X) SUCCEEDED(X)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dislike having two macros that do the same thing. How is FAILED different from !SUCCEEDED?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

98% of the time, code uses the failed marco for error conditions, so if we did have to pick just 1, I'd prefer that. But I do like having two for the cases where you want the opposite. Having english words instead of just ! the other is nicer (IMO) to read.

@dthaler dthaler marked this pull request as ready for review August 18, 2023 21:29
@dthaler dthaler changed the title WIP: factor out code that should move to cxplat Factor out code that should move to cxplat Aug 18, 2023
Signed-off-by: Dave Thaler <[email protected]>
@dthaler dthaler force-pushed the cxplat branch 3 times, most recently from ec55537 to 6c6a136 Compare August 18, 2023 22:09
Signed-off-by: Dave Thaler <[email protected]>
Comment on lines +13 to +14
cxplat_status_t
cxplat_initialize();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind not having the spaces before all these lines? IMHO, it's a lot of wasted space.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think clang-format did it, the formatting isn't supposed to be manual.
We can see if there's a config option to do what you want.

Comment on lines +8 to +11
#ifdef __cplusplus
extern "C"
{
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To simplify this stuff, we can define EXTERN_C (or EXTERN_C_START) and EXTERN_C_END in cxplat_common.h for this. It would reduce the duplication and line count a bit. It would also hide the { and } to eliminate any visible/explicit need to tab things over.

Copy link
Contributor Author

@dthaler dthaler Aug 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #84

{
CXPLAT_STATUS_SUCCESS = CXPLAT_PLATFORM_STATUS_SUCCESS,
CXPLAT_STATUS_NO_MEMORY = CXPLAT_PLATFORM_STATUS_NO_MEMORY,
} cxplat_status_t;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a problem with defining cxplat_status_t as an enum instead of the platform type (HRESULT or NTSTATUS): you lose the "success" SAL annotation of those types that is then used for evaluation of a function being successful or not.

typedef _Return_type_success_(return >= 0) long HRESULT;

typedef _Return_type_success_(return >= 0) LONG NTSTATUS;

I'm not sure if we can get the same thing on this enum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe yes we can get it on an enum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// Include platform-specific definitions of common defines.
#include "cxplat_platform.h"

#include <assert.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, in MsQuic's platform abstraction, the definition of assert is platform specific, and does not use assert.h. On Windows we have:

#define CXPLAT_ASSERT_LOG(_exp, _msg) \
    (CXPLAT_ANALYSIS_ASSUME(_exp), \
    ((!(_exp)) ? (CxPlatLogAssert(__FILE__, __LINE__, #_exp), FALSE) : TRUE))

#define CXPLAT_ASSERT_CRASH(_exp, _msg) \
    (CXPLAT_ANALYSIS_ASSUME(_exp), \
    ((!(_exp)) ? \
        (CxPlatLogAssert(__FILE__, __LINE__, #_exp), \
         __annotation(L"Debug", L"AssertFail", _msg), \
         DbgRaiseAssertionFailure(), FALSE) : \
        TRUE))

Copyright (c) Microsoft Corporation
SPDX-License-Identifier: MIT
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do this in a follow up PR, but this project file needs some work. It won't load on xbox for instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #85 to track

cxplat_initialize()
{
try {
auto fault_injection_stack_depth =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually, this all needs to be DEBUG only.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #86

Copy link
Member

@nibanks nibanks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work so far.

Signed-off-by: Dave Thaler <[email protected]>
@dthaler dthaler merged commit 0c9cc82 into main Aug 20, 2023
@dthaler dthaler deleted the cxplat branch August 20, 2023 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants