int apdb_append_data(apdb_t* db, const void* content, size_t length) { assert(NULL != db && (ADD == db->action || UPDATE == db->action) && CAN_WRITE(db) && db->next_length - db->next_written >= length); assert(db->index_file_len <= db->index_mmap_len); if (db->error) { db->action = NONE; return -1; } ERROR_IF(db->next_length - db->next_written < length, "write more data than expected"); ERRORP_IF((ssize_t)length != writen(db->data_fd, content, length), "failed to write"); db->data_file_len += length; db->next_written += length; return 0; L_error: db->error = -1; db->action = NONE; return -1; }
apdb_record_t apdb_add_end(apdb_t* db, const void* content) { index_t index, *indexp; int content_len; assert(NULL != db && ADD == db->action && CAN_WRITE(db) && db->next_length == db->next_written); assert(db->index_file_len <= db->index_mmap_len); db->action = NONE; if (db->error) return -1; ERROR_IF(db->next_length != db->next_written, "write less data than expected"); pad_data_file(db); if (db->error) return -1; index.guard = GUARD; index.flags = WRITING; index.id = db->next_id; index.length = db->next_length + sizeof(data_t); index.offset = db->next_offset; ERRORP_IF(sizeof(index_t) != writen(db->index_fd, &index, sizeof(index_t)), "failed to write"); content_len = db->index_len - sizeof(index_t); ERRORP_IF(content_len != writen(db->index_fd, content, content_len), "failed to write index content"); db->index_file_len += db->index_len; remap_index_file(db, SIZE_MAX); if (db->error) return -1; indexp = RECORD_TO_INDEX(db, db->index_file_len - db->index_len); assert(GUARD == indexp->guard && WRITING == indexp->flags && index.id == indexp->id && index.length == indexp->length && index.offset == indexp->offset); indexp->flags = 0; return INDEX_TO_RECORD(db, indexp); L_error: db->error = -1; return -1; }
bool brw_validate_instructions(const struct brw_codegen *p, int start_offset, struct annotation_info *annotation) { const struct brw_device_info *devinfo = p->devinfo; const void *store = p->store + start_offset / 16; bool valid = true; for (int src_offset = 0; src_offset < p->next_insn_offset - start_offset; src_offset += sizeof(brw_inst)) { struct string error_msg = { .str = NULL, .len = 0 }; const brw_inst *inst = store + src_offset; switch (num_sources_from_inst(devinfo, inst)) { case 3: /* Nothing to test. 3-src instructions can only have GRF sources, and * there's no bit to control the file. */ break; case 2: ERROR_IF(src1_is_null(devinfo, inst), "src1 is null"); /* fallthrough */ case 1: ERROR_IF(src0_is_null(devinfo, inst), "src0 is null"); break; case 0: default: break; } ERROR_IF(is_unsupported_inst(devinfo, inst), "Instruction not supported on this Gen"); if (error_msg.str && annotation) { annotation_insert_error(annotation, src_offset, error_msg.str); } free(error_msg.str); } return valid; }
MemoryManager::MemoryBlockHeader* MemoryManager::_PullBlock(int32 freeListHandle) { MemoryManager::MemoryBlockHeader *freeBlock = m_freeListHeads[freeListHandle]; MemoryManager::MemoryBlockHeader *next = freeBlock->m_next; m_freeListHeads[freeListHandle] = next; ERROR_IF(!freeBlock, "Invalid memory block handle \n"); return freeBlock; }
bool brw_validate_instructions(const struct brw_codegen *p, int start_offset, struct annotation_info *annotation) { const struct brw_device_info *devinfo = p->devinfo; const void *store = p->store + start_offset / 16; bool valid = true; for (int src_offset = 0; src_offset < p->next_insn_offset - start_offset; src_offset += sizeof(brw_inst)) { struct string error_msg = { .str = NULL, .len = 0 }; const brw_inst *inst = store + src_offset; switch (num_sources_from_inst(devinfo, inst)) { case 3: /* Nothing to test. 3-src instructions can only have GRF sources, and * there's no bit to control the file. */ break; case 2: ERROR_IF(src1_is_null(devinfo, inst), "src1 is null"); /* fallthrough */ case 1: ERROR_IF(src0_is_null(devinfo, inst), "src0 is null"); break; case 0: default: break; } ERROR_IF(is_unsupported_inst(devinfo, inst), "Instruction not supported on this Gen"); if (brw_inst_opcode(devinfo, inst) == BRW_OPCODE_SEND) { ERROR_IF(brw_inst_src0_address_mode(devinfo, inst) != BRW_ADDRESS_DIRECT, "send must use direct addressing"); if (devinfo->gen >= 7) { ERROR_IF(!src0_is_grf(devinfo, inst), "send from non-GRF"); ERROR_IF(brw_inst_eot(devinfo, inst) && brw_inst_src0_da_reg_nr(devinfo, inst) < 112, "send with EOT must use g112-g127"); } } if (error_msg.str && annotation) { annotation_insert_error(annotation, src_offset, error_msg.str); } free(error_msg.str); } return valid; }
void MemoryManager::Delete(void *memory) { LOCK_GAURD_MUTEX(m_masterLock); MemoryBlockHeader *header = (MemoryBlockHeader *)((char *)memory - sizeof(MemoryBlockHeader)); if (header->m_padding == MAX_ALLOCATION_SIZE) { VirtualFree(header, NULL, MEM_RELEASE); return; } ERROR_IF(!header->m_allocated, "Memory block is not allocated \n"); int32 freeListHandle = header->m_logPow2; _AddBlock(freeListHandle, header); _RecordFree(header); }
int apdb_update_end(apdb_t* db, void* content) { index_t* index; assert(NULL != db && UPDATE == db->action && CAN_WRITE(db)); assert(db->index_file_len <= db->index_mmap_len); db->action = NONE; if (db->error) return -1; ERROR_IF(db->next_length != db->next_written, "write less data than expected"); pad_data_file(db); if (db->error) return -1; index = RECORD_TO_INDEX(db, db->next_record); assert(GUARD == index->guard); index->flags |= WRITING; index->length = sizeof(data_t); /* make reader processes read nothing */ index->offset = db->next_offset; if (NULL != content) memcpy(index->content, content, db->index_len - sizeof(index_t)); index->length += db->next_length; index->flags &= ~WRITING; return 0; L_error: db->error = -1; return -1; }
/** * get next available id, 0 <= id < UINT_MAX * * @param db pointer to a database instance * * @return UINT_MAX on error, next id on success * * @note This function can only be called by writer process * because only it knows the real last record. */ static unsigned get_next_id(apdb_t* db) { unsigned count; index_t* index; assert(NULL != db && CAN_WRITE(db)); assert(db->index_file_len <= db->index_mmap_len); if (0 == db->index_file_len) return 0; count = db->index_file_len / db->index_len; index = RECORD_TO_INDEX(db, (count - 1) * db->index_len); ERROR_IF(GUARD != index->guard || UINT_MAX == index->id, "corrupted index"); return index->id + 1; L_error: db->error = -1; return UINT_MAX; }
static av_cold int aac_encode_init(AVCodecContext *avctx) { AACEncContext *s = avctx->priv_data; int i, ret = 0; const uint8_t *sizes[2]; uint8_t grouping[AAC_MAX_CHANNELS]; int lengths[2]; s->channels = avctx->channels; s->chan_map = aac_chan_configs[s->channels-1]; s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120; s->last_frame_pb_count = 0; avctx->extradata_size = 5; avctx->frame_size = 1024; avctx->initial_padding = 1024; avctx->bit_rate = (int)FFMIN( 6144 * s->channels / 1024.0 * avctx->sample_rate, avctx->bit_rate); avctx->profile = avctx->profile == FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW : avctx->profile; for (i = 0; i < 16; i++) if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i]) break; s->samplerate_index = i; ERROR_IF(s->samplerate_index == 16 || s->samplerate_index >= ff_aac_swb_size_1024_len || s->samplerate_index >= ff_aac_swb_size_128_len, "Unsupported sample rate %d\n", avctx->sample_rate); ERROR_IF(s->channels > AAC_MAX_CHANNELS || s->channels == 7, "Unsupported number of channels: %d\n", s->channels); WARN_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels, "Too many bits %f > %d per frame requested, clamping to max\n", 1024.0 * avctx->bit_rate / avctx->sample_rate, 6144 * s->channels); for (i = 0; i < FF_ARRAY_ELEMS(aacenc_profiles); i++) if (avctx->profile == aacenc_profiles[i]) break; ERROR_IF(i == FF_ARRAY_ELEMS(aacenc_profiles), "Unsupported encoding profile: %d\n", avctx->profile); if (avctx->profile == FF_PROFILE_MPEG2_AAC_LOW) { avctx->profile = FF_PROFILE_AAC_LOW; ERROR_IF(s->options.pred, "Main prediction unavailable in the \"mpeg2_aac_low\" profile\n"); ERROR_IF(s->options.ltp, "LTP prediction unavailable in the \"mpeg2_aac_low\" profile\n"); WARN_IF(s->options.pns, "PNS unavailable in the \"mpeg2_aac_low\" profile, turning off\n"); s->options.pns = 0; } else if (avctx->profile == FF_PROFILE_AAC_LTP) { s->options.ltp = 1; ERROR_IF(s->options.pred, "Main prediction unavailable in the \"aac_ltp\" profile\n"); } else if (avctx->profile == FF_PROFILE_AAC_MAIN) { s->options.pred = 1; ERROR_IF(s->options.ltp, "LTP prediction unavailable in the \"aac_main\" profile\n"); } else if (s->options.ltp) { avctx->profile = FF_PROFILE_AAC_LTP; WARN_IF(1, "Chainging profile to \"aac_ltp\"\n"); ERROR_IF(s->options.pred, "Main prediction unavailable in the \"aac_ltp\" profile\n"); } else if (s->options.pred) { avctx->profile = FF_PROFILE_AAC_MAIN; WARN_IF(1, "Chainging profile to \"aac_main\"\n"); ERROR_IF(s->options.ltp, "LTP prediction unavailable in the \"aac_main\" profile\n"); } s->profile = avctx->profile; s->coder = &ff_aac_coders[s->options.coder]; if (s->options.coder != AAC_CODER_TWOLOOP) { ERROR_IF(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL, "Coders other than twoloop require -strict -2 and some may be removed in the future\n"); WARN_IF(s->options.coder == AAC_CODER_FAAC, "The FAAC-like coder will be removed in the near future, please use twoloop!\n"); s->options.intensity_stereo = 0; s->options.pns = 0; } if ((ret = dsp_init(avctx, s)) < 0) goto fail; if ((ret = alloc_buffers(avctx, s)) < 0) goto fail; put_audio_specific_config(avctx); sizes[0] = ff_aac_swb_size_1024[s->samplerate_index]; sizes[1] = ff_aac_swb_size_128[s->samplerate_index]; lengths[0] = ff_aac_num_swb_1024[s->samplerate_index]; lengths[1] = ff_aac_num_swb_128[s->samplerate_index]; for (i = 0; i < s->chan_map[0]; i++) grouping[i] = s->chan_map[i + 1] == TYPE_CPE; if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping)) < 0) goto fail; s->psypp = ff_psy_preprocess_init(avctx); ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON); av_lfg_init(&s->lfg, 0x72adca55); if (HAVE_MIPSDSP) ff_aac_coder_init_mips(s); if ((ret = ff_thread_once(&aac_table_init, &aac_encode_init_tables)) != 0) return AVERROR_UNKNOWN; ff_af_queue_init(avctx, &s->afq); return 0; fail: aac_encode_end(avctx); return ret; }
static av_cold int aac_encode_init(AVCodecContext *avctx) { AACEncContext *s = avctx->priv_data; int i, ret = 0; const uint8_t *sizes[2]; uint8_t grouping[AAC_MAX_CHANNELS]; int lengths[2]; avctx->frame_size = 1024; for (i = 0; i < 16; i++) if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i]) break; s->channels = avctx->channels; ERROR_IF(i == 16, "Unsupported sample rate %d\n", avctx->sample_rate); ERROR_IF(s->channels > AAC_MAX_CHANNELS, "Unsupported number of channels: %d\n", s->channels); ERROR_IF(avctx->profile != FF_PROFILE_UNKNOWN && avctx->profile != FF_PROFILE_AAC_LOW, "Unsupported profile %d\n", avctx->profile); ERROR_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels, "Too many bits per frame requested\n"); s->samplerate_index = i; s->chan_map = aac_chan_configs[s->channels-1]; if (ret = dsp_init(avctx, s)) goto fail; if (ret = alloc_buffers(avctx, s)) goto fail; avctx->extradata_size = 5; put_audio_specific_config(avctx); sizes[0] = swb_size_1024[i]; sizes[1] = swb_size_128[i]; lengths[0] = ff_aac_num_swb_1024[i]; lengths[1] = ff_aac_num_swb_128[i]; for (i = 0; i < s->chan_map[0]; i++) grouping[i] = s->chan_map[i + 1] == TYPE_CPE; if (ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping)) goto fail; s->psypp = ff_psy_preprocess_init(avctx); s->coder = &ff_aac_coders[s->options.aac_coder]; if (HAVE_MIPSDSPR1) ff_aac_coder_init_mips(s); s->lambda = avctx->global_quality ? avctx->global_quality : 120; ff_aac_tableinit(); for (i = 0; i < 428; i++) ff_aac_pow34sf_tab[i] = sqrt(ff_aac_pow2sf_tab[i] * sqrt(ff_aac_pow2sf_tab[i])); avctx->delay = 1024; ff_af_queue_init(avctx, &s->afq); return 0; fail: aac_encode_end(avctx); return ret; }
static av_cold int aac_encode_init(AVCodecContext *avctx) { AACEncContext *s = avctx->priv_data; int i, ret = 0; const uint8_t *sizes[2]; uint8_t grouping[AAC_MAX_CHANNELS]; int lengths[2]; /* Constants */ s->last_frame_pb_count = 0; avctx->extradata_size = 5; avctx->frame_size = 1024; avctx->initial_padding = 1024; s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120; /* Channel map and unspecified bitrate guessing */ s->channels = avctx->channels; ERROR_IF(s->channels > AAC_MAX_CHANNELS || s->channels == 7, "Unsupported number of channels: %d\n", s->channels); s->chan_map = aac_chan_configs[s->channels-1]; if (!avctx->bit_rate) { for (i = 1; i <= s->chan_map[0]; i++) { avctx->bit_rate += s->chan_map[i] == TYPE_CPE ? 128000 : /* Pair */ s->chan_map[i] == TYPE_LFE ? 16000 : /* LFE */ 69000 ; /* SCE */ } } /* Samplerate */ for (i = 0; i < 16; i++) if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i]) break; s->samplerate_index = i; ERROR_IF(s->samplerate_index == 16 || s->samplerate_index >= ff_aac_swb_size_1024_len || s->samplerate_index >= ff_aac_swb_size_128_len, "Unsupported sample rate %d\n", avctx->sample_rate); /* Bitrate limiting */ WARN_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels, "Too many bits %f > %d per frame requested, clamping to max\n", 1024.0 * avctx->bit_rate / avctx->sample_rate, 6144 * s->channels); avctx->bit_rate = (int64_t)FFMIN(6144 * s->channels / 1024.0 * avctx->sample_rate, avctx->bit_rate); /* Profile and option setting */ avctx->profile = avctx->profile == FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW : avctx->profile; for (i = 0; i < FF_ARRAY_ELEMS(aacenc_profiles); i++) if (avctx->profile == aacenc_profiles[i]) break; if (avctx->profile == FF_PROFILE_MPEG2_AAC_LOW) { avctx->profile = FF_PROFILE_AAC_LOW; ERROR_IF(s->options.pred, "Main prediction unavailable in the \"mpeg2_aac_low\" profile\n"); ERROR_IF(s->options.ltp, "LTP prediction unavailable in the \"mpeg2_aac_low\" profile\n"); WARN_IF(s->options.pns, "PNS unavailable in the \"mpeg2_aac_low\" profile, turning off\n"); s->options.pns = 0; } else if (avctx->profile == FF_PROFILE_AAC_LTP) { s->options.ltp = 1; ERROR_IF(s->options.pred, "Main prediction unavailable in the \"aac_ltp\" profile\n"); } else if (avctx->profile == FF_PROFILE_AAC_MAIN) { s->options.pred = 1; ERROR_IF(s->options.ltp, "LTP prediction unavailable in the \"aac_main\" profile\n"); } else if (s->options.ltp) { avctx->profile = FF_PROFILE_AAC_LTP; WARN_IF(1, "Chainging profile to \"aac_ltp\"\n"); ERROR_IF(s->options.pred, "Main prediction unavailable in the \"aac_ltp\" profile\n"); } else if (s->options.pred) { avctx->profile = FF_PROFILE_AAC_MAIN; WARN_IF(1, "Chainging profile to \"aac_main\"\n"); ERROR_IF(s->options.ltp, "LTP prediction unavailable in the \"aac_main\" profile\n"); } s->profile = avctx->profile; /* Coder limitations */ s->coder = &ff_aac_coders[s->options.coder]; if (s->options.coder == AAC_CODER_ANMR) { ERROR_IF(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL, "The ANMR coder is considered experimental, add -strict -2 to enable!\n"); s->options.intensity_stereo = 0; s->options.pns = 0; } ERROR_IF(s->options.ltp && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL, "The LPT profile requires experimental compliance, add -strict -2 to enable!\n"); /* M/S introduces horrible artifacts with multichannel files, this is temporary */ if (s->channels > 3) s->options.mid_side = 0; if ((ret = dsp_init(avctx, s)) < 0) goto fail; if ((ret = alloc_buffers(avctx, s)) < 0) goto fail; put_audio_specific_config(avctx); sizes[0] = ff_aac_swb_size_1024[s->samplerate_index]; sizes[1] = ff_aac_swb_size_128[s->samplerate_index]; lengths[0] = ff_aac_num_swb_1024[s->samplerate_index]; lengths[1] = ff_aac_num_swb_128[s->samplerate_index]; for (i = 0; i < s->chan_map[0]; i++) grouping[i] = s->chan_map[i + 1] == TYPE_CPE; if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping)) < 0) goto fail; s->psypp = ff_psy_preprocess_init(avctx); ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON); s->random_state = 0x1f2e3d4c; s->abs_pow34 = abs_pow34_v; s->quant_bands = quantize_bands; if (ARCH_X86) ff_aac_dsp_init_x86(s); if (HAVE_MIPSDSP) ff_aac_coder_init_mips(s); if ((ret = ff_thread_once(&aac_table_init, &aac_encode_init_tables)) != 0) return AVERROR_UNKNOWN; ff_af_queue_init(avctx, &s->afq); return 0; fail: aac_encode_end(avctx); return ret; }
void* MemoryManager::Allocate(int32 allocationSize) { LOCK_GAURD_MUTEX(m_masterLock); if (allocationSize >= MAX_ALLOCATION_SIZE) { int sizePlusHeader = allocationSize + sizeof(MemoryBlockHeader); MemoryBlockHeader *bigAssAlloc = (MemoryBlockHeader *)VirtualAlloc(NULL, sizePlusHeader, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ERROR_IF(!bigAssAlloc, "BigAssAlloc of size %i failed", sizePlusHeader); bigAssAlloc->m_padding = MAX_ALLOCATION_SIZE; void *userMemory = (void*)((char*)bigAssAlloc + sizeof(MemoryBlockHeader)); return userMemory; } allocationSize += sizeof(MemoryBlockHeader); Pow2Result pow2 = _CalculatePow2(allocationSize); if (pow2.m_pow2 < allocationSize) { pow2.m_pow2 *= 2; pow2.m_logPow2++; } int32 freeListIter = pow2.m_logPow2; MemoryBlockHeader *freeList = m_freeListHeads[freeListIter]; bool freeListEmpty = false; if (!freeList) { freeListEmpty = true; } MemoryBlockHeader *memory = NULL; // List of size does not exist if (freeListEmpty) { int32 newMemoryHandle = m_underlyingMemory.Allocate(pow2.m_pow2); // Initialize memory memory = m_underlyingMemory.Get<MemoryBlockHeader>(newMemoryHandle); memory->m_logPow2 = pow2.m_logPow2; memory->m_next = NULL; } else { MemoryBlockHeader *freeMemoryBlock = _PullBlock(freeListIter); if(freeMemoryBlock->m_logPow2 != pow2.m_logPow2) std::cout << "Memory block not correct power of 2: " << freeMemoryBlock->m_logPow2 << std::endl; if(freeMemoryBlock->m_allocated) std::cout << "Memory block is allocated" << std::endl; // Initialize memory memory = freeMemoryBlock; memory->m_logPow2 = pow2.m_logPow2; memory->m_next = NULL; } _RecordAllocation(memory); int sizeOfHeader = sizeof(MemoryBlockHeader); void *userMemory = (void*)((char*)memory + sizeof(MemoryBlockHeader)); return userMemory; }
apdb_t* apdb_open(const char* path, char mode, size_t index_content_len) { int readonly; apdb_t* db; char* fullpath; size_t len; struct stat st; assert(NULL != path); /* * initialize apdb_t */ db = (apdb_t*)malloc(sizeof(apdb_t)); if (NULL == db) return NULL; db->data_fd = db->index_fd = -1; db->data_mmap = db->index_mmap = MAP_FAILED; db->index_len = sizeof(index_t) + index_content_len; db->error = 0; db->action = NONE; db->next_id = UINT_MAX; db->next_length = 0; db->next_offset = UINT_MAX; /* * open data file and index file */ len = strlen(path); fullpath = (char*)malloc(len + 3); ERRORP_IF(NULL == fullpath, "failed to malloc for fullpath"); memcpy(fullpath, path, len); fullpath[len++] = '.'; fullpath[len++] = 'd'; fullpath[len++] = '\0'; readonly = 'r' == mode; if (readonly) { int flags = O_RDONLY | O_NOATIME; db->data_fd = open(fullpath, flags); ERRORP_IF(-1 == db->data_fd, "failed to open %s readonly", fullpath); fullpath[len - 2] = 'i'; db->index_fd = open(fullpath, flags); ERRORP_IF(-1 == db->index_fd, "failed to open %s readonly", fullpath); db->prot = PROT_READ; } else { #ifdef O_CLOEXEC int flags = O_RDWR | O_APPEND | O_CREAT | O_NOATIME | O_CLOEXEC; #else int flags = O_RDWR | O_APPEND | O_CREAT | O_NOATIME; #endif db->data_fd = open(fullpath, flags, 0644); ERRORP_IF(-1 == db->data_fd, "failed to open %s readwrite", fullpath); ERRORP_IF(-1 == flock(db->data_fd, LOCK_EX | LOCK_NB), "failed to lock data file"); fullpath[len - 2] = 'i'; db->index_fd = open(fullpath, flags, 0644); ERRORP_IF(-1 == db->index_fd, "failed to open %s readwrite", fullpath); ERRORP_IF(-1 == flock(db->index_fd, LOCK_EX | LOCK_NB), "failed to lock index file"); db->prot = PROT_READ | PROT_WRITE; } free(fullpath); fullpath = NULL; /* * mmap data file */ ERRORP_IF(-1 == fstat(db->data_fd, &st), "failed to stat data file"); db->data_mmap_len = st.st_size + DATA_EXPAND_SIZE; db->data_mmap = mmap(NULL, db->data_mmap_len, PROT_READ, MAP_SHARED, db->data_fd, 0); ERRORP_IF(MAP_FAILED == db->data_mmap, "failed to mmap data file"); db->data_file_len = st.st_size; /* * check data file */ if (st.st_size > 0) { data_t* data; ERROR_IF(st.st_size < (off_t)sizeof(data_t), "corrupted data file"); data = (data_t*)db->data_mmap; ERROR_IF(GUARD != data->guard || 0 != data->id || st.st_size < (off_t)ALIGN_UP(sizeof(data_t) + data->length, ALIGN_SIZE), "corrupted header record"); } /* * mmap index file */ ERRORP_IF(-1 == fstat(db->index_fd, &st), "failed to stat index file"); db->index_mmap_len = st.st_size + INDEX_EXPAND_SIZE; db->index_mmap = mmap(NULL, db->index_mmap_len, db->prot, MAP_SHARED, db->index_fd, 0); ERRORP_IF(MAP_FAILED == db->index_mmap, "failed to mmap index file"); db->index_file_len = st.st_size; /* * check index file */ if (st.st_size > 0) { index_t* index; unsigned count; ERROR_IF(st.st_size < (off_t)db->index_len, "corrupted index file"); index = RECORD_TO_INDEX(db, 0); ERROR_IF(GUARD != index->guard || 0 != index->id || 0 != index->offset, "corrupted header index"); /* * only one writer process, so there shouldn't be any partially * written index */ ERROR_IF(!readonly && (st.st_size % db->index_len) != 0, "found partially written index"); /* * check last index */ count = st.st_size / db->index_len; index = RECORD_TO_INDEX(db, (count - 1) * db->index_len); ERROR_IF(GUARD != index->guard, "corrupted tailer index"); ERROR_IF(db->data_file_len < ALIGN_UP(index->offset + index->length, ALIGN_SIZE), "corrupted tailer record"); } /* * unmap data file to reduce virtual address space usage */ ERRORP_IF(-1 == munmap(db->data_mmap, db->data_mmap_len), "failed to munmap data file"); db->data_mmap = MAP_FAILED; db->data_mmap_len = 0; #ifndef O_CLOEXEC /* * avoid forked writer child processes writing data and index file */ if (! readonly) { long flags; flags = fcntl(db->data_fd, F_GETFD); flags |= FD_CLOEXEC; ERRORP_IF(-1 == fcntl(db->data_fd, F_SETFD, flags), "failed to set FD_CLOEXEC on data_fd"); flags = fcntl(db->index_fd, F_GETFD); flags |= FD_CLOEXEC; ERRORP_IF(-1 == fcntl(db->index_fd, F_SETFD, flags), "failed to set FD_CLOEXEC on index_fd"); } #endif return db; L_error: if (NULL != fullpath) free(fullpath); apdb_close(db); return NULL; }