Example #1
0
int CS_putSegment(struct content_obj * prefix_obj, struct linked_list * content_chunks)
{
    if (!prefix_obj || !content_chunks) return -1;

    struct CS_segment * segment = malloc(sizeof(struct CS_segment));
    /* this is a content matching a prefix */
    char * key = malloc(strlen(prefix_obj->name->full_name));
    strcpy(key, prefix_obj->name->full_name);
    segment->index_chunk = prefix_obj;
    segment->num_chunks = content_chunks->len;
    segment->chunks = malloc(sizeof(struct content_obj * ) * segment->num_chunks);
    segment->valid = bit_create(segment->num_chunks);
    pthread_mutex_init(&segment->lock, NULL);

    int i = 0;
    while (content_chunks->len) {
        bit_set(segment->valid, i);
        segment->chunks[i++] = linked_list_remove(content_chunks, 0);
    }

    pthread_mutex_lock(&_cs.lock);
    hash_put(_cs.table, key, (void * ) segment);
    pthread_mutex_unlock(&_cs.lock);

    return 0;
}
Example #2
0
int
test_base_bitset(const char* param) {
    rand_seed((uint32_t)time(NULL));

    // bit create 
    int size = param ? atoi(param) : rand() % 1024;
    bit_t* bit = bit_create(size);
    if (!bit) {
        fprintf(stderr, "bit create fail\n");
        return -1;
    }

    // bit set 
    int test_size = (size >> 1);
    for (int i = 0; i < test_size; ++ i) {
        bit_set(bit, i);
    }

    // bit is set 
    for (int i = 0; i < size; ++ i) {
        if (i < test_size && bit_isset(bit, i)) {
            fprintf(stderr, "bit-set error\n");
            bit_release(bit);
            return -1;
        }
        if (i >= test_size && bit_isset(bit, i) == 0) {
            fprintf(stderr, "bit-set error\n");
            bit_release(bit);
            return -1;
        }
    }

    // bit count
    if (bit_count(bit) != test_size) {
        fprintf(stderr, "bit-count = %d error\n", bit_count(bit));
        bit_release(bit);
        return -1;
    }

    // bit reset -> bit count
    for (int i = 0; i < test_size; ++ i) {
        bit_reset(bit, i);
    }
    if (bit_count(bit) != 0) {
        fprintf(stderr, "bit-count error\n");
        bit_release(bit);
        return -1;
    }

    bit_release(bit);
    return 0;
}
Example #3
0
int CS_put(struct content_obj * content)
{
    content = content_copy(content);
    log_assert(g_log, content != NULL, "CS: failed to allocate content");

    pthread_mutex_lock(&_cs.lock);
    struct CS_segment * segment = (struct CS_segment * )
        hash_get(_cs.table, content_prefix(content->name));
    pthread_mutex_unlock(&_cs.lock);

    int rv = 0;
    if (content_is_segmented(content->name)) {

        if (segment) {

            pthread_mutex_lock(&segment->lock);

            int seq_no = content_seq_no(content->name);
            if (seq_no >= segment->num_chunks) {
                segment->chunks = realloc(segment->chunks, sizeof(struct content_obj * ) * (seq_no + 1));
                segment->num_chunks = seq_no + 1;
                segment->chunks[seq_no] = content;
                struct bitmap * larger = bit_create(segment->num_chunks);
                memcpy(larger->map, segment->valid->map, segment->valid->num_words);
                bit_destroy(segment->valid);
                segment->valid = larger;
                bit_set(larger, seq_no);
            } else {
                if (bit_test(segment->valid, seq_no)) {
                    content_obj_destroy(segment->chunks[seq_no]);
                }
                segment->chunks[seq_no] = content;
                bit_set(segment->valid, seq_no);
            }

            pthread_mutex_unlock(&segment->lock);

        } else {
            rv = -1;
        }

    } else {

        if (!segment) {

            segment = malloc(sizeof(struct CS_segment));
            /* this is a content matching a prefix */
            char * key = malloc(strlen(content->name->full_name));
            strcpy(key, content->name->full_name);
            segment->index_chunk = content;
            segment->chunks = NULL;
            segment->num_chunks = -1;
            segment->valid = bit_create(0);
            pthread_mutex_init(&segment->lock, NULL);

            pthread_mutex_lock(&_cs.lock);
            hash_put(_cs.table, key, (void * ) segment);
            pthread_mutex_unlock(&_cs.lock);

        } else {

            pthread_mutex_lock(&segment->lock);

            if (segment->index_chunk) {
                content_obj_destroy(segment->index_chunk);
            }
            segment->index_chunk = content;

            pthread_mutex_unlock(&segment->lock);

        }
    }

    return rv;
}
Example #4
0
/*{{{  shape -- reshape a window to specified dimensions*/
int shape(int x, int y, int dx, int dy)
{
  int sx, sy, w, h;
  WINDOW *win;

  if (dx > 0) {
    sx = x;
    w = dx;
  } else {
    sx = x + dx;
    w = -dx;
  }
  if (dy > 0) {
    sy = y;
    h = dy;
  } else {
    sy = y + dy;
    h = -dy;
  }

  if (sx < 0)
    sx = 0;

  if (sx + w >= BIT_WIDE(screen))
    w = BIT_WIDE(screen) - sx;

  if (sy + h >= BIT_HIGH(screen))
    h = BIT_HIGH(screen) - sy;

  if (w < 2 * ACTIVE(borderwid) + ACTIVE(font)->head.wide * MIN_X || h < 2 * ACTIVE(borderwid) + ACTIVE(font)->head.high * MIN_Y)
    return (-1);

#ifdef MGR_ALIGN
  alignwin(screen, &sx, &w, ACTIVE(borderwid));
#endif

  /* remove current window position */
  save_win(active);
  erase_win(ACTIVE(border));
  clip_bad(active); /* invalidate clip lists */

  /* redraw remaining windows */
  repair(active);

  /* adjust window state */
  ACTIVE(x0) = sx;
  ACTIVE(y0) = sy;
  bit_destroy(ACTIVE(window));
  bit_destroy(ACTIVE(border));
  ACTIVE(border) = bit_create(screen, sx, sy, w, h);
  ACTIVE(window) = bit_create(ACTIVE(border),
      ACTIVE(borderwid),
      ACTIVE(borderwid),
      w - ACTIVE(borderwid) * 2,
      h - ACTIVE(borderwid) * 2);

  for (win = ACTIVE(next); win != (WINDOW *)0; win = W(next)) {
    if (W(flags) & W_ACTIVE && intersect(active, win))
      save_win(win);
  }

  CLEAR(ACTIVE(window), PUTOP(BIT_CLR, ACTIVE(style)));

  border(active, BORDER_THIN);
  bit_blit(ACTIVE(border), 0, 0,
      BIT_WIDE(ACTIVE(save)) - ACTIVE(borderwid),
      BIT_HIGH(ACTIVE(save)) - ACTIVE(borderwid),
      BIT_SRC, ACTIVE(save), 0, 0);

  /* make sure character cursor is in a good spot */
  if (ACTIVE(x) > BIT_WIDE(ACTIVE(window))) {
    ACTIVE(x) = 0;
    ACTIVE(y) += ((int)(ACTIVE(font)->head.high));
  }
  if (ACTIVE(y) > BIT_HIGH(ACTIVE(window))) {
#ifdef WIERD
    ACTIVE(y) = BIT_HIGH(ACTIVE(window));
    scroll(ACTIVE(window), 0, BIT_HIGH(ACTIVE(window)),
        ((int)(ACTIVE(font)->head.high)), SWAPCOLOR(ACTIVE(style)));
    bit_blit(ACTIVE(window), 0, BIT_HIGH(ACTIVE(window)) - ((int)(ACTIVE(font)->head.high)),
        BIT_WIDE(ACTIVE(save)), ((int)(ACTIVE(font)->head.high)),
        BIT_SRC, ACTIVE(save),
        ACTIVE(borderwid), BIT_HIGH(ACTIVE(save)) - ((int)(ACTIVE(font)->head.high)) - ACTIVE(borderwid));
#else
    ACTIVE(y) = BIT_HIGH(ACTIVE(window)) - ((int)(ACTIVE(font)->head.high));
#endif
  }

  bit_destroy(ACTIVE(save));
  ACTIVE(save) = (BITMAP *)0;

  /* invalidate clip lists */
  clip_bad(active);
  un_covered();
  set_size(active);
  return (0);
}
Example #5
0
void test_bit(void)
{
  int i;
  void* B = bit_create(10);
  fprintf(stdout, "call function : %s\n", __func__);
  bit_object_show(B);

  fprintf(stdout, "\ntest function - bit_set/bit_get ===>\n");
  {
    srand((unsigned int)time(0));
    for (i = 0; i < bit_size(B); ++i)
      bit_set(B, i, rand() % 2);

    bit_object_show(B);
    for (i = 0; i < bit_size(B); ++i)
      fprintf(stdout, "\tbit values [%02d] => %d\n", i, bit_get(B, i));
  }

  fprintf(stdout, "\ntest function - bit_clear_range ===>\n");
  {
    bit_clear_range(B, 0, 4);
    bit_object_show(B);
    bit_for_each(B, bit_object_bit_show, NULL);
  }

  fprintf(stdout, "\ntest function - bit_set_range ===>\n");
  {
    bit_set_range(B, 5, 9);
    bit_object_show(B);
    bit_for_each(B, bit_object_bit_show, NULL);
  }

  fprintf(stdout, "\ntest function - bit_not_range ===>\n");
  {
    bit_not_range(B, 0, 9);
    bit_object_show(B);
    bit_for_each(B, bit_object_bit_show, NULL);
  }

  fprintf(stdout, "\ntest function - bit_clear ===>\n");
  {
    bit_clear(B);
    bit_object_show(B);
  }

  fprintf(stdout, "\ntest function - bit_release ===>\n");
  bit_release(&B);
  bit_object_show(B);


  fprintf(stdout, "\ntest function - bit_lt/bit_eq/bit_leq ===>\n");
  {
    void* B1 = bit_create(5);
    void* B2 = bit_create(5);

    srand((unsigned int)time(0));
    for (i = 0; i < 5; ++i)
    {
      bit_set(B1, i, rand() % 2);
      bit_set(B2, i, rand() % 2);
    }
    fprintf(stdout, "    B1 object show:\n");
    bit_for_each(B1, bit_object_bit_show, NULL);
    fprintf(stdout, "    B2 object show:\n");
    bit_for_each(B2, bit_object_bit_show, NULL);

    fprintf(stdout, "    B1 < B2 ? '%s'\n", bit_lt(B1, B2) ? "yes" : "no");
    fprintf(stdout, "    B1 = B2 ? '%s'\n", bit_eq(B1, B2) ? "yes" : "no");
    fprintf(stdout, "    B1 <= B2 ? '%s'\n", bit_leq(B1, B2) ? "yes" : "no");

    bit_release(&B1);
    bit_release(&B2);
  }

  fprintf(stdout, "\ntest function - union/inter/minus/diff ===>\n");
  {
    void* B1 = bit_create(5);
    void* B2 = bit_create(5);

    srand((unsigned int)time(0));
    for (i = 0; i < 5; ++i)
    {
      bit_set(B1, i, rand() % 2);
      bit_set(B2, i, rand() % 2);
    }
    fprintf(stdout, "    B1 object show:\n");
    bit_for_each(B1, bit_object_bit_show, NULL);
    fprintf(stdout, "    B2 object show:\n");
    bit_for_each(B2, bit_object_bit_show, NULL);

    B = bit_union(B1, B2);
    fprintf(stdout, "    B1 union B2 ->\n");
    bit_for_each(B, bit_object_bit_show, NULL);
    bit_release(&B);

    B = bit_inter(B1, B2);
    fprintf(stdout, "    B1 inter B2 ->\n");
    bit_for_each(B, bit_object_bit_show, NULL);
    bit_release(&B);
    
    B = bit_minus(B1, B2);
    fprintf(stdout, "    B1 minus B2 ->\n");
    bit_for_each(B, bit_object_bit_show, NULL);
    bit_release(&B);

    B = bit_diff(B1, B2);
    fprintf(stdout, "    B1 diff B2 ->\n");
    bit_for_each(B, bit_object_bit_show, NULL);
    bit_release(&B);

    bit_release(&B1);
    bit_release(&B2);
  }
}
Example #6
0
static int retrieve_segment(struct segment * seg)
{
    char proc[256];
    snprintf(proc, 256, "rsg%u", g_nodeId);
    prctl(PR_SET_NAME, proc, 0, 0, 0);
    int rv = -1;
    log_print(g_log, "retrieve_segment: trying to retrieve segment %s[%d - %d].",
              seg->name->full_name, 0, seg->num_chunks-1);

    pthread_mutex_lock(&g_lock);
    int retries = g_interest_attempts;
    int timeout_ms = g_timeout_ms;
    pthread_mutex_unlock(&g_lock);
    int ttl = MAX_TTL;

    if ((seg->opts->mode & CCNFDNB_USE_RETRIES) == CCNFDNB_USE_RETRIES) {
        retries = seg->opts->retries;
    }
    if ((seg->opts->mode & CCNFDNB_USE_TIMEOUT) == CCNFDNB_USE_TIMEOUT) {
        timeout_ms = seg->opts->timeout_ms;
    }
    if ((seg->opts->mode & CCNFDNB_USE_TTL) == CCNFDNB_USE_TTL) {
        ttl = seg->opts->ttl;
    }

    struct chunk chunk_window[MAX_INTEREST_PIPELINE];
    PENTRY _pit_handles[MAX_INTEREST_PIPELINE];
    int pit_to_chunk[PIT_SIZE];
    memset(&pit_to_chunk, 0, sizeof(pit_to_chunk));
    struct bitmap * window = bit_create(MAX_INTEREST_PIPELINE);
    struct bitmap * missing = bit_create(seg->num_chunks);

    char str[MAX_NAME_LENGTH], comp[MAX_NAME_LENGTH];
    strncpy(str, seg->name->full_name, seg->name->len);

    int rtt_est = timeout_ms;
    int cwnd = 1;
    int ssthresh = DEFAULT_INTEREST_PIPELINE;
    int fullfilled = 0;
    int min_rtt_est = 10;

    int current_chunk = 0;
    cc_state state = SLOW_START;
    int tx;

    _segment_q_t seg_q;
    pthread_mutex_init(&seg_q.mutex, NULL);
    pthread_cond_init(&seg_q.cond, NULL);
    seg_q.rcv_window = 0;
    seg_q.max_window = &cwnd;
    seg_q.rcv_chunks = linked_list_init(NULL);
    seg_q.base = seg->name;
    ccnfdnl_reg_segment(&seg_q);

    int i;
    window->num_bits = cwnd;
    while (!bit_allSet(missing)) {
        tx = cwnd;
        window->num_bits = cwnd;

        log_debug(g_log, "state = %d, cwnd = %d, ssthresh = %d rtt_est = %d",
                  state, cwnd, ssthresh, rtt_est);

        while (tx && (current_chunk < seg->num_chunks)) {
            snprintf(comp, MAX_NAME_LENGTH - seg->name->len, "/%d", current_chunk);
            strncpy(str + seg->name->len, comp, seg->name->len);
            i = bit_find(window);
            if (i < 0 || i >= MAX_INTEREST_PIPELINE) {
                /* we must still be waiting for data */
                break;
            }
            chunk_window[i].intr.name = content_name_create(str);
            chunk_window[i].intr.ttl = ttl;
            chunk_window[i].seq_no = current_chunk;
            chunk_window[i].retries = retries;

            _pit_handles[i] = PIT_get_handle(chunk_window[i].intr.name);
            if (!_pit_handles[i]) {
                bit_clear(window, i);
                break;
            }
            pit_to_chunk[_pit_handles[i]->index] = i;
            pthread_mutex_unlock(_pit_handles[i]->mutex);

            struct content_obj * co = CS_get(chunk_window[i].intr.name);
            if (!co) {
                log_debug(g_log, "expressing new interest: %s", chunk_window[i].intr.name->full_name);
                ccnfdnb_fwd_interest(&chunk_window[i].intr);
                tx--;
            } else {
                log_debug(g_log, "retrieved %s from CS", co->name->full_name);

                PENTRY pe = PIT_exact_match(chunk_window[i].intr.name);
                *pe->obj = co;
                pthread_mutex_unlock(pe->mutex);

                pthread_mutex_lock(&seg_q.mutex);

                linked_list_append(seg_q.rcv_chunks, pe);
                seg_q.rcv_window++;

                pthread_mutex_unlock(&seg_q.mutex);
            }

            current_chunk++;
        }
        log_debug(g_log, "tx window full");

        pthread_mutex_lock(&seg_q.mutex);

        if (seg_q.rcv_chunks->len == 0) {
            struct timespec wait;
            ts_fromnow(&wait);
            ts_addms(&wait, 2 * rtt_est);

            rv = pthread_cond_timedwait(&seg_q.cond, &seg_q.mutex, &wait);
            if ((rv == ETIMEDOUT) && !seg_q.rcv_chunks->len) {
                /* we timed out, we need to rtx */
                rtt_est += rtt_est / 2;
                if (rtt_est > PIT_LIFETIME_MS)
                    rtt_est = PIT_LIFETIME_MS / 2;
            }
        } else {
            int pit_ages = 0;
            int pits_fulfilled = 0;
            while (seg_q.rcv_chunks->len > 0) {
                PENTRY pe = linked_list_remove(seg_q.rcv_chunks, 0);
                log_assert(g_log, pe != NULL, "invalid pit entry");

                pthread_mutex_lock(pe->mutex);
                log_debug(g_log, "pit entry %s fulfilled", (*pe->obj)->name->full_name);

                int chunk_id = pit_to_chunk[pe->index];
                log_assert(g_log, chunk_id >= 0, "invalid chunk id");

                if (chunk_window[chunk_id].seq_no == 0) {
                    seg->obj->publisher = (*pe->obj)->publisher;
                    seg->obj->timestamp = (*pe->obj)->timestamp;
                    seg->chunk_size = (*pe->obj)->size;
                }
                int offset = chunk_window[chunk_id].seq_no * seg->chunk_size;
                memcpy(&seg->obj->data[offset], (*pe->obj)->data, (*pe->obj)->size);
                content_obj_destroy(*pe->obj);

                struct timespec now;
                ts_fromnow(&now);
                ts_addms(&now, PIT_LIFETIME_MS);
                pit_ages += PIT_age(pe);
				pits_fulfilled++;

                pit_to_chunk[pe->index] = -1;
                PIT_release(pe);
                free(_pit_handles[chunk_id]);
                _pit_handles[chunk_id] = NULL;
                bit_clear(window, chunk_id);
                bit_set(missing, chunk_window[chunk_id].seq_no);
                log_debug(g_log, "retrieved chunk %s", chunk_window[chunk_id].intr.name->full_name);
                content_name_delete(chunk_window[chunk_id].intr.name);
                chunk_window[chunk_id].intr.name = NULL;
                cwnd++;
                if (state == CONG_AVOID)
                    fullfilled++;
            }

            rtt_est -= floor(pit_ages / pits_fulfilled);
            if (rtt_est < min_rtt_est)
                rtt_est = min_rtt_est;
        }

        pthread_mutex_unlock(&seg_q.mutex);

        for (i = 0; i < MAX_INTEREST_PIPELINE; i++) {
            if (bit_test(window, i)) {
                if (!_pit_handles[i]) {
                    continue;
                }
                pthread_mutex_lock(_pit_handles[i]->mutex);
                if (PIT_age(_pit_handles[i]) > (2 * rtt_est)) {
                    PIT_refresh(_pit_handles[i]);
                    chunk_window[i].retries--;
                    ccnfdnb_fwd_interest(&chunk_window[i].intr);
                    log_debug(g_log, "rtx interest: %s (rtt = %d)",
                              chunk_window[i].intr.name->full_name, rtt_est);
                    ssthresh = cwnd / 2 + 1;
                    cwnd = 1;
                    state = SLOW_START;
                }
                pthread_mutex_unlock(_pit_handles[i]->mutex);
            }
        }

        if ((cwnd >= ssthresh) && (state == SLOW_START))
            state = CONG_AVOID;
        if (state == SLOW_START)
            fullfilled = 0;
        if ((fullfilled == cwnd) && (state == CONG_AVOID)) {
            cwnd++;
            fullfilled = 0;
        }
        if (cwnd > MAX_INTEREST_PIPELINE)
            cwnd = MAX_INTEREST_PIPELINE;

        /*log_debug(g_log, "cwnd = %d, ssthresh = %d", cwnd, ssthresh);*/
    }

    log_debug(g_log, "retrieve_segment: finished for %s[%d-%d]",
              seg->name->full_name, 0, seg->num_chunks-1);

    rv = 0;

    PIT_print();
    ccnfdnl_unreg_segment(&seg_q);
    pthread_mutex_destroy(&seg_q.mutex);
    pthread_cond_destroy(&seg_q.cond);
    while (seg_q.rcv_chunks->len) {
        PENTRY pe = linked_list_remove(seg_q.rcv_chunks, 0);
        content_obj_destroy(*pe->obj);
        PIT_release(pe);
    }

    bit_destroy(window);
    bit_destroy(missing);

    return rv;
}