-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[dns-sd] Optimize memory usage of SRP client (#8370)
* [dns-sd] Optimize memory usage of SRP client Allocate all SRP service data from a single flat buffer instead of using an array of arrays. That way, less memory is used when entries of the same kind differ in size. Also, don't duplicate TXT entry keys as they are constants. * Address code review comments * Add TODO * Restyled by clang-format Co-authored-by: Restyled.io <[email protected]>
- Loading branch information
Showing
9 changed files
with
313 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* | ||
* Copyright (c) 2021 Project CHIP Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "FixedBufferAllocator.h" | ||
|
||
#include <cstring> | ||
|
||
namespace chip { | ||
uint8_t * FixedBufferAllocator::Alloc(size_t count) | ||
{ | ||
if (mBegin + count > mEnd) | ||
{ | ||
mAnyAllocFailed = true; | ||
return nullptr; | ||
} | ||
|
||
uint8_t * ptr = mBegin; | ||
mBegin += count; | ||
return ptr; | ||
} | ||
|
||
uint8_t * FixedBufferAllocator::Clone(const void * data, size_t dataLen) | ||
{ | ||
uint8_t * ptr = Alloc(dataLen); | ||
|
||
if (ptr != nullptr) | ||
{ | ||
memcpy(ptr, data, dataLen); | ||
} | ||
|
||
return ptr; | ||
} | ||
|
||
char * FixedBufferAllocator::Clone(const char * str) | ||
{ | ||
return reinterpret_cast<char *>(Clone(str, strlen(str) + 1)); | ||
} | ||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* | ||
* Copyright (c) 2021 Project CHIP Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <cstddef> | ||
#include <cstdint> | ||
|
||
namespace chip { | ||
/** | ||
* Memory allocator that uses a fixed-size buffer. | ||
* | ||
* This class allocates subsequent memory regions out of a fixed-size buffer. | ||
* Deallocation of specific regions is unsupported and it is assumed that the entire | ||
* buffer will be released at once. | ||
*/ | ||
class FixedBufferAllocator | ||
{ | ||
public: | ||
FixedBufferAllocator() = default; | ||
FixedBufferAllocator(uint8_t * buffer, size_t capacity) { Init(buffer, capacity); } | ||
|
||
template <size_t N> | ||
explicit FixedBufferAllocator(uint8_t (&buffer)[N]) | ||
{ | ||
Init(buffer); | ||
} | ||
|
||
void Init(uint8_t * buffer, size_t capacity) | ||
{ | ||
mBegin = buffer; | ||
mEnd = buffer + capacity; | ||
mAnyAllocFailed = false; | ||
} | ||
|
||
template <size_t N> | ||
void Init(uint8_t (&buffer)[N]) | ||
{ | ||
Init(buffer, N); | ||
} | ||
|
||
/** | ||
* Allocate a specified number of bytes. | ||
* | ||
* @param count Number of bytes to allocate. | ||
* @return Pointer to the allocated memory region or nullptr on failure. | ||
*/ | ||
uint8_t * Alloc(size_t count); | ||
|
||
/** | ||
* Allocate memory for the specified data and copy the data into the allocated region. | ||
* | ||
* @param data Pointer to the data to be copied into the allocated memory region. | ||
* @param dataLen Size of the data to be copied into the allocated memory region. | ||
* @return Pointer to the allocated memory region or nullptr on failure. | ||
*/ | ||
uint8_t * Clone(const void * data, size_t dataLen); | ||
|
||
/** | ||
* Allocate memory for the specified string and copy the string, including | ||
* the null-character, into the allocated region. | ||
* | ||
* @param str Pointer to the string to be copied into the allocated memory region. | ||
* @return Pointer to the allocated memory region or nullptr on failure. | ||
*/ | ||
char * Clone(const char * str); | ||
|
||
/** | ||
* Returns whether any allocation has failed so far. | ||
*/ | ||
bool AnyAllocFailed() const { return mAnyAllocFailed; } | ||
|
||
private: | ||
FixedBufferAllocator(const FixedBufferAllocator &) = delete; | ||
void operator=(const FixedBufferAllocator &) = delete; | ||
|
||
uint8_t * mBegin = nullptr; | ||
uint8_t * mEnd = nullptr; | ||
bool mAnyAllocFailed = false; | ||
}; | ||
|
||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* | ||
* Copyright (c) 2021 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <support/FixedBufferAllocator.h> | ||
#include <support/UnitTestRegistration.h> | ||
|
||
#include <cstring> | ||
#include <nlunit-test.h> | ||
|
||
using namespace chip; | ||
|
||
namespace { | ||
|
||
void TestClone(nlTestSuite * inSuite, void * inContext) | ||
{ | ||
uint8_t buffer[128]; | ||
FixedBufferAllocator alloc(buffer); | ||
|
||
const char * kTestString = "Test string"; | ||
const char * allocatedString = alloc.Clone(kTestString); | ||
|
||
NL_TEST_ASSERT(inSuite, allocatedString != nullptr); | ||
NL_TEST_ASSERT(inSuite, allocatedString != kTestString); | ||
NL_TEST_ASSERT(inSuite, strcmp(allocatedString, kTestString) == 0); | ||
|
||
const uint8_t kTestData[] = { 0xDE, 0xAD, 0xBE, 0xEF }; | ||
const uint8_t * allocatedData = alloc.Clone(kTestData, sizeof(kTestData)); | ||
|
||
NL_TEST_ASSERT(inSuite, allocatedData != nullptr); | ||
NL_TEST_ASSERT(inSuite, allocatedData != kTestData); | ||
NL_TEST_ASSERT(inSuite, memcmp(allocatedData, kTestData, sizeof(kTestData)) == 0); | ||
} | ||
|
||
void TestOutOfMemory(nlTestSuite * inSuite, void * inContext) | ||
{ | ||
uint8_t buffer[16]; | ||
FixedBufferAllocator alloc(buffer); | ||
|
||
const char * kTestData = "0123456789abcdef"; | ||
|
||
// Allocating 16 bytes still works... | ||
NL_TEST_ASSERT(inSuite, alloc.Clone(kTestData, 16) != nullptr); | ||
NL_TEST_ASSERT(inSuite, !alloc.AnyAllocFailed()); | ||
|
||
// ...but cannot allocate even one more byte... | ||
NL_TEST_ASSERT(inSuite, alloc.Clone(kTestData, 1) == nullptr); | ||
NL_TEST_ASSERT(inSuite, alloc.AnyAllocFailed()); | ||
} | ||
|
||
const nlTest sTests[] = { NL_TEST_DEF("Test successfull clone", TestClone), NL_TEST_DEF("Test out of memory", TestOutOfMemory), | ||
NL_TEST_SENTINEL() }; | ||
|
||
} // namespace | ||
|
||
int TestFixedBufferAllocator() | ||
{ | ||
nlTestSuite theSuite = { "CHIP FixedBufferAllocator tests", &sTests[0], nullptr, nullptr }; | ||
|
||
// Run test suit againt one context. | ||
nlTestRunner(&theSuite, nullptr); | ||
return nlTestRunnerStats(&theSuite); | ||
} | ||
|
||
CHIP_REGISTER_TEST_SUITE(TestFixedBufferAllocator) |
Oops, something went wrong.