# HG changeset patch # User jfp <jf.pieronne@laposte.net> # Date 1737965165 -3600 # Mon Jan 27 09:06:05 2025 +0100 # Node ID 56bdbeabb0c4c8500eaaae1c4063e1f40ec7e2a1 # Parent 6e0b22f464a6cebb092c4e0c3a31d83c5e6376dd Allocate buffer with a end at page limit diff --git a/python/local/ovms_module/ovms/ptd/_vmsptd.pyx b/python/local/ovms_module/ovms/ptd/_vmsptd.pyx --- a/python/local/ovms_module/ovms/ptd/_vmsptd.pyx +++ b/python/local/ovms_module/ovms/ptd/_vmsptd.pyx @@ -112,7 +112,8 @@ void read_start_read_ast (...) void read_end_read_ast (...) void* align_pointer (...) - + void* allocate_page_aligned_memory(...) + void free_page_aligned_memory(...) from libc.stdio cimport printf, puts, sprintf @@ -302,22 +303,21 @@ cdef PtdHandler handler = PtdHandler() cdef DevChar* devchar cdef unsigned short buflen - cdef int item_code = SYI__MAXBUF + cdef int item_code = SYI__MAXBUF cdef int maxbuf s = lib_getsyi(&item_code, &maxbuf) + checkStatus(s); cdef int nbpages = 6 # 4 + 1 data + 1 guard pages cdef int nbpagelets = <int>(nbpages * pgsize / 512) - - checkStatus(s); + cdef int allocsz = sizeof(ptd_handler) + 3 * maxbuf + pgsize if charbuff is None: devchar = NULL buflen = 0 else: devchar = &(charbuff.devchar) buflen = sizeof(charbuff.devchar) - s = lib_get_vm_page(&nbpagelets, &(handler.handler)) - checkStatus(s) - ptrc = <char *>align_pointer(<char *>handler.handler + pgsize, pgsize, 1) # align to page boundary, keep one data page + handler.handler = <ptd_handler *>allocate_page_aligned_memory(allocsz, pgsize) + ptrc = <char *>handler.handler + pgsize handler.handler.read_buf = ptrc handler.handler.write_buf = ptrc + maxbuf handler.handler.echo_buf = ptrc + 2 * maxbuf @@ -325,22 +325,20 @@ handler.handler.maxbuf = maxbuf handler.handler.inadr.va_range_ps_start_va = ptrc handler.handler.buflen = buflen - handler.handler.inadr.va_range_ps_end_va = <char *>align_pointer(<char *>handler.handler + nbpagelets * 512 - 1, - pgsize, 0) - 1 + handler.handler.inadr.va_range_ps_end_va = \ + <char *>align_pointer(<char *>handler.handler + allocsz, pgsize, 1) - 1 handler.handler.read_status = 0 handler.handler.timer_status = 0 s = lib_get_ef(<unsigned int *>&(handler.handler.efn)) if s & 1 == 0: - lib_free_vm_page(<int *>&(handler.handler.nbpagelets), - &(handler.handler)) + free_page_aligned_memory(ptrc) checkStatus(s) s = ptd_create(<unsigned short*>&(handler.handler.channel), acmode, devchar, buflen, 0, 0, 0, <VA_RANGE *>&(handler.handler.inadr)) if s & 1 == 0: lib_free_ef(<unsigned int *>&(handler.handler.efn)) - lib_free_vm_page(<int *>&(handler.handler.nbpagelets), - &(handler.handler)) + free_page_aligned_memory(ptrc) checkStatus(s) return s, handler @@ -353,8 +351,7 @@ checkStatus(s) s = lib_free_ef(<unsigned int *>&(handler.handler.efn)) checkStatus(s) - s = lib_free_vm_page(<int *>&(handler.handler.nbpagelets), - &(handler.handler)) + free_page_aligned_memory(handler.handler.read_buf) return s def readw(PtdHandler handler): diff --git a/python/local/ovms_module/ovms/ptd/ovptd.h b/python/local/ovms_module/ovms/ptd/ovptd.h --- a/python/local/ovms_module/ovms/ptd/ovptd.h +++ b/python/local/ovms_module/ovms/ptd/ovptd.h @@ -166,4 +166,51 @@ return (void*)(addr & ~(page_size - 1)); } } + +void* allocate_page_aligned_memory(size_t size, size_t page_size) { + /* + * Allocates memory aligned to a page boundary with a length rounded + * to the nearest multiple of the page size. + * + * Parameters: + * size - The requested size of the memory block. + * page_size - The alignment size (usually the system's page size). + * + * Returns: + * A pointer to the allocated memory (aligned) or NULL on failure. + */ + + // Round size up to the nearest multiple of the page size + size_t rounded_size = (size + page_size - 1) & ~(page_size - 1); + + // Over-allocate memory to ensure alignment + void* raw_memory = malloc(rounded_size + page_size - 1 + sizeof(void*)); + if (raw_memory == NULL) { + return NULL; // Allocation failed + } + + // Align the pointer + uintptr_t raw_addr = (uintptr_t)raw_memory + sizeof(void*); + uintptr_t aligned_addr = (raw_addr + (page_size - 1)) & ~(page_size - 1); + + // Store the original pointer just before the aligned memory + ((void**)aligned_addr)[-1] = raw_memory; + + return (void*)aligned_addr; +} + +void free_page_aligned_memory(void* aligned_memory) { + /* + * Frees memory allocated with allocate_page_aligned_memory. + * + * Parameters: + * aligned_memory - Pointer to the aligned memory. + */ + if (aligned_memory) { + // Retrieve the original pointer and free it + void* raw_memory = ((void**)aligned_memory)[-1]; + free(raw_memory); + } +} + #endif