Ejemplo n.º 1
0
/**
 * Determine the space required for a correctly aligned array of fatbit
 * structure, laid out as:
 *
 * - an array of num_entries pointers, each to a fatbit.
 * - an array of fatbit structures, each of size fatbit_size(num_keys).
 */
static
size_t fatbit_array_size(u32 num_entries, u32 num_keys) {
    size_t len = 0;

    // Array of pointers to each fatbit entry.
    len += sizeof(struct fatbit *) * num_entries;

    // Fatbit entries themselves.
    len = ROUNDUP_N(len, alignof(struct fatbit));
    len += (size_t)fatbit_size(num_keys) * num_entries;

    return ROUNDUP_N(len, 8); // Round up for potential padding.
}
Ejemplo n.º 2
0
/** Used by hs_alloc_scratch and hs_clone_scratch to allocate a complete
 * scratch region from a prototype structure. */
static
hs_error_t alloc_scratch(const hs_scratch_t *proto, hs_scratch_t **scratch) {
    u32 queueCount = proto->queueCount;
    u32 deduperCount = proto->deduper.log_size;
    u32 bStateSize = proto->bStateSize;
    u32 tStateSize = proto->tStateSize;
    u32 fullStateSize = proto->fullStateSize;
    u32 anchored_region_len = proto->anchored_region_len;
    u32 anchored_region_width = proto->anchored_region_width;
    u32 anchored_literal_region_len = proto->anchored_literal_region_len;
    u32 anchored_literal_region_width = proto->anchored_literal_count;

    u32 som_store_size = proto->som_store_count * sizeof(u64a);
    u32 som_attempted_store_size = proto->som_store_count * sizeof(u64a);
    u32 som_now_size = fatbit_size(proto->som_store_count);
    u32 som_attempted_size = fatbit_size(proto->som_store_count);

    struct hs_scratch *s;
    struct hs_scratch *s_tmp;
    size_t queue_size = queueCount * sizeof(struct mq);
    size_t qmpq_size = queueCount * sizeof(struct queue_match);

    assert(anchored_region_len < 8 * sizeof(s->am_log_sum));
    assert(anchored_literal_region_len < 8 * sizeof(s->am_log_sum));

    size_t anchored_region_size = anchored_region_len
        * (mmbit_size(anchored_region_width) + sizeof(u8 *));
    anchored_region_size = ROUNDUP_N(anchored_region_size, 8);

    size_t anchored_literal_region_size = anchored_literal_region_len
        * (mmbit_size(anchored_literal_region_width) + sizeof(u8 *));
    anchored_literal_region_size = ROUNDUP_N(anchored_literal_region_size, 8);

    size_t delay_size = mmbit_size(proto->delay_count) * DELAY_SLOT_COUNT;

    size_t nfa_context_size = 2 * sizeof(struct NFAContext512) + 127;

    // the size is all the allocated stuff, not including the struct itself
    size_t size = queue_size + 63
                  + bStateSize + tStateSize
                  + fullStateSize + 63 /* cacheline padding */
                  + nfa_context_size
                  + fatbit_size(proto->roleCount) /* handled roles */
                  + fatbit_size(queueCount) /* active queue array */
                  + 2 * fatbit_size(deduperCount) /* need odd and even logs */
                  + 2 * fatbit_size(deduperCount) /* ditto som logs */
                  + 2 * sizeof(u64a) * deduperCount /* start offsets for som */
                  + anchored_region_size
                  + anchored_literal_region_size + qmpq_size + delay_size
                  + som_store_size
                  + som_now_size
                  + som_attempted_size
                  + som_attempted_store_size
                  + proto->sideScratchSize + 15;

    /* the struct plus the allocated stuff plus padding for cacheline
     * alignment */
    const size_t alloc_size = sizeof(struct hs_scratch) + size + 256;
    s_tmp = hs_scratch_alloc(alloc_size);
    hs_error_t err = hs_check_alloc(s_tmp);
    if (err != HS_SUCCESS) {
        hs_scratch_free(s_tmp);
        *scratch = NULL;
        return err;
    }

    memset(s_tmp, 0, alloc_size);
    s = ROUNDUP_PTR(s_tmp, 64);
    DEBUG_PRINTF("allocated %zu bytes at %p but realigning to %p\n", alloc_size, s_tmp, s);
    DEBUG_PRINTF("sizeof %zu\n", sizeof(struct hs_scratch));
    *s = *proto;

    s->magic = SCRATCH_MAGIC;
    s->scratchSize = alloc_size;
    s->scratch_alloc = (char *)s_tmp;

    // each of these is at an offset from the previous
    char *current = (char *)s + sizeof(*s);

    // align current so that the following arrays are naturally aligned: this
    // is accounted for in the padding allocated
    current = ROUNDUP_PTR(current, 8);

    s->queues = (struct mq *)current;
    current += queue_size;

    assert(ISALIGNED_N(current, 8));
    s->som_store = (u64a *)current;
    current += som_store_size;

    s->som_attempted_store = (u64a *)current;
    current += som_attempted_store_size;

    s->delay_slots = (u8 *)current;
    current += delay_size;

    current = ROUNDUP_PTR(current, 8);
    s->am_log = (u8 **)current;
    current += sizeof(u8 *) * anchored_region_len;
    for (u32 i = 0; i < anchored_region_len; i++) {
        s->am_log[i] = (u8 *)current;
        current += mmbit_size(anchored_region_width);
    }

    current = ROUNDUP_PTR(current, 8);
    s->al_log = (u8 **)current;
    current += sizeof(u8 *) * anchored_literal_region_len;
    for (u32 i = 0; i < anchored_literal_region_len; i++) {
        s->al_log[i] = (u8 *)current;
        current += mmbit_size(anchored_literal_region_width);
    }

    current = ROUNDUP_PTR(current, 8);
    s->catchup_pq.qm = (struct queue_match *)current;
    current += qmpq_size;

    s->bstate = (char *)current;
    s->bStateSize = bStateSize;
    current += bStateSize;

    s->tstate = (char *)current;
    s->tStateSize = tStateSize;
    current += tStateSize;

    current = ROUNDUP_PTR(current, 64);
    assert(ISALIGNED_CL(current));
    s->nfaContext = current;
    current += sizeof(struct NFAContext512);
    current = ROUNDUP_PTR(current, 64);
    assert(ISALIGNED_CL(current));
    s->nfaContextSom = current;
    current += sizeof(struct NFAContext512);

    assert(ISALIGNED_N(current, 8));
    s->deduper.som_start_log[0] = (u64a *)current;
    current += sizeof(u64a) * deduperCount;

    s->deduper.som_start_log[1] = (u64a *)current;
    current += sizeof(u64a) * deduperCount;

    assert(ISALIGNED_N(current, 8));
    s->aqa = (struct fatbit *)current;
    current += fatbit_size(queueCount);

    s->handled_roles = (struct fatbit *)current;
    current += fatbit_size(proto->roleCount);

    s->deduper.log[0] = (struct fatbit *)current;
    current += fatbit_size(deduperCount);

    s->deduper.log[1] = (struct fatbit *)current;
    current += fatbit_size(deduperCount);

    s->deduper.som_log[0] = (struct fatbit *)current;
    current += fatbit_size(deduperCount);

    s->deduper.som_log[1] = (struct fatbit *)current;
    current += fatbit_size(deduperCount);

    s->som_set_now = (struct fatbit *)current;
    current += som_now_size;

    s->som_attempted_set = (struct fatbit *)current;
    current += som_attempted_size;

    current = ROUNDUP_PTR(current, 16);
    s->side_scratch = (void *)current;
    current += proto->sideScratchSize;

    current = ROUNDUP_PTR(current, 64);
    assert(ISALIGNED_CL(current));
    s->fullState = (char *)current;
    s->fullStateSize = fullStateSize;
    current += fullStateSize;

    *scratch = s;

    // Don't get too big for your boots
    assert((size_t)(current - (char *)s) <= alloc_size);

    // Init q->scratch ptr for every queue.
    for (struct mq *qi = s->queues; qi != s->queues + queueCount; ++qi) {
        qi->scratch = s;
    }

    return HS_SUCCESS;
}