region_table_t *parse_regions_from_gff_file(char *filename, const char *url, const char *species, const char *version) { gff_file_t *file = gff_open(filename); if (file == NULL) { return NULL; } region_table_t *regions_table = create_table(url, species, version); int ret_code = 0; size_t max_batches = 20; size_t batch_size = 2000; list_t *read_list = (list_t*) malloc (sizeof(list_t)); list_init("batches", 1, max_batches, read_list); #pragma omp parallel sections { // The producer reads the GFF file #pragma omp section { LOG_DEBUG_F("Thread %d reads the GFF file\n", omp_get_thread_num()); ret_code = gff_read_batches(read_list, batch_size, file); list_decr_writers(read_list); if (ret_code) { LOG_FATAL_F("Error while reading GFF file %s (%d)\n", filename, ret_code); } } // The consumer inserts regions in the structure #pragma omp section { list_item_t *item = NULL, *batch_item = NULL; gff_batch_t *batch; gff_record_t *record; while ( (item = list_remove_item(read_list)) != NULL ) { batch = item->data_p; // For each record in the batch, generate a new region for (batch_item = batch->first_p; batch_item != NULL; batch_item = batch_item->next_p) { record = batch_item->data_p; region_t *region = (region_t*) malloc (sizeof(region_t)); region->chromosome = (char*) calloc ((strlen(record->sequence)+1), sizeof(char)); strncat(region->chromosome, record->sequence, strlen(record->sequence)); region->start_position = record->start; region->end_position = record->end; LOG_DEBUG_F("region '%s:%u-%u'\n", region->chromosome, region->start_position, region->end_position); insert_region(region, regions_table); } gff_batch_free(item->data_p); list_item_free(item); } } } gff_close(file, 0); return regions_table; }
int region_table_parse_from_string(char *input_regions, region_table_t *regions_table) { int as_positions = 1; char *str_1 = input_regions; char *str_2 = (char*) malloc (64 * sizeof(char)); char *saveptr1, *saveptr2; char *token, *subtoken; size_t token_len, subtoken_len; int i = 0; while ((token = strtok_r(str_1, ",", &saveptr1)) != NULL) { region_t *region = (region_t*) malloc (sizeof(region_t)); token_len = strlen(token); LOG_DEBUG_F("token = %s, len = %zu\n", token, token_len); strncpy(str_2, token, 63); str_2[token_len] = '\0'; // Set chromosome subtoken = strtok_r(str_2, ":", &saveptr2); subtoken_len = strlen(subtoken); region->chromosome = (char*) malloc ((subtoken_len+1) * sizeof(char)); strncpy(region->chromosome, subtoken, subtoken_len); region->chromosome[subtoken_len] = '\0'; // Set start position subtoken = strtok_r(NULL, "-", &saveptr2); region->start_position = (subtoken != NULL) ? atol(subtoken) : 1; // Set end position subtoken = strtok_r(NULL, "-", &saveptr2); if (subtoken != NULL) { region->end_position = atol(subtoken); } else { if (as_positions) { region->end_position = region->start_position; } else { region->end_position = UINT_MAX; } } LOG_DEBUG_F("region '%s:%u-%u'\n", region->chromosome, region->start_position, region->end_position); region->strand = NULL; region->type = NULL; insert_region(region, regions_table); str_1 = NULL; i++; } free(str_1); free(str_2); return 1; }
/* * Add an exclusion region. */ void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags) { vm_offset_t adj; /* * Truncate the starting address down to a page boundary, and round the * ending page up to a page boundary. */ adj = pa - trunc_page(pa); pa = trunc_page(pa); sz = round_page(sz + adj); if (excnt < nitems(exregions)) insert_region(exregions, excnt++, pa, sz, exflags); }
/* * Add a hardware memory region. */ void arm_physmem_hardware_region(uint64_t pa, uint64_t sz) { vm_offset_t adj; /* * Filter out the page at PA 0x00000000. The VM can't handle it, as * pmap_extract() == 0 means failure. */ if (pa == 0) { if (sz <= PAGE_SIZE) return; pa = PAGE_SIZE; sz -= PAGE_SIZE; } else if (pa > MAX_PHYS_ADDR) { /* This range is past usable memory, ignore it */ return; } /* * Also filter out the page at the end of the physical address space -- * if addr is non-zero and addr+size is zero we wrapped to the next byte * beyond what vm_paddr_t can express. That leads to a NULL pointer * deref early in startup; work around it by leaving the last page out. * * XXX This just in: subtract out a whole megabyte, not just 1 page. * Reducing the size by anything less than 1MB results in the NULL * pointer deref in _vm_map_lock_read(). Better to give up a megabyte * than leave some folks with an unusable system while we investigate. */ if ((pa + sz) > (MAX_PHYS_ADDR - 1024 * 1024)) { sz = MAX_PHYS_ADDR - pa + 1; if (sz <= 1024 * 1024) return; sz -= 1024 * 1024; } /* * Round the starting address up to a page boundary, and truncate the * ending page down to a page boundary. */ adj = round_page(pa) - pa; pa = round_page(pa); sz = trunc_page(sz - adj); if (sz > 0 && hwcnt < nitems(hwregions)) insert_region(hwregions, hwcnt++, pa, sz, 0); }
/* * Add an exclusion region. */ void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags) { vm_offset_t adj; /* * Truncate the starting address down to a page boundary, and round the * ending page up to a page boundary. */ adj = pa - trunc_page(pa); pa = trunc_page(pa); sz = round_page(sz + adj); if (excnt >= nitems(exregions)) panic("failed to exclude region %#jx-%#jx", (uintmax_t)pa, (uintmax_t)(pa + sz)); excnt = insert_region(exregions, excnt, pa, sz, exflags); }
BOOT_CODE static void init_freemem(p_region_t ui_p_reg, mem_p_regs_t mem_p_regs) { word_t i; /* we are guaranteed that we started loading the user image after the kernel * so we only include addresses above ui_info.p_reg.end */ pptr_t floor = ui_p_reg.end; for (i = 0; i < MAX_NUM_FREEMEM_REG; i++) { ndks_boot.freemem[i] = REG_EMPTY; } for (i = 0; i < mem_p_regs.count; i++) { pptr_t start = mem_p_regs.list[i].start; pptr_t end = mem_p_regs.list[i].end; if (start < floor) { start = floor; } if (end < floor) { end = floor; } insert_region(paddr_to_pptr_reg((p_region_t) { start, end })); } }
BOOT_CODE pptr_t alloc_region(word_t size_bits) { word_t i; word_t reg_index = 0; /* gcc cannot work out that this will not be used uninitialized */ region_t reg = REG_EMPTY; region_t rem_small = REG_EMPTY; region_t rem_large = REG_EMPTY; region_t new_reg; region_t new_rem_small; region_t new_rem_large; /* Search for a freemem region that will be the best fit for an allocation. We favour allocations * that are aligned to either end of the region. If an allocation must split a region we favour * an unbalanced split. In both cases we attempt to use the smallest region possible. In general * this means we aim to make the size of the smallest remaining region smaller (ideally zero) * followed by making the size of the largest remaining region smaller */ for (i = 0; i < MAX_NUM_FREEMEM_REG; i++) { /* Determine whether placing the region at the start or the end will create a bigger left over region */ if (ROUND_UP(ndks_boot.freemem[i].start, size_bits) - ndks_boot.freemem[i].start < ndks_boot.freemem[i].end - ROUND_DOWN(ndks_boot.freemem[i].end, size_bits)) { new_reg.start = ROUND_UP(ndks_boot.freemem[i].start, size_bits); new_reg.end = new_reg.start + BIT(size_bits); } else { new_reg.end = ROUND_DOWN(ndks_boot.freemem[i].end, size_bits); new_reg.start = new_reg.end - BIT(size_bits); } if (new_reg.end > new_reg.start && new_reg.start >= ndks_boot.freemem[i].start && new_reg.end <= ndks_boot.freemem[i].end) { if (new_reg.start - ndks_boot.freemem[i].start < ndks_boot.freemem[i].end - new_reg.end) { new_rem_small.start = ndks_boot.freemem[i].start; new_rem_small.end = new_reg.start; new_rem_large.start = new_reg.end; new_rem_large.end = ndks_boot.freemem[i].end; } else { new_rem_large.start = ndks_boot.freemem[i].start; new_rem_large.end = new_reg.start; new_rem_small.start = new_reg.end; new_rem_small.end = ndks_boot.freemem[i].end; } if ( is_reg_empty(reg) || (reg_size(new_rem_small) < reg_size(rem_small)) || (reg_size(new_rem_small) == reg_size(rem_small) && reg_size(new_rem_large) < reg_size(rem_large)) ) { reg = new_reg; rem_small = new_rem_small; rem_large = new_rem_large; reg_index = i; } } } if (is_reg_empty(reg)) { printf("Kernel init failing: not enough memory\n"); return 0; } /* Remove the region in question */ ndks_boot.freemem[reg_index] = REG_EMPTY; /* Add the remaining regions in largest to smallest order */ insert_region(rem_large); if (!insert_region(rem_small)) { printf("alloc_region(): wasted 0x%lx bytes due to alignment, try to increase MAX_NUM_FREEMEM_REG\n", (word_t)(rem_small.end - rem_small.start)); } return reg.start; }
void mu_getlst(char *name, int4 size) { char *c1, *c2, *c3, *c4, rbuff[MAX_FN_LEN + 1], fbuff[MAX_FN_LEN + 1]; unsigned short rlen, flen, i; gd_region *reg; tp_region *list; boolean_t matched; error_def(ERR_MUNODBNAME); error_def(ERR_MUBCKNODIR); error_def(ERR_MUNOACTION); error_def(ERR_TEXT); mu_star_specified = FALSE; assert(size > 0); rlen = sizeof(rbuff); flen = sizeof(fbuff); if (!cli_get_str(name, rbuff, &rlen)) mupip_exit(ERR_MUNODBNAME); if (in_backup && ((!cli_get_str("SAVE_DIR", fbuff, &flen)) || (0 == flen))) mupip_exit(ERR_MUBCKNODIR); is_directory = FALSE; for (c1 = c2 = rbuff, c3 = c4 = fbuff;;) { for (; *c2 && (*c2 != ','); c2++) /* locate a reg spec */ ; if (c2 - c1 > MAX_RN_LEN) { error_mupip = TRUE; util_out_print("!UL exceeds maximum REGION name length of !UL characters.", TRUE, c2 - c1, MAX_RN_LEN); } else { /* handle the reg spec here */ if ('*' == *c1 && (1 == c2 - c1)) mu_star_specified = TRUE; matched = FALSE; for (i = 0, reg = gd_header->regions; i < gd_header->n_regions; i++, reg++) { if (TRUE == str_match((char *)reg->rname, reg->rname_len, c1, c2 - c1)) { matched = TRUE; if (NULL == (list = insert_region(reg, &(grlist), NULL, size))) { error_mupip = TRUE; rts_error(VARLSTCNT(4) ERR_TEXT, 2, RTS_ERROR_STRING("Region not found")); continue; } if ((FALSE == in_backup) || (0 != ((backup_reg_list *)list)->backup_file.len)) continue; if (TRUE == is_directory) { assert(NULL != grlist->fPtr); mubexpfilnam(directory.addr, directory.len, (backup_reg_list *)list); } else { for (; *c4 && (*c4 != ','); c4++) /* locate a file spec */ ; if (FALSE == mubgetfil((backup_reg_list *)list, c3, c4 - c3)) break; if (*c4) c3 = ++c4; else if (FALSE == is_directory) break; } } } if (!matched) { util_out_print("REGION !AD not found", TRUE, c2 - c1, c1); mupip_exit(ERR_MUNOACTION); } } if (!*c2) break; else c1 = ++c2; } return; }