void threaded_resampler::free_contrib_lists() { if (m_pX_contribs) { vogl_free(m_pX_contribs->p); m_pX_contribs->p = NULL; vogl_free(m_pX_contribs); m_pX_contribs = NULL; } if (m_pY_contribs) { vogl_free(m_pY_contribs->p); m_pY_contribs->p = NULL; vogl_free(m_pY_contribs); m_pY_contribs = NULL; } }
void *file_utils::read_file_to_heap(const char *pPath, size_t &data_size) { data_size = 0; FILE *pFile = vogl_fopen(pPath, "rb"); if (!pFile) return NULL; vogl_fseek(pFile, 0, SEEK_END); uint64_t file_size = vogl_ftell(pFile); vogl_fseek(pFile, 0, SEEK_SET); if (file_size > VOGL_MAX_POSSIBLE_HEAP_BLOCK_SIZE) { vogl_fclose(pFile); return NULL; } data_size = static_cast<size_t>(file_size); VOGL_ASSERT(data_size == file_size); void *p = vogl_malloc(data_size); if (!p) { vogl_fclose(pFile); data_size = 0; return NULL; } bool success = (vogl_fread(p, 1, data_size, pFile) == data_size); vogl_fclose(pFile); if (!success) { vogl_free(p); data_size = 0; return NULL; } return p; }
bool file_utils::read_file_to_vec(const char *pPath, uint8_vec &data) { size_t data_size; void *p = read_file_to_heap(pPath, data_size); if (!p) return false; if (static_cast<uint>(data_size) != data_size) return false; if (!data.try_resize(static_cast<uint>(data_size))) return false; if (!data.grant_ownership(static_cast<uint8 *>(p), static_cast<uint>(data_size), static_cast<uint>(data_size))) { vogl_free(p); return false; } return true; }
bool elemental_vector::increase_capacity(uint32_t min_new_capacity, bool grow_hint, uint32_t element_size, object_mover pMover, bool nofail) { VOGL_ASSERT(m_size <= m_capacity); #ifdef VOGL_64BIT_POINTERS VOGL_ASSERT(min_new_capacity < (0x400000000ULL / element_size)); #else VOGL_ASSERT(min_new_capacity < (0x7FFF0000U / element_size)); #endif if (m_capacity >= min_new_capacity) return true; size_t new_capacity = min_new_capacity; if ((grow_hint) && (!math::is_power_of_2(static_cast<uint64_t>(new_capacity)))) { uint64_t new_capacity64 = math::next_pow2(static_cast<uint64_t>(new_capacity)); if (new_capacity64 != static_cast<size_t>(new_capacity64)) new_capacity64 = min_new_capacity; new_capacity = static_cast<size_t>(new_capacity64); } VOGL_ASSERT(new_capacity && (new_capacity > m_capacity)); uint64_t desired_size64 = element_size * static_cast<uint64_t>(new_capacity); if ((desired_size64 != static_cast<size_t>(desired_size64)) || (desired_size64 > VOGL_MAX_POSSIBLE_HEAP_BLOCK_SIZE)) { if (nofail) return false; char buf[256]; sprintf(buf, "%s: Can't increase capacity to %" PRIu64 " items, %" PRIu64 " bytes", VOGL_FUNCTION_INFO_CSTR, static_cast<uint64_t>(new_capacity), desired_size64); VOGL_FAIL(buf); } const size_t desired_size = static_cast<size_t>(desired_size64); size_t actual_size; if (!pMover) { void *new_p = vogl_realloc(m_p, desired_size, &actual_size); if (!new_p) { if (nofail) return false; char buf[256]; sprintf(buf, "%s: vogl_realloc() failed allocating %u bytes", VOGL_FUNCTION_INFO_CSTR, (uint32_t)desired_size); VOGL_FAIL(buf); } m_p = new_p; } else { void *new_p = vogl_malloc(desired_size, &actual_size); if (!new_p) { if (nofail) return false; char buf[256]; sprintf(buf, "%s: vogl_malloc() failed allocating %u bytes", VOGL_FUNCTION_INFO_CSTR, (uint32_t)desired_size); VOGL_FAIL(buf); } (*pMover)(new_p, m_p, m_size); if (m_p) vogl_free(m_p); m_p = new_p; } if (actual_size > desired_size) m_capacity = static_cast<uint32_t>(actual_size / element_size); else m_capacity = static_cast<uint32_t>(new_capacity); return true; }
// init_uuid() is slow (~40ms, maybe slower), and forces a disk flush on a file, so don't call it more than once. // I'm a paranoid nut so this hashes a bunch of shit. It's probably completely overkill for my needs - I should stop reading RFC's. static md5_hash init_uuid() { static uint64_t s_counter; // Get as much entropy as we can here const uint N = 2; void *p[N]; memset(p, 0, sizeof(p)); md5_hash_gen gen; timer_ticks tick_hist[N]; for (uint i = 0; i < N; i++) { uint64_t start_rdtsc = utils::RDTSC(); gen.update(start_rdtsc); gen.update(s_counter); gen.update((uint64_t) & s_counter); s_counter++; // Hash stack address of gen_uuid gen.update((uint64_t) & gen_uuid); // Hash the initial timer ticks, and time(NULL) gen.update(timer::get_init_ticks()); gen.update((uint64_t)time(NULL)); // Hash user ID, name, shell, home dir uid_t uid = geteuid(); gen.update(uid); struct passwd *pw = getpwuid(uid); gen.update((uint64_t) & pw); if (pw) { gen.update(pw, sizeof(struct passwd)); if (pw->pw_name) gen.update(pw->pw_name, vogl_strlen(pw->pw_name)); if (pw->pw_passwd) gen.update(pw->pw_passwd, vogl_strlen(pw->pw_passwd)); if (pw->pw_shell) gen.update(pw->pw_shell, vogl_strlen(pw->pw_shell)); if (pw->pw_dir) gen.update(pw->pw_dir, vogl_strlen(pw->pw_dir)); if (pw->pw_gecos) gen.update(pw->pw_gecos, vogl_strlen(pw->pw_gecos)); } uint8_vec buf; timer_ticks ticks = timer::get_ticks(); gen.update(ticks); // This is obviously expensive (and questionable?), only do it once. But it helps us get some entropy from the disk subsystem. // This is also by far the slowest component of this function (~35ms out of ~40ms). if (!i) { uint64_t st = utils::RDTSC(); timer tm; tm.start(); const char *pFilename = "!_!_!_!_!_!_!_vogl_temp!_!_!_!_!_!_!_!_.txt"; FILE *pFile = vogl_fopen(pFilename, "wb"); gen.update_obj_bits(pFile); if (pFile) { fwrite("X", 1, 1, pFile); fflush(pFile); fsync(fileno(pFile)); vogl_fclose(pFile); remove(pFilename); } uint64_t t = utils::RDTSC() - st; gen.update(t); tm.stop(); gen.update(tm.get_elapsed_ticks()); } // Grab some bits from /dev/urandom (not /dev/random - it may block for a long time) { const uint N = 64; char buf[N]; FILE *fp = vogl_fopen("/dev/urandom", "rb"); gen.update_obj_bits(fp); if (fp) { size_t n = fread(buf, 1, N, fp); VOGL_NOTE_UNUSED(n); vogl_fclose(fp); gen.update(buf, sizeof(buf)); } } // It's fine if some/most/all of these files don't exist, the true/false results get fed into the hash too. // TODO: Double check that all the files we should be able to read are actually getting read and hashed here. #define HASH_FILE(filename) \ do \ { \ bool success = cfile_stream::read_file_into_array(filename, buf); \ gen.update_obj_bits(success); \ gen.update(buf); \ } while (0) HASH_FILE("/proc/sys/kernel/random/entropy_avail"); HASH_FILE("/proc/self/statm"); HASH_FILE("/proc/self/mounts"); HASH_FILE("/proc/self/io"); HASH_FILE("/proc/self/smaps"); HASH_FILE("/proc/self/stack"); HASH_FILE("/proc/self/status"); HASH_FILE("/proc/self/maps"); HASH_FILE("/proc/self/stat"); HASH_FILE("/proc/self/stat"); HASH_FILE("/proc/cpuinfo"); HASH_FILE("/proc/meminfo"); HASH_FILE("/proc/stat"); HASH_FILE("/proc/misc"); HASH_FILE("/proc/swaps"); HASH_FILE("/proc/version"); HASH_FILE("/proc/loadavg"); HASH_FILE("/proc/interrupts"); HASH_FILE("/proc/ioports"); HASH_FILE("/proc/partitions"); HASH_FILE("/proc/driver/rtc"); HASH_FILE("/proc/self/net/wireless"); HASH_FILE("/proc/self/net/netstat"); HASH_FILE("/proc/self/net/netlink"); HASH_FILE("/sys/class/net/eth0/address"); HASH_FILE("/sys/class/net/eth1/address"); HASH_FILE("/sys/class/net/wlan0/address"); #undef HASH_FILE gen.update(utils::RDTSC()); // Hash thread, process ID's, etc. pid_t tid = (pid_t)syscall(SYS_gettid); gen.update_obj_bits(tid); pid_t pid = getpid(); gen.update_obj_bits(pid); pid = getppid(); gen.update_obj_bits(pid); gen.update((uint64_t) & pid); ticks -= timer::get_ticks(); tick_hist[i] = ticks; gen.update(ticks); ticks = timer::get_ticks(); // Get some entropy from the stack. char purposely_uninitialized_buf[256]; gen.update(purposely_uninitialized_buf, sizeof(purposely_uninitialized_buf)); // Get some entropy from the heap. p[i] = vogl_malloc(65536 * (i + 1)); gen.update_obj_bits(p[i]); if (p[i]) { for (uint j = 0; j < 16; j++) gen.update_obj_bits(reinterpret_cast<const uint64_t *>(p)[j]); } struct timeval tv; gettimeofday(&tv, NULL); gen.update_obj_bits(tv); // Hash the current environment uint e = 0; while (environ[e]) { gen.update(environ[e], vogl_strlen(environ[e])); ++e; } uint64_t s = utils::RDTSC(); // Try to get some entropy from the scheduler. vogl_sleep(2); gen.update(utils::RDTSC() - s); ticks -= timer::get_ticks(); gen.update(ticks); gen.update(utils::RDTSC() - start_rdtsc); } for (uint i = 1; i < N; i++) { uint64_t t = tick_hist[i] - tick_hist[i - 1]; gen.update(t); } for (uint i = 0; i < N; i++) vogl_free(p[i]); return gen.finalize(); }