Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}