void ExecutablePool::systemRelease(const ExecutablePool::Allocation& allocation) { SpinLockHolder lock_holder(&spinlock); ASSERT(allocator); allocator->free(allocation.pages, allocation.size); }
bool ExecutableAllocator::isValid() const { SpinLockHolder lock_holder(&spinlock); if (!allocator) allocator = new FixedVMPoolAllocator(JIT_ALLOCATOR_LARGE_ALLOC_SIZE, VM_POOL_SIZE); return allocator->isValid(); }
ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size) { SpinLockHolder lock_holder(&spinlock); if (!allocator) allocator = new FixedVMPoolAllocator(JIT_ALLOCATOR_LARGE_ALLOC_SIZE, VM_POOL_SIZE); ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(allocator->alloc(size)), size}; return alloc; }
void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size, size_t alignment) { // Discard requests that overflow if (size + alignment < size) return NULL; SpinLockHolder lock_holder(&spinlock); // Enforce minimum alignment if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner); // Try twice, once avoiding allocators that failed before, and once // more trying all allocators even if they failed before. for (int i = 0; i < 2; i++) { #ifndef WTF_CHANGES if (use_devmem && !devmem_failure) { void* result = TryDevMem(size, actual_size, alignment); if (result != NULL) return result; } #endif #if HAVE(SBRK) if (use_sbrk && !sbrk_failure) { void* result = TrySbrk(size, actual_size, alignment); if (result != NULL) return result; } #endif #if HAVE(MMAP) if (use_mmap && !mmap_failure) { void* result = TryMmap(size, actual_size, alignment); if (result != NULL) return result; } #endif #if HAVE(VIRTUALALLOC) if (use_VirtualAlloc && !VirtualAlloc_failure) { void* result = TryVirtualAlloc(size, actual_size, alignment); if (result != NULL) return result; } #endif // nothing worked - reset failure flags and try again devmem_failure = false; sbrk_failure = false; mmap_failure = false; VirtualAlloc_failure = false; } return NULL; }
void* TCMalloc_SystemAlloc(size_t size, size_t alignment) { #ifndef WTF_CHANGES if (TCMallocDebug::level >= TCMallocDebug::kVerbose) { MESSAGE("TCMalloc_SystemAlloc(%" PRIuS ", %" PRIuS")\n", size, alignment); } #endif SpinLockHolder lock_holder(&spinlock); // Enforce minimum alignment if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner); // Try twice, once avoiding allocators that failed before, and once // more trying all allocators even if they failed before. for (int i = 0; i < 2; i++) { #ifndef WTF_CHANGES if (use_devmem && !devmem_failure) { void* result = TryDevMem(size, alignment); if (result != NULL) return result; } #endif #if HAVE(SBRK) if (use_sbrk && !sbrk_failure) { void* result = TrySbrk(size, alignment); if (result != NULL) return result; } #endif #if HAVE(MMAP) if (use_mmap && !mmap_failure) { void* result = TryMmap(size, alignment); if (result != NULL) return result; } #endif // nothing worked - reset failure flags and try again devmem_failure = false; sbrk_failure = false; mmap_failure = false; } return NULL; }
int check_active_psus() { int error = 0; lock_holder(worldlock, &world.lock); lock_take(worldlock); if (world.paused == 1) { usleep(1000); goto cleanup; } if (world.config == NULL) { lock_release(worldlock); usleep(5000); goto cleanup; } world.num_active_addrs = 0; scanning = 1; //fprintf(stderr, "Begin presence check: "); for(int rack = 0; rack < 3; rack++) { for(int shelf = 0; shelf < 2; shelf++) { for(int psu = 0; psu < 3; psu++) { char addr = psu_address(rack, shelf, psu); uint16_t status = 0; int err = read_registers(&world.rs485, world.modbus_timeout, addr, REGISTER_PSU_STATUS, 1, &status); if (err == 0) { world.active_addrs[world.num_active_addrs] = addr; world.num_active_addrs++; //fprintf(stderr, "%02x - active (%04x) ", addr, status); } else { dbg("%02x - %d; ", addr, err); } } } } //its the only stdlib sort qsort(world.active_addrs, world.num_active_addrs, sizeof(uint8_t), sub_uint8s); cleanup: scanning = 0; lock_release(worldlock); return error; }
int modbus_command(rs485_dev* dev, int timeout, char* command, size_t len, char* destbuf, size_t dest_limit, size_t expect) { int error = 0; lock_holder(devlock, &dev->lock); modbus_req req; req.tty_fd = dev->tty_fd; req.gpio_fd = dev->gpio_fd; req.modbus_cmd = command; req.cmd_len = len; req.dest_buf = destbuf; req.dest_limit = dest_limit; req.timeout = timeout; req.expected_len = expect != 0 ? expect : dest_limit; req.scan = scanning; lock_take(devlock); int cmd_error = modbuscmd(&req); CHECK(cmd_error); cleanup: lock_release(devlock); if (error >= 0) { return req.dest_len; } return error; }
ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size) { SpinLockHolder lock_holder(&spinlock); ASSERT(allocator); return allocator->alloc(size); }
int do_command(int sock, rackmond_command* cmd) { int error = 0; lock_holder(worldlock, &world.lock); switch(cmd->type) { case COMMAND_TYPE_RAW_MODBUS: { uint16_t expected = cmd->raw_modbus.expected_response_length; int timeout = world.modbus_timeout; if (cmd->raw_modbus.custom_timeout) { //ms to us timeout = cmd->raw_modbus.custom_timeout * 1000; } if (expected == 0) { expected = 1024; } char response[expected]; int response_len = modbus_command( &world.rs485, timeout, cmd->raw_modbus.data, cmd->raw_modbus.length, response, expected, expected); uint16_t response_len_wire = response_len; if(response_len < 0) { uint16_t error = -response_len; response_len_wire = 0; send(sock, &response_len_wire, sizeof(uint16_t), 0); send(sock, &error, sizeof(uint16_t), 0); break; } send(sock, &response_len_wire, sizeof(uint16_t), 0); send(sock, response, response_len, 0); break; } case COMMAND_TYPE_SET_CONFIG: { lock_take(worldlock); if (world.config != NULL) { BAIL("rackmond already configured\n"); } size_t config_size = sizeof(monitoring_config) + (sizeof(monitor_interval) * cmd->set_config.config.num_intervals); world.config = calloc(1, config_size); memcpy(world.config, &cmd->set_config.config, config_size); syslog(LOG_INFO, "got configuration"); lock_release(worldlock); break; } case COMMAND_TYPE_DUMP_DATA_JSON: { lock_take(worldlock); if (world.config == NULL) { send(sock, "[]", 2, 0); } else { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); uint32_t now = ts.tv_sec; send(sock, "[", 1, 0); int data_pos = 0; while(world.stored_data[data_pos] != NULL && data_pos < MAX_ACTIVE_ADDRS) { dprintf(sock, "{\"addr\":%d,\"now\":%d,\"ranges\":[", world.stored_data[data_pos]->addr, now); for(int i = 0; i < world.config->num_intervals; i++) { uint32_t time; register_range_data *rd = &world.stored_data[data_pos]->range_data[i]; char* mem_pos = rd->mem_begin; dprintf(sock,"{\"begin\":%d,\"readings\":[", rd->i->begin); // want to cut the list off early just before // the first entry with time == 0 memcpy(&time, mem_pos, sizeof(time)); for(int j = 0; j < rd->i->keep && time != 0; j++) { mem_pos += sizeof(time); dprintf(sock, "{\"time\":%d,\"data\":\"", time); for(int c = 0; c < rd->i->len * 2; c++) { dprintf(sock, "%02x", *mem_pos); mem_pos++; } send(sock, "\"}", 2, 0); memcpy(&time, mem_pos, sizeof(time)); if (time == 0) { break; } if ((j+1) < rd->i->keep) { send(sock, ",", 1, 0); } } send(sock, "]}", 2, 0); if ((i+1) < world.config->num_intervals) { send(sock, ",", 1, 0); } } data_pos++; if (data_pos < MAX_ACTIVE_ADDRS && world.stored_data[data_pos] != NULL) { send(sock, "]},", 3, 0); } else { send(sock, "]}", 2, 0); } } send(sock, "]", 1, 0); } lock_release(worldlock); break; } case COMMAND_TYPE_PAUSE_MONITORING: { lock_take(worldlock); uint8_t was_paused = world.paused; world.paused = 1; send(sock, &was_paused, sizeof(was_paused), 0); lock_release(worldlock); break; } case COMMAND_TYPE_START_MONITORING: { lock_take(worldlock); uint8_t was_started = !world.paused; world.paused = 0; send(sock, &was_started, sizeof(was_started), 0); lock_release(worldlock); break; } default: CHECK(-1); } cleanup: lock_release(worldlock); return error; }
int fetch_monitored_data() { int error = 0; int data_pos = 0; lock_holder(worldlock, &world.lock); lock_take(worldlock); if (world.paused == 1) { usleep(1000); goto cleanup; } if (world.config == NULL) { goto cleanup; } lock_release(worldlock); usleep(1000); // wait a sec btween PSUs to not overload RT scheduling // threshold while(world.stored_data[data_pos] != NULL && data_pos < MAX_ACTIVE_ADDRS) { uint8_t addr = world.stored_data[data_pos]->addr; //log("readpsu %02x\n", addr); for(int r = 0; r < world.config->num_intervals; r++) { register_range_data* rd = &world.stored_data[data_pos]->range_data[r]; monitor_interval* i = rd->i; uint16_t regs[i->len]; int err = read_registers(&world.rs485, world.modbus_timeout, addr, i->begin, i->len, regs); if (err) { log("Error %d reading %02x registers at %02x from %02x\n", err, i->len, i->begin, addr); continue; } struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); uint32_t timestamp = ts.tv_sec; if (rd->i->flags & MONITOR_FLAG_ONLY_CHANGES) { int pitch = sizeof(timestamp) + (sizeof(uint16_t) * i->len); int lastpos = rd->mem_pos - pitch; if (lastpos < 0) { lastpos = (pitch * rd->i->keep) - pitch; } if (!memcmp(rd->mem_begin + lastpos + sizeof(timestamp), regs, sizeof(uint16_t) * i->len) && memcmp(rd->mem_begin, "\x00\x00\x00\x00", 4)) { continue; } if (world.status_log) { time_t rawt; struct tm* ti; time(&rawt); ti = localtime(&rawt); char timestr[80]; strftime(timestr, sizeof(timestr), "%b %e %T", ti); fprintf(world.status_log, "%s: Change to status register %02x on address %02x. New value: %02x\n", timestr, i->begin, addr, regs[0]); fflush(world.status_log); } } lock_take(worldlock); record_data(rd, timestamp, regs); lock_release(worldlock); } data_pos++; } cleanup: lock_release(worldlock); return error; }