diff --git a/prism/defines.h b/prism/defines.h index c9af5fa42c..8fa6a6a3d1 100644 --- a/prism/defines.h +++ b/prism/defines.h @@ -99,4 +99,13 @@ # define PM_STATIC_ASSERT(line, condition, message) typedef char PM_CONCATENATE(static_assert_, line)[(condition) ? 1 : -1] #endif +/** + * In general, libc for embedded systems does not support memory-mapped files. + * If the target platform is POSIX or Windows, we can map a file in memory and + * read it in a more efficient manner. + */ +#if defined(_POSIX_MAPPED_FILES) || defined(_WIN32) +# define PRISM_HAS_MMAP +#endif + #endif diff --git a/prism/templates/src/serialize.c.erb b/prism/templates/src/serialize.c.erb index c9511bbfca..7c20e06ea9 100644 --- a/prism/templates/src/serialize.c.erb +++ b/prism/templates/src/serialize.c.erb @@ -41,9 +41,11 @@ pm_serialize_string(pm_parser_t *parser, pm_string_t *string, pm_buffer_t *buffe pm_buffer_append_bytes(buffer, pm_string_source(string), length); break; } +#ifdef PRISM_HAS_MMAP case PM_STRING_MAPPED: assert(false && "Cannot serialize mapped strings."); break; +#endif } } diff --git a/prism/util/pm_string.c b/prism/util/pm_string.c index 8f3ef92c9b..4589f1e8c6 100644 --- a/prism/util/pm_string.c +++ b/prism/util/pm_string.c @@ -102,7 +102,7 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) { *string = (pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = (size_t) file_size }; return true; -#else +#elif defined(_POSIX_MAPPED_FILES) // Open the file for reading int fd = open(filepath, O_RDONLY); if (fd == -1) { @@ -135,6 +135,11 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) { close(fd); *string = (pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = size }; return true; +#else + (void) string; + (void) filepath; + perror("pm_string_mapped_init is not implemented for this platform"); + return false; #endif } @@ -213,11 +218,13 @@ pm_string_free(pm_string_t *string) { if (string->type == PM_STRING_OWNED) { free(memory); +#ifdef PRISM_HAS_MMAP } else if (string->type == PM_STRING_MAPPED && string->length) { #if defined(_WIN32) UnmapViewOfFile(memory); -#else +#elif defined(_POSIX_MAPPED_FILES) munmap(memory, string->length); #endif +#endif /* PRISM_HAS_MMAP */ } } diff --git a/prism/util/pm_string.h b/prism/util/pm_string.h index 8a568a8238..758677b197 100644 --- a/prism/util/pm_string.h +++ b/prism/util/pm_string.h @@ -17,7 +17,7 @@ // The following headers are necessary to read files using demand paging. #ifdef _WIN32 #include -#else +#elif defined(_POSIX_MAPPED_FILES) #include #include #include @@ -45,8 +45,10 @@ typedef struct { /** This string owns its memory, and should be freed using `pm_string_free`. */ PM_STRING_OWNED, +#ifdef PRISM_HAS_MMAP /** This string is a memory-mapped file, and should be freed using `pm_string_free`. */ PM_STRING_MAPPED +#endif } type; } pm_string_t;