Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
  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;
  }
Beispiel #5
0
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;
}
Beispiel #6
0
  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);
  }
Beispiel #7
0
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;
}
Beispiel #8
0
/**
 * 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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
  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;
  }
Beispiel #13
0
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;
}