コード例 #1
0
ファイル: block.c プロジェクト: ejrh/ejrh
BLOCK *allocate_block(FS *fs, BLOCK_TYPE type, LOCATION target)
{
    BLOCK *block;
    LOCATION addr;
    
    if (type != B_SUPER)
        addr = bitmap_search(fs, target);
    else
        addr = 0;

    if (addr != 0)
    {
        struct superblock_header *sbh;

        block = get_block(fs, addr, 0);
        sbh = (struct superblock_header *) fs->superblock->buffer;
        sbh->block_counts[B_FREE]--;
        if (!block)
            error("Error reusing free block!\n");
        remove_block_from_hash(fs, block);
    }
    else
    {
        block = find_free_slot(fs);
        if (!block)
            error("Error allocating block, cache is full!\n");
        
        addr = fs->num_blocks;
        fs->num_blocks++;
    }
    
    memset(block->buffer, 0, fs->block_size);
    set_flag(block, F_CACHED);
    set_flag(block, F_DIRTY);
    block->location = addr;
    block->type = type;
    block->pins = 0;
    
    if (block->type != B_DATA)
    {
        struct block_header *h = (struct block_header *) block->buffer;
        h->version = 1;
        h->location = addr;
        h->type = type;
    }
    
    if (block->type == B_TREE)
    {
        struct tree_block_header *h = (struct tree_block_header *) block->buffer;
        h->height = 0;
        h->num_keys = 0;
        h->string_size = 0;
    }
    
    if (block->type == B_SUPER)
    {
        struct superblock_header *sbh = (struct superblock_header *) block->buffer;
        sbh->block_counts[B_SUPER] = 1;
        fs->max_bitmap_pointers = (fs->block_size - sizeof (struct superblock_header)) / sizeof (unsigned long int);
        fs->num_bitmap_pointers = 0;
        fs->bitmap_size = (fs->block_size - sizeof (struct superblock_header)) * 8;
        fs->bitmaps = (unsigned long int *) (block->buffer + sizeof(struct superblock_header));
        fs->superblock = block;
    }
    else
    {
        struct superblock_header *sbh = (struct superblock_header *) fs->superblock->buffer;
        sbh->block_counts[block->type]++;
    }
    
    flush_block(fs, block);
    set_flag(block, F_CACHED);
    set_flag(block, F_DIRTY);
    add_block_to_hash(fs, block);
    
    if (block->type != B_BITMAP)
        bitmap_set(fs, addr, 1);
    
    //printf("Allocated block %d, type %d\n", block->location, block->type);
    return block;
}
コード例 #2
0
static void flush_fifos()
{
    assert(d7asp_state == D7ASP_STATE_MASTER);
    DPRINT("Flushing FIFOs");
    hw_watchdog_feed(); // TODO do here?

    if(current_request_id == NO_ACTIVE_REQUEST_ID)
    {
        // find first request which is not acked or dropped
        int8_t found_next_req_index = bitmap_search(current_master_session.progress_bitmap, false, MODULE_D7AP_FIFO_MAX_REQUESTS_COUNT);
        if(found_next_req_index == -1 || found_next_req_index == current_master_session.next_request_id)
        {
            // we handled all requests ...
            flush_completed();

            // TODO move callback to ALP?
//            if(d7asp_init_args != NULL && d7asp_init_args->d7asp_fifo_flush_completed_cb != NULL)
//                d7asp_init_args->d7asp_fifo_flush_completed_cb(fifo.token, fifo.progress_bitmap, fifo.success_bitmap, REQUESTS_BITMAP_BYTE_COUNT);

            return;
        }

        current_request_id = found_next_req_index;
        current_request_retry_count = 0;

        current_request_packet = packet_queue_alloc_packet();
        packet_queue_mark_processing(current_request_packet);
        current_request_packet->d7anp_addressee = &(current_master_session.config.addressee); // TODO explicitly pass addressee down the stack layers?

        memcpy(current_request_packet->payload, current_master_session.request_buffer + current_master_session.requests_indices[current_request_id], current_master_session.requests_lengths[current_request_id]);
        current_request_packet->payload_length = current_master_session.requests_lengths[current_request_id];

        // TODO calculate Tl and Tc
        // Tc(NB, LEN, CH) = (SFC  * NB  + 1) * TTX(CH, LEN) + TG with NB the number of concurrent devices and SF the collision Avoidance Spreading Factor
        // Tl should correspond to the maximum time needed to send the remaining requests in the FIFO including the RETRY parameter

        // For now, set Tc and Tl according the transmission_timeout_period set in the access profile
        dae_access_profile_t active_addressee_access_profile;
        fs_read_access_class(current_request_packet->d7anp_addressee->ctrl.access_class, &active_addressee_access_profile);
        current_request_packet->d7atp_tc = active_addressee_access_profile.transmission_timeout_period;
        current_request_packet->d7anp_listen_timeout = active_addressee_access_profile.transmission_timeout_period;
    }
    else
    {
        // retrying request ...
        DPRINT("Current request retry count: %i", current_request_retry_count);
        if(current_request_retry_count == single_request_retry_limit)
        {
            // mark request as failed and pop
            mark_current_request_done();
            DPRINT("Request reached single request retry limit (%i), skipping request", single_request_retry_limit);
            packet_queue_free_packet(current_request_packet);
            current_request_id = NO_ACTIVE_REQUEST_ID;
            sched_post_task(&flush_fifos); // continue flushing until all request handled ...
            return;
        }

        // TODO stop on error
    }

    // TODO calculate D7ANP timeout (and update during transaction lifetime) (based on Tc, channel, cs, payload size, # msgs, # retries)
    d7atp_start_dialog(current_master_session.token, current_request_id, (current_request_id == current_master_session.next_request_id - 1), current_request_packet, &current_master_session.config.qos);
}