diff --git a/src/platform_linux/shmem.c b/src/platform_linux/shmem.c index 249b3c1c..c3b65fa5 100644 --- a/src/platform_linux/shmem.c +++ b/src/platform_linux/shmem.c @@ -24,7 +24,7 @@ static bool Trace_large_frags = FALSE; /* * --------------------------------------------------------------------------- - * shm_frag_info{} - Struct describing a large memory fragment allocation. + * shm_large_frag_info{} - Struct describing a large memory fragment allocation. * * This is a specialized memory-fragment tracker solely constructed to satisfy * large memory requests. In Splinter large memory requests, i.e. something over @@ -45,17 +45,17 @@ static bool Trace_large_frags = FALSE; * - (allocated_to_pid != 0) && (freed_by_pid != 0) - Fragment is free. * --------------------------------------------------------------------------- */ -typedef struct shm_frag_info { - void *shm_frag_addr; // Start address of this memory fragment - // NULL => tracking fragment is empty - size_t shm_frag_size; // bytes (Used in re-allocation logic.) +typedef struct shm_large_frag_info { + void *frag_addr; // Start address of this memory fragment + // NULL => tracking fragment is empty + size_t frag_size; // bytes (Used in re-allocation logic.) // Following fields are used mainly for assertions and diagnostics. - int shm_frag_allocated_to_pid; // Allocated to this OS-pid - threadid shm_frag_allocated_to_tid; // Allocated to this Splinter thread-ID - int shm_frag_freed_by_pid; // OS-pid that freed this - threadid shm_frag_freed_by_tid; // Splinter thread-ID that freed this -} shm_frag_info; + int frag_allocated_to_pid; // Allocated to this OS-pid + threadid frag_allocated_to_tid; // Allocated to this Splinter thread-ID + int frag_freed_by_pid; // OS-pid that freed this large fragment + threadid frag_freed_by_tid; // Splinter thread-ID that freed fragment +} shm_large_frag_info; /* * All memory allocations of this size or larger will be tracked in the @@ -103,13 +103,14 @@ typedef struct shmem_heap { platform_spinlock shm_mem_frags_lock; // Protected by shm_mem_frags_lock. Must hold to read or modify. - shm_frag_info shm_mem_frags[SHM_NUM_LARGE_FRAGS]; - uint32 shm_num_frags_tracked; - uint32 shm_num_frags_inuse; - uint32 shm_num_frags_inuse_HWM; - size_t shm_used_by_large_frags; // Actually reserved - size_t shm_nfrees; // # of calls to free memory - size_t shm_nfrees_last_frag; // Freed last small-fragment + shm_large_frag_info shm_large_frags[SHM_NUM_LARGE_FRAGS]; + uint32 shm_nlarge_frags_tracked; + + uint32 shm_nlarge_frags_inuse; + uint32 shm_nlarge_frags_inuse_HWM; + size_t shm_used_by_large_frags; // Actually reserved + size_t shm_nfrees; // # of calls to free memory + size_t shm_nfrees_last_frag; // Freed last small-fragment size_t shm_total_bytes; // Total size of shared segment allocated initially. size_t shm_free_bytes; // Free bytes of memory left (that can be allocated) @@ -126,7 +127,7 @@ typedef struct shmem_heap { // Function prototypes static void -platform_shm_track_alloc(shmem_heap *shm, void *addr, size_t size); +platform_shm_track_large_alloc(shmem_heap *shm, void *addr, size_t size); static void platform_shm_track_free(shmem_heap *shm, @@ -137,12 +138,12 @@ platform_shm_track_free(shmem_heap *shm, const int lineno); static void * -platform_shm_find_free(shmem_heap *shm, - size_t size, - const char *objname, - const char *func, - const char *file, - const int lineno); +platform_shm_find_large(shmem_heap *shm, + size_t size, + const char *objname, + const char *func, + const char *file, + const int lineno); static void platform_shm_trace_allocs(shmem_heap *shm, @@ -253,7 +254,7 @@ typedef struct shminfo_usage_stats { size_t nfrees; size_t nf_search_skipped; size_t used_by_large_frags_bytes; - uint32 frags_inuse_HWM; + uint32 nlarge_frags_inuse_HWM; int large_frags_found_in_use; int shmid; } shminfo_usage_stats; @@ -289,7 +290,7 @@ platform_shm_print_usage_stats(shminfo_usage_stats *usage) usage->nf_search_skipped, (usage->nfrees ? (int)((usage->nf_search_skipped * 100) / usage->nfrees) : 0), - usage->frags_inuse_HWM, + usage->nlarge_frags_inuse_HWM, usage->large_frags_found_in_use, usage->used_by_large_frags_bytes, size_str(usage->used_by_large_frags_bytes)); @@ -313,7 +314,7 @@ platform_shm_print_usage(platform_heap_id hid) usage.free_bytes = shminfo->shm_free_bytes; usage.nfrees = shminfo->shm_nfrees; usage.used_by_large_frags_bytes = shminfo->shm_used_by_large_frags; - usage.frags_inuse_HWM = shminfo->shm_num_frags_inuse_HWM; + usage.nlarge_frags_inuse_HWM = shminfo->shm_nlarge_frags_inuse_HWM; usage.large_frags_found_in_use = platform_trace_large_frags(shminfo); platform_shm_print_usage_stats(&usage); @@ -460,13 +461,13 @@ platform_shmdestroy(platform_heap_id *hid_out) size_t shm_used_bytes = shm->shm_used_bytes; size_t shm_used_bytes_HWM = shm->shm_used_bytes_HWM; size_t shm_free_bytes = shm->shm_free_bytes; - uint32 frags_inuse_HWM = shm->shm_num_frags_inuse_HWM; + uint32 nlarge_frags_inuse_HWM = shm->shm_nlarge_frags_inuse_HWM; size_t used_by_large_frags_bytes = shm->shm_used_by_large_frags; size_t shm_nfrees = shm->shm_nfrees; size_t shm_nfrees_last_frag = shm->shm_nfrees_last_frag; // Print large-fragment tracking metrics (for deep debugging) - int found_in_use = platform_trace_large_frags(shm); + int large_frags_found_in_use = platform_trace_large_frags(shm); // Retain some memory usage stats before releasing shmem shminfo_usage_stats usage; @@ -478,8 +479,8 @@ platform_shmdestroy(platform_heap_id *hid_out) usage.free_bytes = shm->shm_free_bytes; usage.nfrees = shm->shm_nfrees; usage.used_by_large_frags_bytes = shm->shm_used_by_large_frags; - usage.frags_inuse_HWM = shm->shm_num_frags_inuse_HWM; - usage.large_frags_found_in_use = found_in_use; + usage.nlarge_frags_inuse_HWM = shm->shm_nlarge_frags_inuse_HWM; + usage.large_frags_found_in_use = large_frags_found_in_use; rv = shmctl(shmid, IPC_RMID, NULL); if (rv != 0) { @@ -538,8 +539,8 @@ platform_shmdestroy(platform_heap_id *hid_out) shm_nfrees, shm_nfrees_last_frag, (FRACTION_ARGS(freed_last_frag_pct) * 100), - frags_inuse_HWM, - found_in_use, + nlarge_frags_inuse_HWM, + large_frags_found_in_use, used_by_large_frags_bytes, size_str(used_by_large_frags_bytes)); // clang-format on @@ -589,7 +590,7 @@ platform_shm_alloc(platform_heap_id hid, // list of used/free fragments that are tracked separately. if ((size >= SHM_LARGE_FRAG_SIZE) && ((retptr = - platform_shm_find_free(shm, size, objname, func, file, lineno)) + platform_shm_find_large(shm, size, objname, func, file, lineno)) != NULL)) { return retptr; @@ -611,16 +612,16 @@ platform_shm_alloc(platform_heap_id hid, platform_error_log( "[%s:%d::%s()]: Insufficient memory in shared segment" " to allocate %lu bytes for '%s'. Approx free space=%lu bytes." - " shm_num_frags_tracked=%u, shm_num_frags_inuse=%u (HWM=%u).\n", + " shm_nlarge_frags_tracked=%u, shm_nlarge_frags_inuse=%u (HWM=%u).\n", file, lineno, func, size, objname, shm->shm_free_bytes, - shm->shm_num_frags_tracked, - shm->shm_num_frags_inuse, - shm->shm_num_frags_inuse_HWM); + shm->shm_nlarge_frags_tracked, + shm->shm_nlarge_frags_inuse, + shm->shm_nlarge_frags_inuse_HWM); platform_trace_large_frags(shm); return NULL; } @@ -635,7 +636,7 @@ platform_shm_alloc(platform_heap_id hid, shm_unlock_mem(shm); if (size >= SHM_LARGE_FRAG_SIZE) { - platform_shm_track_alloc(shm, retptr, size); + platform_shm_track_large_alloc(shm, retptr, size); } // Trace shared memory allocation; then return memory ptr. @@ -810,13 +811,13 @@ platform_shm_free(platform_heap_id hid, /* * ----------------------------------------------------------------------------- - * platform_shm_track_alloc() - Track the allocation of this large fragment. + * platform_shm_track_large_alloc() - Track the allocation of this large fragment. * 'Tracking' here means we record this large-fragment in an array tracking * large-memory fragments allocated. * ----------------------------------------------------------------------------- */ static void -platform_shm_track_alloc(shmem_heap *shm, void *addr, size_t size) +platform_shm_track_large_alloc(shmem_heap *shm, void *addr, size_t size) { debug_assert( (size >= SHM_LARGE_FRAG_SIZE), @@ -828,43 +829,43 @@ platform_shm_track_alloc(shmem_heap *shm, void *addr, size_t size) // Iterate through the list of memory fragments being tracked. int fctr = 0; - shm_frag_info *frag = shm->shm_mem_frags; + shm_large_frag_info *frag = shm->shm_large_frags; shm_lock_mem_frags(shm); - while ((fctr < ARRAY_SIZE(shm->shm_mem_frags)) && frag->shm_frag_addr) { + while ((fctr < ARRAY_SIZE(shm->shm_large_frags)) && frag->frag_addr) { // As this is a newly allocated fragment being tracked, it should // not be found elsewhere in the tracker array. - platform_assert((frag->shm_frag_addr != addr), + platform_assert((frag->frag_addr != addr), "Error! Newly allocated large memory fragment at %p" " is already tracked at slot %d." " Fragment is allocated to PID=%d, to tid=%lu," " and is %s (freed by PID=%d, by tid=%lu)\n.", addr, fctr, - frag->shm_frag_allocated_to_pid, - frag->shm_frag_allocated_to_tid, - (frag->shm_frag_freed_by_pid ? "free" : "in use"), - frag->shm_frag_freed_by_pid, - frag->shm_frag_freed_by_tid); + frag->frag_allocated_to_pid, + frag->frag_allocated_to_tid, + (frag->frag_freed_by_pid ? "free" : "in use"), + frag->frag_freed_by_pid, + frag->frag_freed_by_tid); fctr++; frag++; } // If we found a free slot, track our memory fragment at fctr'th slot. - if (fctr < ARRAY_SIZE(shm->shm_mem_frags)) { - shm->shm_num_frags_tracked++; - shm->shm_num_frags_inuse++; + if (fctr < ARRAY_SIZE(shm->shm_large_frags)) { + shm->shm_nlarge_frags_tracked++; + shm->shm_nlarge_frags_inuse++; shm->shm_used_by_large_frags += size; - if (shm->shm_num_frags_inuse > shm->shm_num_frags_inuse_HWM) { - shm->shm_num_frags_inuse_HWM = shm->shm_num_frags_inuse; + if (shm->shm_nlarge_frags_inuse > shm->shm_nlarge_frags_inuse_HWM) { + shm->shm_nlarge_frags_inuse_HWM = shm->shm_nlarge_frags_inuse; } // We should really assert that the other fields are zero, but for now // re-init this fragment tracker. memset(frag, 0, sizeof(*frag)); - frag->shm_frag_addr = addr; - frag->shm_frag_size = size; + frag->frag_addr = addr; + frag->frag_size = size; - frag->shm_frag_allocated_to_pid = getpid(); - frag->shm_frag_allocated_to_tid = platform_get_tid(); + frag->frag_allocated_to_pid = getpid(); + frag->frag_allocated_to_tid = platform_get_tid(); // The freed_by_pid/freed_by_tid == 0 means fragment is still allocated. @@ -905,32 +906,32 @@ platform_shm_track_free(shmem_heap *shm, bool found_tracked_frag = FALSE; bool trace_shmem = (Trace_shmem || Trace_shmem_frees); - shm_frag_info *frag = shm->shm_mem_frags; + shm_large_frag_info *frag = shm->shm_large_frags; int fctr = 0; - while ((fctr < ARRAY_SIZE(shm->shm_mem_frags)) - && (!frag->shm_frag_addr || (frag->shm_frag_addr != addr))) + while ((fctr < ARRAY_SIZE(shm->shm_large_frags)) + && (!frag->frag_addr || (frag->frag_addr != addr))) { fctr++; frag++; } - if (fctr < ARRAY_SIZE(shm->shm_mem_frags)) { - debug_assert(frag->shm_frag_addr == addr); + if (fctr < ARRAY_SIZE(shm->shm_large_frags)) { + debug_assert(frag->frag_addr == addr); found_tracked_frag = TRUE; // Cross-check the recording we did when fragment was allocated // We cannot check the tid as the parent process' tid may be 0. // We could have come across a free fragment that was previously // used by the parent process. - // debug_assert(frag->shm_frag_allocated_to_tid != 0); - debug_assert(frag->shm_frag_allocated_to_pid != 0); - debug_assert(frag->shm_frag_size != 0); + // debug_assert(frag->frag_allocated_to_tid != 0); + debug_assert(frag->frag_allocated_to_pid != 0); + debug_assert(frag->frag_size != 0); - shm->shm_num_frags_inuse--; + shm->shm_nlarge_frags_inuse--; // Mark the fragment as in-use by recording the process/thread that's // doing the free. - frag->shm_frag_freed_by_pid = getpid(); - frag->shm_frag_freed_by_tid = platform_get_tid(); + frag->frag_freed_by_pid = getpid(); + frag->frag_freed_by_tid = platform_get_tid(); if (trace_shmem) { platform_default_log("OS-pid=%d, ThreadID=%lu" @@ -938,13 +939,13 @@ platform_shm_track_free(shmem_heap *shm, ", at slot=%d, addr=%p" ", allocated_to_pid=%d, allocated_to_tid=%lu" ", shm_large_frag_hip=%p\n", - frag->shm_frag_freed_by_pid, - frag->shm_frag_freed_by_tid, - frag->shm_frag_size, + frag->frag_freed_by_pid, + frag->frag_freed_by_tid, + frag->frag_size, fctr, addr, - frag->shm_frag_allocated_to_pid, - frag->shm_frag_allocated_to_tid, + frag->frag_allocated_to_pid, + frag->frag_allocated_to_tid, shm->shm_large_frag_hip); } } @@ -965,14 +966,14 @@ platform_shm_track_free(shmem_heap *shm, /* * ----------------------------------------------------------------------------- - * platform_shm_find_free() - Search the array of large-fragments being tracked + * platform_shm_find_large() - Search the array of large-fragments being tracked * to see if there is an already allocated and now-free large memory fragment. * If so, allocate that fragment to this requester. Do the book-keeping * accordingly. * ----------------------------------------------------------------------------- */ static void * -platform_shm_find_free(shmem_heap *shm, +platform_shm_find_large(shmem_heap *shm, size_t size, const char *objname, const char *func, @@ -986,7 +987,7 @@ platform_shm_find_free(shmem_heap *shm, SHM_LARGE_FRAG_SIZE); void *retptr = NULL; - shm_frag_info *frag = shm->shm_mem_frags; + shm_large_frag_info *frag = shm->shm_large_frags; int local_in_use = 0; // Tracked while iterating in this fn, locally int found_at_fctr = -1; @@ -994,23 +995,23 @@ platform_shm_find_free(shmem_heap *shm, shm_lock_mem_frags(shm); - uint32 shm_num_frags_tracked = shm->shm_num_frags_tracked; - uint32 shm_num_frags_inuse = shm->shm_num_frags_inuse; + uint32 shm_nlarge_frags_tracked = shm->shm_nlarge_frags_tracked; + uint32 shm_nlarge_frags_inuse = shm->shm_nlarge_frags_inuse; - for (int fctr = 0; fctr < ARRAY_SIZE(shm->shm_mem_frags); fctr++, frag++) { - if (!frag->shm_frag_addr || (frag->shm_frag_size < size)) { + for (int fctr = 0; fctr < ARRAY_SIZE(shm->shm_large_frags); fctr++, frag++) { + if (!frag->frag_addr || (frag->frag_size < size)) { continue; } // Skip fragment if it's still in-use - if (frag->shm_frag_freed_by_pid == 0) { - platform_assert((frag->shm_frag_freed_by_tid == 0), + if (frag->frag_freed_by_pid == 0) { + platform_assert((frag->frag_freed_by_tid == 0), "Invalid state found for fragment at index %d," "freed_by_pid=%d but freed_by_tid=%lu " "(which should also be 0)\n", fctr, - frag->shm_frag_freed_by_pid, - frag->shm_frag_freed_by_tid); + frag->frag_freed_by_pid, + frag->frag_freed_by_tid); local_in_use++; continue; @@ -1019,23 +1020,23 @@ platform_shm_find_free(shmem_heap *shm, found_at_fctr = fctr; // Record the process/thread to which free fragment is being allocated - frag->shm_frag_allocated_to_pid = getpid(); - frag->shm_frag_allocated_to_tid = platform_get_tid(); + frag->frag_allocated_to_pid = getpid(); + frag->frag_allocated_to_tid = platform_get_tid(); - shm->shm_num_frags_inuse++; - if (shm->shm_num_frags_inuse > shm->shm_num_frags_inuse_HWM) { - shm->shm_num_frags_inuse_HWM = shm->shm_num_frags_inuse; + shm->shm_nlarge_frags_inuse++; + if (shm->shm_nlarge_frags_inuse > shm->shm_nlarge_frags_inuse_HWM) { + shm->shm_nlarge_frags_inuse_HWM = shm->shm_nlarge_frags_inuse; } - shm_num_frags_inuse = shm->shm_num_frags_inuse; + shm_nlarge_frags_inuse = shm->shm_nlarge_frags_inuse; // Now, mark that this fragment is in-use - frag->shm_frag_freed_by_pid = 0; - frag->shm_frag_freed_by_tid = 0; + frag->frag_freed_by_pid = 0; + frag->frag_freed_by_tid = 0; - retptr = frag->shm_frag_addr; + retptr = frag->frag_addr; // Zero out the recycled large-memory fragment, just to be sure ... - memset(retptr, 0, frag->shm_frag_size); + memset(retptr, 0, frag->frag_size); break; } shm_unlock_mem_frags(shm); @@ -1046,7 +1047,7 @@ platform_shm_find_free(shmem_heap *shm, if (found_tracked_frag) { /* * In this trace message, don't be confused if you see a wide gap - * between local_in_use and shm_num_frags_inuse. The latter is a global + * between local_in_use and shm_nlarge_frags_inuse. The latter is a global * counter while the former is a local counter. We may have found a * free fragment to reallocate early in the array w/o processing the * full array. Hence, these two values are likely to diff (by a big @@ -1055,22 +1056,22 @@ platform_shm_find_free(shmem_heap *shm, snprintf(msg, sizeof(msg), "Reallocated free fragment at slot=%d, addr=%p, " - "shm_num_frags_tracked=%u, shm_num_frags_inuse=%u" + "shm_nlarge_frags_tracked=%u, shm_nlarge_frags_inuse=%u" " (local_in_use=%d)", found_at_fctr, retptr, - shm_num_frags_tracked, - shm_num_frags_inuse, + shm_nlarge_frags_tracked, + shm_nlarge_frags_inuse, local_in_use); } else { snprintf(msg, sizeof(msg), "Did not find free fragment of size=%lu bytes to reallocate." - " shm_num_frags_tracked=%u, shm_num_frags_inuse=%u" + " shm_nlarge_frags_tracked=%u, shm_nlarge_frags_inuse=%u" " (local_in_use=%d)", size, - shm_num_frags_tracked, - shm_num_frags_inuse, + shm_nlarge_frags_tracked, + shm_nlarge_frags_inuse, local_in_use); } platform_shm_trace_allocs( @@ -1092,18 +1093,18 @@ static int platform_trace_large_frags(shmem_heap *shm) { int local_in_use = 0; // Tracked while iterating in this fn, locally - shm_frag_info *frag = shm->shm_mem_frags; + shm_large_frag_info *frag = shm->shm_large_frags; threadid thread_tid = platform_get_tid(); bool print_new_line = false; // Walk the tracked-fragments array looking for an in-use fragment - for (int fctr = 0; fctr < ARRAY_SIZE(shm->shm_mem_frags); fctr++, frag++) { - if (!frag->shm_frag_addr) { + for (int fctr = 0; fctr < ARRAY_SIZE(shm->shm_large_frags); fctr++, frag++) { + if (!frag->frag_addr) { continue; } // Skip freed fragments. - if (frag->shm_frag_freed_by_pid != 0) { + if (frag->frag_freed_by_pid != 0) { continue; } // Found a large fragment that is still "in-use" @@ -1111,13 +1112,13 @@ platform_trace_large_frags(shmem_heap *shm) // Do -NOT- assert here. As this is a diagnostic routine, report // the inconsistency, and continue to find more stray large fragments. - if (frag->shm_frag_freed_by_tid != 0) { + if (frag->frag_freed_by_tid != 0) { platform_error_log("Invalid state found for fragment at index %d," "freed_by_pid=%d but freed_by_tid=%lu " "(which should also be 0)\n", fctr, - frag->shm_frag_freed_by_pid, - frag->shm_frag_freed_by_tid); + frag->frag_freed_by_pid, + frag->frag_freed_by_tid); } if (!print_new_line) { @@ -1132,11 +1133,11 @@ platform_trace_large_frags(shmem_heap *shm) ", allocated_to_tid=%lu\n", thread_tid, fctr, - frag->shm_frag_addr, - frag->shm_frag_size, - size_str(frag->shm_frag_size), - frag->shm_frag_allocated_to_pid, - frag->shm_frag_allocated_to_tid); + frag->frag_addr, + frag->frag_size, + size_str(frag->frag_size), + frag->frag_allocated_to_pid, + frag->frag_allocated_to_tid); } return local_in_use; }