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; }
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, ¤t_master_session.config.qos); }