bool pmem_reserve(phys_addr_t addr, size_t length) { register phys_addr_t top, cur; register bool checkPass = true; if(ALIGN_RST(addr, PMEM_PAGESIZE) != 0) { fatal("misaligned physical address!\n"); } debug("try to reserve physical memory at %p (length: %d bytes)\n", addr, length); spl_lock(&pmem_lock); next_pass: top = (addr + length); cur = addr; while(top > cur) { pmem_region_t* reg = pmem_region_head; while(reg) { while(pmem_reg_contains(reg, cur)) { register size_t idx = PMEM_TO_REGBIT(reg, cur); if(checkPass) { if(bmap_get(reg->bmap, idx)) { spl_unlock(&pmem_lock); debug("failed to reserve region, %p already reserved\n", cur); return false; } } else { bmap_set(reg->bmap, idx, 1); } cur += PMEM_PAGESIZE; if(top <= cur) goto pass_ok; } reg = reg->next; } cur += PMEM_PAGESIZE; } pass_ok: if(checkPass) { checkPass = false; goto next_pass; } spl_unlock(&pmem_lock); return true; }
static int find_shortest_path (Bitmap *bitmap, GraphPath **path_r) /* current optimal path */ { GraphPath *path = *path_r; GraphPath *found_path = NULL; int cur_path_size = path->num_edges; int j,i; size_t num_p; int status = 1; int two_pass_mode = (cur_path_size < num_nodes); GraphNode **idc = alloca ( (path->num_edges + 1)*sizeof (GraphNode*) ); path_transform_to_reverse_nodes_aray (path, &idc, &num_p); _loop_enter: for (j = 0 ; j < num_p ;j++) { GraphNode *curnode = idc[j]; for (i = 0; i < curnode->num_edges; i++) { GraphEdge *curedge = curnode->edges[i]; GraphNode *node_to = curedge->node_ptr; if (path->total_weight + curedge->weight >= _found_min){ #ifdef DEBUG _stat_cut_by_weight++; #endif continue; //don't go this way } if (two_pass_mode && status && bmap_get_in (bitmap, node_to->arr_idx)){ continue; } if (two_pass_mode && !status && !bmap_get_in (bitmap, node_to->arr_idx)){ continue; } if (bmap_get (bitmap, curnode->arr_idx, node_to->arr_idx)){ #ifdef DEBUG _stat_cut_by_presence++; #endif continue; //already passed by this edge } _stop_cnt++; if (_stop_cnt > MAXIMUM_SEARCH_ITERATION){ //up until third level if (cur_path_size < _update_path){ _update_path -= 2; // printf ("max path update: %d\n", _update_path); _stop_cnt = 0; } goto _loop_exit; } #ifdef DEBUG _stat_evaluated++; #endif void *bitmap_n = bmap_clone (bitmap); // printf ("before(%d,%d): ",i,j); // path_print_short (path); path_add (path, curedge); bmap_set (bitmap_n, curnode->arr_idx, node_to->arr_idx); // printf ("after(%d,%d) : ",i,j); // path_print_short (path); int path_found = bmap_check_full (bitmap_n) && path_check_valid (path); GraphPath *hpath = NULL; if (path_found == 0){ //try to check solution in hash table hpath = bmap_hash_path_search_optimal (bitmap_n); if (hpath == NULL){ if (path->num_edges <= _depth ) path_found = find_shortest_path (bitmap_n, &path); }else { #ifdef DEBUG _stat_found_hash++; #endif if (hpath != BMAP_HASH_PATH_EMPTY ){ hpath = path_clone (hpath); //rearrange path ensure_order_paths (path, hpath, cur_path_size); path_free (path); path = hpath; path_found = 1; }else{ path_found = 0; } } } if (path_found == 1 && (found_path == NULL || path->total_weight < found_path->total_weight)) { path_free (found_path); found_path = path_clone (path); if (hpath == NULL && found_path->num_edges - cur_path_size > 1) bmap_hash_path_add_optimal (bitmap_n, found_path); }else{ if (hpath == NULL && cur_path_size < num_nodes + 2) bmap_hash_path_add_optimal (bitmap_n, NULL); } path_shrink_to_size (path, cur_path_size); bmap_free (bitmap_n); } } if(two_pass_mode && status && cur_path_size < num_nodes){ status = 0; goto _loop_enter; } _loop_exit: if (found_path != NULL){ _update_path = found_path->num_edges; // printf ("FOUND: "); // path_print_short (found_path); path_free (path); if (found_path->total_weight < _found_min){ _stop_cnt = 0; #ifdef DEBUG printf (" update max: %lu -> %lu (weight:%lu, presence:%lu, eval:%lu, hash:%lu)\n", _found_min, found_path->total_weight, _stat_cut_by_weight, _stat_cut_by_presence, _stat_evaluated, _stat_found_hash); #endif _found_min = found_path->total_weight; } *path_r = found_path; return 1; } return 0; }
int shim_sisis_read(struct thread * thread) { struct sisis_listener *listener; int sisis_sock; uint16_t length, checksum; int already; u_int ifindex; struct shim_interface * si; struct in6_addr src; char src_buf[INET6_ADDRSTRLEN]; struct in6_addr dst; char dst_buf[INET6_ADDRSTRLEN]; zlog_notice("Reading packet from SISIS connection!"); /* first of all get listener pointer. */ listener = THREAD_ARG (thread); sisis_sock = THREAD_FD (thread); stream_reset(listener->ibuf); if ((already = stream_get_endp(listener->ibuf)) < SVZ_OUT_HEADER_SIZE) { ssize_t nbytes; if (((nbytes = stream_read_try (listener->ibuf, sisis_sock, SVZ_OUT_HEADER_SIZE-already)) == 0) || (nbytes == -1)) { return -1; } if(nbytes != (SVZ_OUT_HEADER_SIZE - already)) { listener->read_thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; } already = SVZ_OUT_HEADER_SIZE; } stream_set_getp(listener->ibuf, 0); length = stream_getw(listener->ibuf); checksum = stream_getw(listener->ibuf); if(length > STREAM_SIZE(listener->ibuf)) { struct stream * ns; zlog_warn("message size exceeds buffer size"); ns = stream_new(length); stream_copy(ns, listener->ibuf); stream_free(listener->ibuf); listener->ibuf = ns; } if(already < length) { ssize_t nbytes; if(((nbytes = stream_read_try(listener->ibuf, sisis_sock, length-already)) == 0) || nbytes == -1) { return -1; } if(nbytes != (length-already)) { listener->read_thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; } } unsigned int num_of_addrs = number_of_sisis_addrs_for_process_type(SISIS_PTYPE_RIBCOMP_OSPF6); unsigned int num_of_listeners = number_of_listeners(); zlog_notice("Number of addr: %d", num_of_addrs); zlog_notice("Number of listeners: %d", num_of_listeners); pthread_mutex_lock(&bmap_mutex); struct bmap * bmap = bmap_set(checksum); // if we added initially // set timer at which to recycle bmap // if there are no more processes sending data if(bmap->count == 0) { uint16_t * chcksum_ptr = malloc(sizeof(uint16_t)); *chcksum_ptr = checksum; listener->bmap_thread = thread_add_timer_msec (master, svz_sisis_clean_bmap, chcksum_ptr, 100); } bmap->count++; zlog_notice("# of streams %d for checksum %d with length %d", bmap->count, checksum, length); float received_ratio = (float)bmap->count/(float)num_of_addrs; stream_putw(listener->chksum_stream, checksum); if((received_ratio > 1.0/2.0) && !bmap->sent) { if(are_checksums_same()) { zlog_notice("Checksums are all the same"); if(primary_listener == NULL) primary_listener = listener; reset_checksum_streams(); svz_send(listener->ibuf); bmap->sent = 1; } else { zlog_notice("Checksums are not all the same"); stream_fifo_push(listener->dif, listener->ibuf); listener->dif_size++; } } else if(!bmap->sent) { zlog_notice("Not enough processes have sent their data; buffering..."); } else { zlog_notice("Data has already been sent..."); } if((bmap->count == num_of_addrs) && (bmap->sent)) { zlog_notice("Bmap no longer needed, freeing..."); bmap->count = 0; bmap->sent = 0; clear_checksum_streams(checksum); bmap_unset(checksum); } pthread_mutex_unlock(&bmap_mutex); if (sisis_sock < 0) /* Connection was closed during packet processing. */ return -1; /* Register read thread. */ // stream_reset(listener->ibuf); /* prepare for next packet. */ listener->read_thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; }