Skip to content

Commit c8cee4a

Browse files
committed
Make clippy happy
1 parent 38cdb35 commit c8cee4a

1 file changed

Lines changed: 75 additions & 86 deletions

File tree

src/lib.rs

Lines changed: 75 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ fn layout_for_allocation(
5252
req_user_alignment: usize, // Alignment requested for the user pointer
5353
) -> Result<(Layout, usize), ()> {
5454
// The alignment for the total block must satisfy both metadata and user alignment.
55-
let total_block_align = cmp::max(req_user_alignment, METADATA_ALIGN);
55+
let total_align = cmp::max(req_user_alignment, METADATA_ALIGN);
5656

5757
// Calculate the offset for the user data pointer.
5858
// The user pointer must start *after* the metadata AND satisfy `req_user_alignment`.
@@ -68,11 +68,10 @@ fn layout_for_allocation(
6868
};
6969

7070
// Calculate the total size needed for the allocation block.
71-
let total_block_size = user_data_offset.checked_add(req_user_size).ok_or(())?;
71+
let total_size = user_data_offset.checked_add(req_user_size).ok_or(())?;
7272

7373
// Create the final layout for the allocator.
74-
let total_layout =
75-
Layout::from_size_align(total_block_size, total_block_align).map_err(|_| ())?;
74+
let total_layout = Layout::from_size_align(total_size, total_align).map_err(|_| ())?;
7675

7776
Ok((total_layout, user_data_offset))
7877
}
@@ -86,12 +85,12 @@ fn layout_for_allocation(
8685
/// `user_ptr` must point to the start of the user data area of a valid allocation
8786
/// managed by this allocator. The memory layout must be as expected (Metadata immediately preceding).
8887
#[inline]
89-
unsafe fn get_metadata_ptr_from_user_ptr(user_ptr: NonNull<u8>) -> NonNull<Metadata> {
88+
unsafe fn get_metadata_ptr(user_ptr: NonNull<u8>) -> NonNull<Metadata> {
9089
// Calculate the address directly before the user pointer.
91-
let metadata_byte_ptr = user_ptr.as_ptr().sub(METADATA_SIZE);
90+
let metadata_ptr = user_ptr.as_ptr().sub(METADATA_SIZE);
9291
// Safety: Caller guarantees user_ptr points METADATA_SIZE bytes *after*
9392
// the start of a valid Metadata struct instance within the same allocated block.
94-
NonNull::new_unchecked(metadata_byte_ptr.cast::<Metadata>())
93+
NonNull::new_unchecked(metadata_ptr.cast::<Metadata>())
9594
}
9695

9796
/// Recovers the original allocation pointer (as returned by `talc`) and the
@@ -101,27 +100,27 @@ unsafe fn get_metadata_ptr_from_user_ptr(user_ptr: NonNull<u8>) -> NonNull<Metad
101100
/// `user_ptr` must be a non-null pointer returned by `malloc`, `aligned_alloc`, or `realloc`
102101
/// from this allocator. The metadata preceding it must be intact.
103102
#[inline]
104-
unsafe fn recover_alloc_ptr_and_layout(user_ptr: NonNull<u8>) -> Result<(NonNull<u8>, Layout), ()> {
103+
unsafe fn recover_alloc_info(user_ptr: NonNull<u8>) -> Result<(NonNull<u8>, Layout), ()> {
105104
// 1. Get pointer to metadata and read it to find original size and alignment.
106-
let metadata_ptr = get_metadata_ptr_from_user_ptr(user_ptr);
105+
let metadata_ptr = get_metadata_ptr(user_ptr);
107106
// Safety: Pointer is assumed valid by caller.
108107
let metadata = metadata_ptr.as_ptr().read();
109108

110109
// 2. Recalculate the layout and user_data_offset used for the original allocation.
111110
// Use the size and alignment stored *in the metadata*.
112-
let (original_total_layout, user_data_offset) =
111+
let (original_layout, user_data_offset) =
113112
layout_for_allocation(metadata.size, metadata.alignment)?;
114113

115114
// 3. Calculate the original allocation start pointer address.
116115
// user_ptr = alloc_ptr + user_data_offset
117116
// alloc_ptr = user_ptr - user_data_offset
118-
let alloc_start_ptr_addr = user_ptr.as_ptr().wrapping_sub(user_data_offset);
117+
let start_ptr_addr = user_ptr.as_ptr().wrapping_sub(user_data_offset);
119118

120119
// Safety: We assume the subtraction is valid and yields the original non-null pointer
121120
// returned by talc.
122-
let alloc_start_ptr = NonNull::new_unchecked(alloc_start_ptr_addr);
121+
let start_ptr = NonNull::new_unchecked(start_ptr_addr);
123122

124-
Ok((alloc_start_ptr, original_total_layout))
123+
Ok((start_ptr, original_layout))
125124
}
126125

127126
// == C API Implementation ==
@@ -151,6 +150,33 @@ pub unsafe extern "C" fn heap_init(address: *mut u8, size: usize) -> bool {
151150
ALLOCATOR.lock().claim(arena).is_ok()
152151
}
153152

153+
/// Returns the usable size of the memory block pointed to by `ptr`.
154+
/// This corresponds to the size originally requested during allocation (`malloc`, `aligned_alloc`, `realloc`).
155+
/// Returns 0 if `ptr` is null.
156+
///
157+
/// # Safety
158+
/// - `ptr` must be null or a pointer previously returned by `malloc`, `realloc`,
159+
/// or `aligned_alloc` from this specific allocator instance and implementation.
160+
/// Passing any other pointer (including pointers offset from the original user pointer)
161+
/// leads to Undefined Behavior.
162+
/// - The behavior is undefined if the metadata preceding `ptr` has been corrupted.
163+
#[no_mangle]
164+
pub unsafe extern "C" fn usable_size(ptr: *mut c_void) -> usize {
165+
// Standard behavior: usable_size(NULL) returns 0.
166+
let Some(user_ptr) = NonNull::new(ptr.cast::<u8>()) else {
167+
return 0;
168+
};
169+
170+
// Retrieve the stored size from the metadata located just before the user pointer.
171+
// Safety: Assumes `ptr` is valid and points *after* our metadata header as designed.
172+
let metadata_ptr = get_metadata_ptr(user_ptr);
173+
// Safety: Pointer is assumed valid by caller, points to readable Metadata.
174+
let metadata = metadata_ptr.as_ptr().read();
175+
176+
// Return the user-requested size stored in the metadata.
177+
metadata.size
178+
}
179+
154180
/// Internal allocation function implementing the core logic for `malloc` and `aligned_alloc`.
155181
/// Handles layout calculation, allocation via `talc`, metadata writing, and returns the aligned user pointer.
156182
///
@@ -171,20 +197,20 @@ unsafe fn allocate_internal(size: usize, alignment: usize) -> *mut c_void {
171197
// `alloc_ptr` points to the start of the talc allocation block.
172198
// Calculate the user pointer address based on the start and the offset.
173199
// Safety: alloc_ptr is valid and non-null, user_data_offset calculated correctly.
174-
let user_ptr_addr = alloc_ptr.as_ptr().add(user_data_offset);
200+
let user_ptr = alloc_ptr.as_ptr().add(user_data_offset);
175201

176202
// Calculate the metadata pointer address (immediately before user_ptr).
177203
// Safety: user_ptr_addr is valid, and layout_for_allocation ensures
178204
// user_data_offset >= METADATA_SIZE.
179-
let metadata_ptr_addr = user_ptr_addr.sub(METADATA_SIZE);
180-
let metadata_ptr = metadata_ptr_addr.cast::<Metadata>();
205+
let metadata_ptr = user_ptr.sub(METADATA_SIZE);
206+
let metadata_ptr = metadata_ptr.cast::<Metadata>();
181207

182208
// Write the metadata (original requested size and alignment).
183209
// Safety: metadata_ptr points to valid, allocated space of METADATA_SIZE within the block.
184210
metadata_ptr.write(Metadata { size, alignment });
185211

186212
// Return the user pointer (correctly aligned).
187-
user_ptr_addr as *mut c_void
213+
user_ptr as *mut c_void
188214
}
189215
Err(_) => ptr::null_mut(), // Allocation failed (OOM)
190216
}
@@ -205,8 +231,7 @@ pub unsafe extern "C" fn malloc(size: usize) -> *mut c_void {
205231
return ptr::null_mut();
206232
}
207233
// Use the natural alignment of usize as the default alignment for malloc.
208-
let default_alignment = align_of::<usize>();
209-
allocate_internal(size, default_alignment)
234+
allocate_internal(size, align_of::<usize>())
210235
}
211236

212237
/// Allocates memory with specified alignment.
@@ -251,21 +276,18 @@ pub unsafe extern "C" fn free(ptr: *mut c_void) {
251276
};
252277

253278
// Recover the original allocation pointer and layout using the metadata stored before user_ptr.
254-
match recover_alloc_ptr_and_layout(user_ptr) {
255-
Ok((alloc_start_ptr, original_total_layout)) => {
256-
// Safety: `alloc_start_ptr` and `original_total_layout` must correspond to a previous
279+
match recover_alloc_info(user_ptr) {
280+
Ok((start_ptr, original_layout)) => {
281+
// Safety: `start_ptr` and `original_layout` must correspond to a previous
257282
// allocation made by this allocator via `allocate_internal` or `realloc`.
258-
// `recover_alloc_ptr_and_layout` guarantees this if `user_ptr` was valid.
259-
ALLOCATOR
260-
.lock()
261-
.free(alloc_start_ptr, original_total_layout);
283+
// `recover_alloc_info` guarantees this if `user_ptr` was valid.
284+
ALLOCATOR.lock().free(start_ptr, original_layout);
262285
}
263286
Err(_) => {
264287
// Indicates an internal logic error (layout recovery failed) or memory corruption
265288
// (metadata damaged or ptr wasn't from this allocator).
266289
// In a real system, log an error or trigger an assertion. Avoid crashing.
267290
// Leaking memory might be the safest option here if corruption is suspected.
268-
return;
269291
}
270292
}
271293
}
@@ -275,50 +297,46 @@ pub unsafe extern "C" fn free(ptr: *mut c_void) {
275297
///
276298
/// # Safety
277299
/// - `ptr` must be null or a pointer previously returned by `malloc`, `realloc`, or `aligned_alloc`.
278-
/// - `new_size` is the desired size for the new allocation.
300+
/// - `size` is the desired size for the new allocation.
279301
/// - If reallocation fails, the original pointer `ptr` remains valid and must still be freed.
280302
/// - If reallocation succeeds, the original `ptr` is invalidated and the new pointer should be used.
281303
#[no_mangle]
282-
pub unsafe extern "C" fn realloc(ptr: *mut c_void, new_size: usize) -> *mut c_void {
283-
// Handle null pointer: standard requires this is equivalent to malloc(new_size).
284-
let Some(user_ptr_non_null) = NonNull::new(ptr.cast::<u8>()) else {
304+
pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void {
305+
// Handle null pointer: standard requires this is equivalent to malloc(size).
306+
let Some(user_ptr) = NonNull::new(ptr.cast::<u8>()) else {
285307
// Use default alignment consistent with malloc.
286-
let default_alignment = align_of::<usize>();
287-
return allocate_internal(new_size, default_alignment);
308+
return allocate_internal(size, align_of::<usize>());
288309
};
289310

290-
// Handle new_size == 0: standard requires this is equivalent to free(ptr) and returns null.
291-
if new_size == 0 {
311+
// Handle size == 0: standard requires this is equivalent to free(ptr) and returns null.
312+
if size == 0 {
292313
free(ptr);
293314
return ptr::null_mut();
294315
}
295316

296317
// --- Attempt Optimized Realloc ---
297318

298319
// 1. Recover original allocation info (pointer returned by talc and its layout).
299-
let (old_alloc_ptr, old_total_layout) = match recover_alloc_ptr_and_layout(user_ptr_non_null) {
320+
let (old_alloc_ptr, old_total_layout) = match recover_alloc_info(user_ptr) {
300321
Ok(res) => res,
301322
Err(_) => return ptr::null_mut(), // Cannot recover layout - indicates corruption or invalid ptr.
302323
};
303324

304325
// 2. Read old metadata *again* to get the original alignment and user size.
305326
// Safety: Assumes ptr is valid and metadata readable.
306-
let old_metadata = get_metadata_ptr_from_user_ptr(user_ptr_non_null)
307-
.as_ptr()
308-
.read();
309-
let original_alignment = old_metadata.alignment;
310-
let old_user_size = old_metadata.size;
327+
let old_metadata = get_metadata_ptr(user_ptr).as_ptr().read();
328+
let alignment = old_metadata.alignment;
311329

312330
// 3. Compare sizes and choose strategy.
313-
match new_size.cmp(&old_user_size) {
331+
match size.cmp(&old_metadata.size) {
314332
Ordering::Equal => {
315333
// Sizes are the same, no operation needed.
316334
ptr
317335
}
318336

319337
Ordering::Greater => {
320338
// Calculate the required new total layout based on new user size and original alignment.
321-
let (new_total_layout, _) = match layout_for_allocation(new_size, original_alignment) {
339+
let (new_total_layout, _) = match layout_for_allocation(size, alignment) {
322340
Ok(l) => l,
323341
Err(_) => return ptr::null_mut(), // New layout calculation failed.
324342
};
@@ -339,12 +357,9 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, new_size: usize) -> *mut c_vo
339357
// We MUST update the metadata *in place*.
340358
drop(allocator_lock); // Release lock before writing metadata
341359

342-
let metadata_ptr = get_metadata_ptr_from_user_ptr(user_ptr_non_null);
360+
let metadata_ptr = get_metadata_ptr(user_ptr);
343361
// Safety: metadata_ptr is valid as pointer hasn't moved.
344-
metadata_ptr.as_ptr().write(Metadata {
345-
size: new_size,
346-
alignment: original_alignment,
347-
});
362+
metadata_ptr.as_ptr().write(Metadata { size, alignment });
348363

349364
// Return the original user pointer.
350365
ptr
@@ -355,17 +370,19 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, new_size: usize) -> *mut c_vo
355370
drop(allocator_lock);
356371

357372
// Allocate a completely new block.
358-
let new_ptr_void = allocate_internal(new_size, original_alignment);
373+
let new_ptr_void = allocate_internal(size, alignment);
359374
if new_ptr_void.is_null() {
360375
// Allocation failed, original pointer `ptr` is still valid.
361376
return ptr::null_mut();
362377
}
363378
let new_user_ptr = new_ptr_void.cast::<u8>();
364379

365380
// Copy data from the old user pointer area to the new user pointer area.
366-
let copy_size = old_user_size; // When growing, copy the original size.
367-
// Safety: `ptr` and `new_user_ptr` are valid, non-overlapping.
368-
ptr::copy_nonoverlapping(user_ptr_non_null.as_ptr(), new_user_ptr, copy_size);
381+
let copy_size = old_metadata.size;
382+
383+
// When growing, copy the original size.
384+
// Safety: `ptr` and `new_user_ptr` are valid, non-overlapping.
385+
ptr::copy_nonoverlapping(user_ptr.as_ptr(), new_user_ptr, copy_size);
369386

370387
// Free the *original* allocation block (using recovered ptr and layout).
371388
// `free` will handle locking internally.
@@ -382,7 +399,7 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, new_size: usize) -> *mut c_vo
382399
// --- Shrink ---
383400
// Calculate the new total layout for the smaller size.
384401
let (new_total_layout, _new_user_data_offset) =
385-
match layout_for_allocation(new_size, original_alignment) {
402+
match layout_for_allocation(size, alignment) {
386403
Ok(l) => l,
387404
Err(_) => return ptr::null_mut(), // Should not fail for smaller size if old layout was valid.
388405
};
@@ -395,40 +412,12 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, new_size: usize) -> *mut c_vo
395412
allocator_lock.shrink(old_alloc_ptr, old_total_layout, new_total_size);
396413
drop(allocator_lock); // Release lock
397414

398-
let metadata_ptr = get_metadata_ptr_from_user_ptr(user_ptr_non_null);
415+
let metadata_ptr = get_metadata_ptr(user_ptr);
399416
// Safety: metadata_ptr is valid.
400-
metadata_ptr.as_ptr().write(Metadata {
401-
size: new_size,
402-
alignment: original_alignment,
403-
});
404-
ptr // Return original pointer
417+
metadata_ptr.as_ptr().write(Metadata { size, alignment });
418+
419+
// Return original pointer
420+
ptr
405421
}
406422
}
407423
}
408-
409-
/// Returns the usable size of the memory block pointed to by `ptr`.
410-
/// This corresponds to the size originally requested during allocation (`malloc`, `aligned_alloc`, `realloc`).
411-
/// Returns 0 if `ptr` is null.
412-
///
413-
/// # Safety
414-
/// - `ptr` must be null or a pointer previously returned by `malloc`, `realloc`,
415-
/// or `aligned_alloc` from this specific allocator instance and implementation.
416-
/// Passing any other pointer (including pointers offset from the original user pointer)
417-
/// leads to Undefined Behavior.
418-
/// - The behavior is undefined if the metadata preceding `ptr` has been corrupted.
419-
#[no_mangle]
420-
pub unsafe extern "C" fn usable_size(ptr: *mut c_void) -> usize {
421-
// Standard behavior: usable_size(NULL) returns 0.
422-
let Some(user_ptr) = NonNull::new(ptr.cast::<u8>()) else {
423-
return 0;
424-
};
425-
426-
// Retrieve the stored size from the metadata located just before the user pointer.
427-
// Safety: Assumes `ptr` is valid and points *after* our metadata header as designed.
428-
let metadata_ptr = get_metadata_ptr_from_user_ptr(user_ptr);
429-
// Safety: Pointer is assumed valid by caller, points to readable Metadata.
430-
let metadata = metadata_ptr.as_ptr().read();
431-
432-
// Return the user-requested size stored in the metadata.
433-
metadata.size
434-
}

0 commit comments

Comments
 (0)