mirror of
https://github.com/google/pebble
synced 2026-10-16 08:14:11 +02:00
Import of the watch repository from Pebble
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* 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 "segment.h"
|
||||
|
||||
#include "system/passert.h"
|
||||
|
||||
#include <stdalign.h>
|
||||
|
||||
// Remove once the Bamboo build agents build unit tests with a more
|
||||
// C11-compliant compiler (i.e. clang >= 3.5)
|
||||
#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T)
|
||||
typedef long double max_align_t;
|
||||
#endif
|
||||
|
||||
static void prv_assert_sane_segment(MemorySegment *segment) {
|
||||
PBL_ASSERT(segment->start <= segment->end,
|
||||
"Segment end points before segment start");
|
||||
}
|
||||
|
||||
static void * prv_align(void *ptr) {
|
||||
uintptr_t c = (uintptr_t)ptr;
|
||||
// Advance the pointer to the next alignment boundary.
|
||||
return (void *)((c + alignof(max_align_t) - 1) & ~(alignof(max_align_t) - 1));
|
||||
}
|
||||
|
||||
|
||||
size_t memory_segment_get_size(MemorySegment *segment) {
|
||||
prv_assert_sane_segment(segment);
|
||||
return (size_t)((uintptr_t)segment->end - (uintptr_t)segment->start);
|
||||
}
|
||||
|
||||
void memory_segment_align(MemorySegment *segment) {
|
||||
segment->start = prv_align(segment->start);
|
||||
prv_assert_sane_segment(segment);
|
||||
}
|
||||
|
||||
void * memory_segment_split(MemorySegment * restrict parent,
|
||||
MemorySegment * restrict child, size_t size) {
|
||||
prv_assert_sane_segment(parent);
|
||||
char *child_start = prv_align(parent->start);
|
||||
void *child_end = child_start + size;
|
||||
if (child_end > parent->end) {
|
||||
// Requested size is too big to fit in the parent segment.
|
||||
return NULL;
|
||||
}
|
||||
void *adjusted_parent_start = prv_align(child_end);
|
||||
if (adjusted_parent_start > parent->end) {
|
||||
// The child has left no room for the adjusted parent.
|
||||
return NULL;
|
||||
}
|
||||
parent->start = adjusted_parent_start;
|
||||
|
||||
if (child) {
|
||||
*child = (MemorySegment) {
|
||||
.start = child_start,
|
||||
.end = child_end,
|
||||
};
|
||||
}
|
||||
return child_start;
|
||||
}
|
||||
Reference in New Issue
Block a user