コード例 #1
0
ファイル: pos-list.c プロジェクト: kunulee/f-stm
int t_pos_list_insert( char * name , void *_key, void * _val , unsigned long val_size, int thread_num){//, stm_tx_attr_t a){ 
	struct list_head * head ;
        struct list_node * node ;
        unsigned long * key , val ;
        int i = 0 ;
        key = (unsigned long *)_key ;
        val = (unsigned long *)_val ;

        head = (struct list_head *)pos_get_prime_object(name) ; //not changed// 
        lock() ;
        node = (struct list_node *)pos_malloc(name ,sizeof(struct list_node)) ;  
        unlock() ; //alloc not affect to consistency about list. 
        for( i = 0 ; i < KEY_SIZE ; i++ ){
                node->key[i] = key[i] ;
        }
        pos_clflush_cache_range(node->key , KEY_SIZE * sizeof(unsigned long));//one clflush
        lock() ;
        node->value = (unsigned long *)pos_malloc(name , val_size) ;
        unlock() ;

        pos_clflush_cache_range(&node->value , sizeof(node->value)); //two clflush
        memcpy(node->value , val , val_size) ;
        pos_clflush_cache_range( node->value ,val_size) ;
      
	TM_START(1 , RW) ;
                node->next = TM_LOAD( &head->head ) ;
                pos_clflush_cache_range(&node->next , sizeof(node->next)) ;
                TM_STORE( &head->head , node) ;
                pos_clflush_cache_range((void*)&head->head , sizeof(unsigned long)) ;
        TM_COMMIT ;

	return 0 ; 
}
コード例 #2
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_remove(intset_t *set, val_t val, thread_data_t *td)
{
  int result, i;
  bucket_t *b, *prev;

# ifdef DEBUG
  printf("++> set_remove(%d)\n", val);
  IO_FLUSH;
# endif

  if (!td) {
    i = HASH(val);
    prev = b = set->buckets[i];
    result = 0;
    while (b != NULL) {
      if (b->val == val) {
        result = 1;
        break;
      }
      prev = b;
      b = b->next;
    }
    if (result) {
      if (prev == b) {
        /* First element of bucket */
        set->buckets[i] = b->next;
      } else {
        prev->next = b->next;
      }
      free(b);
    }
  } else {
    TM_START(0, RW);
    i = HASH(val);
    prev = b = (bucket_t *)TM_LOAD(&set->buckets[i]);
    result = 0;
    while (b != NULL) {
      if (TM_LOAD(&b->val) == val) {
        result = 1;
        break;
      }
      prev = b;
      b = (bucket_t *)TM_LOAD(&b->next);
    }
    if (result) {
      if (prev == b) {
        /* First element of bucket */
        TM_STORE(&set->buckets[i], TM_LOAD(&b->next));
      } else {
        TM_STORE(&prev->next, TM_LOAD(&b->next));
      }
      /* Free memory (delayed until commit) */
      TM_FREE2(b, sizeof(bucket_t));
    }
    TM_COMMIT;
  }

  return result;
}
コード例 #3
0
ファイル: ns_turn_utils.c プロジェクト: SteppeChange/coturn
extern "C" void* debug_ptr_add_func(void *ptr, const char* function, int line) {

	TM_START();

	add_tm_ptr(ptr,id);

	return ptr;
}
コード例 #4
0
ファイル: ns_turn_utils.c プロジェクト: SteppeChange/coturn
void *turn_malloc_func(size_t sz, const char* function, int line) {

  TM_START();

  void *ptr = malloc(sz);
  
  add_tm_ptr(ptr,id);

  return ptr;
}
コード例 #5
0
ファイル: ns_turn_utils.c プロジェクト: SteppeChange/coturn
void turn_free_func(void *ptr, size_t sz, const char* function, int line) {

  UNUSED_ARG(sz);

  TM_START();

  del_tm_ptr(ptr,id);

  free(ptr);
}
コード例 #6
0
ファイル: ns_turn_utils.c プロジェクト: SteppeChange/coturn
void *turn_calloc_func(size_t number, size_t size, const char* function, int line) {
  
  TM_START();

  void *ptr = calloc(number,size);

  add_tm_ptr(ptr,id);

  return ptr;
}
コード例 #7
0
ファイル: ns_turn_utils.c プロジェクト: SteppeChange/coturn
char *turn_strdup_func(const char* s, const char* function, int line) {

  TM_START();

  char *ptr = strdup(s);

  add_tm_ptr(ptr,id);

  return ptr;
}
コード例 #8
0
ファイル: pos-list.c プロジェクト: kunulee/f-stm
/* flags == 0 normal flags == 1 lock flags == 2 stm flags == 3 selectvie */
int t_pos_list_remove( char *name , void *_key, int thread_num){ 
        struct list_head * head;
        struct list_node *node, *prev_node;
        unsigned long *key;
        unsigned long *k ;
        int i;
        struct list_node * next ;

        key = (unsigned long *)_key;
        head = (struct list_head *)pos_get_prime_object(name);

        TM_START(2, RW);
        prev_node = (struct list_node *)TM_LOAD(&head->head) ;
        next = (struct list_node *)TM_LOAD(&prev_node->next) ;
        // modified in here to set prev_node 
        while( prev_node ){
                if( (next == NULL ) && ( prev_node != NULL ) ){
                        //last node ;
                        #if (KEONWOO_DEBUG == 1)
                        PR_DEBUG("Last Node\n") ;
                        #endif
                        if( key_cmp(prev_node->key , key)==1){
                                node = (struct list_node *)
                                        TM_LOAD(&prev_node->next);
                                if(node==NULL) node = 0 ;
                                //head->head = node ; 
                                //TM_STORE(prev_node , node ) ;         
                                TM_STORE(&head->head , node) ;
                                PR_DEBUG("prev_node : %p\n" , prev_node) ;
                                break;
                        }
                }
               if(key_cmp(next->key , key) == 1){ // if match
                        node = ( struct list_node *)TM_LOAD(&next->next) ;
                        TM_STORE(&prev_node->next , node ) ;
                        pos_clflush_cache_range( &prev_node->next, sizeof(struct list_node)) ;
                        goto ret;
                }
                prev_node = next ;
                next = (struct list_node *)TM_LOAD(&next->next) ;
        }

        ret:
        TM_COMMIT ;
        // after commit
/*      if( next != NULL ){ 
        r_lock() ;
        pos_free(name , next->value) ;
        pos_free(name , next) ;
        r_unlock() ;    
        }*/
        return 0;
} 
コード例 #9
0
ファイル: ns_turn_utils.c プロジェクト: SteppeChange/coturn
void *turn_realloc_func(void *ptr, size_t old_sz, size_t new_sz, const char* function, int line) {

  UNUSED_ARG(old_sz);

  TM_START();

  if(ptr)
	  del_tm_ptr(ptr,id);

  ptr = realloc(ptr,new_sz);

  add_tm_ptr(ptr,id);

  return ptr;
}
コード例 #10
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_add(intset_t *set, val_t val, thread_data_t *td)
{
  int result, i;
  bucket_t *b, *first;

# ifdef DEBUG
  printf("++> set_add(%d)\n", val);
  IO_FLUSH;
# endif

  if (!td) {
    i = HASH(val);
    first = b = set->buckets[i];
    result = 1;
    while (b != NULL) {
      if (b->val == val) {
        result = 0;
        break;
      }
      b = b->next;
    }
    if (result) {
      set->buckets[i] = new_entry(val, first, 0);
    }
  } else {
    TM_START(0, RW);
    i = HASH(val);
    first = b = (bucket_t *)TM_LOAD(&set->buckets[i]);
    result = 1;
    while (b != NULL) {
      if (TM_LOAD(&b->val) == val) {
        result = 0;
        break;
      }
      b = (bucket_t *)TM_LOAD(&b->next);
    }
    if (result) {
      TM_STORE(&set->buckets[i], new_entry(val, first, 1));
    }
    TM_COMMIT;
  }

  return result;
}
コード例 #11
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_remove(intset_t *set, val_t val, thread_data_t *td)
{
  int result;

# ifdef DEBUG
  printf("++> set_remove(%d)\n", val);
  IO_FLUSH;
# endif

  if (!td) {
    result = rbtree_delete((rbtree_t *)set, (void *)val);
  } else {
    TM_START(2, RW);
    result = TMrbtree_delete((rbtree_t *)set, (void *)val);
    TM_COMMIT;
  }

  return result;
}
コード例 #12
0
void *count(void *ptr) {
    long i, max = MAX_COUNT/NUM_THREADS;
    int tid = ((struct tdata *) ptr)->tid;
    int c;

    stm_init_thread();

    for (i=0; i < max; i++) {
        TM_START(0, 0);
        c = stm_load_int(&counter);
        if (i % 10 == 0) {
            c++;
            stm_store_int(&counter, c);
        }
        TM_COMMIT;
    }
    printf("End %d counter: %d\n", tid, counter);
    stm_exit_thread();
}
コード例 #13
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_contains(intset_t *set, val_t val, thread_data_t *td)
{
  int result, i;
  node_t *node, *next;
  val_t v;

# ifdef DEBUG
  printf("++> set_contains(%d)\n", val);
  IO_FLUSH;
# endif

  if (!td) {
    node = set->head;
    for (i = set->level; i >= 0; i--) {
      next = node->forward[i];
      while (next->val < val) {
        node = next;
        next = node->forward[i];
      }
    }
    node = node->forward[0];
    result = (node->val == val);
  } else {
    TM_START(0, RO);
    v = VAL_MIN; /* Avoid compiler warning (should not be necessary) */
    node = set->head;
    for (i = TM_LOAD(&set->level); i >= 0; i--) {
      next = (node_t *)TM_LOAD(&node->forward[i]);
      while (1) {
        v = TM_LOAD(&next->val);
        if (v >= val)
          break;
        node = next;
        next = (node_t *)TM_LOAD(&node->forward[i]);
      }
    }
    result = (v == val);
    TM_COMMIT;
  }

  return result;
}
コード例 #14
0
ファイル: pos-hashtable-stm.c プロジェクト: kunulee/f-stm
int
stm_hashtable_insert(char *name, struct hashtable *h, unsigned long *k, unsigned long *v,unsigned long v_size){ 
	unsigned int index ; 	
        struct entry * e;
        hash_lock() ;
        e = (struct entry *)pos_malloc( name , sizeof(struct entry)) ;
        if( e == NULL) PR_DEBUG("enull\n") ;
        e->v = (unsigned long *)pos_malloc( name , v_size) ;

//	TM_START(1, RW) ; 	
        if( e->v == NULL)PR_DEBUG("e->v null\n") ;
        hash_unlock() ;
	
	TM_START(1, RW) ; 		

//        e->h = hash(h , k) ;
//        memcpy(e->k , k , sizeof(unsigned long)*KEY_SIZE) ;
//        memcpy(e->v , v, v_size) ;
	TM_STORE(&e->h , hash(h,k)) ; 	
	TM_STORE(&e->k , k ) ; 	
	TM_STORE(&e->v , v ) ;
//        TM_START(1 , RW) ;
                int entrycount = (int)TM_LOAD(&h->entrycount) ;
                int loadlimit = (int)TM_LOAD(&h->loadlimit) ;
                TM_STORE(&h->entrycount , entrycount+1) ;
                if( entrycount+1 > loadlimit ){
//                      h_lock();
//                      shashtable_expand(name ,h) ;   
//                      h_unlock() ;    
                }
                e->h = hash( h , k ) ;
                index = indexFor((int)TM_LOAD(&h->tablelength) , e->h);
                e->next = (struct entry *)TM_LOAD(&h->table[index]);
                pos_clflush_cache_range(e , sizeof(struct entry));
                pos_clflush_cache_range(e->v , v_size) ;
                TM_STORE(&h->table[index] , e) ;
                pos_clflush_cache_range(&h->table[index] , sizeof(unsigned long)) ;
        TM_COMMIT ;
        return ;

} 
コード例 #15
0
ファイル: pos-hashtable-stm.c プロジェクト: kunulee/f-stm
int 
stm_hashtable_remove( char *name , struct hashtable *h, unsigned long *k){ 
	struct entry *prev, *b ; 
	unsigned long hashvalue , index ; 	
        int result = 0 ; // whether find node or not find.

        TM_START(0 ,RW) ; // transaction start 
        hashvalue = hash( h , k );
        int tablelength = (int)TM_LOAD(&h->tablelength) ;
        index = indexFor( tablelength , hashvalue ) ;
        prev = b = (struct entry *)TM_LOAD(&h->table[index]) ;
        result = 0 ;
        while( b != NULL ){
                if(( hashvalue == b->h ) && default_key_eq_fn( k , b->k )){
                        result = 1 ;
                        goto ret;
                }
                prev = b ;
                b = (struct entry *)TM_LOAD(&b->next) ;
        }
        ret:
        if(result){ // matching entry so end normaly.
                if( prev == b ){
                        TM_STORE( &h->table[index] , TM_LOAD(&b->next)) ;
                        pos_clflush_cache_range(&h->table[index] , sizeof(struct entry*)) ;
			TM_STORE( &h->entrycount , (unsigned long)(h->entrycount-1)) ;
			pos_clflush_cache_range(&h->entrycount , sizeof(unsigned long)) ; 	
                }
                else{
                         TM_STORE(&prev->next , TM_LOAD(&b->next)) ;
                        pos_clflush_cache_range(&prev->next , sizeof(struct entry*));
			TM_STORE( &h->entrycount , (unsigned long)(h->entrycount-1)) ;
			pos_clflush_cache_range(&h->entrycount , sizeof(unsigned long)) ; 	
                }
                //pos_free part.
        }
        TM_COMMIT ;
        return result ;
} 
コード例 #16
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_contains(intset_t *set, val_t val, thread_data_t *td)
{
  int result, i;
  bucket_t *b;

# ifdef DEBUG
  printf("++> set_contains(%d)\n", val);
  IO_FLUSH;
# endif

  if (!td) {
    i = HASH(val);
    b = set->buckets[i];
    result = 0;
    while (b != NULL) {
      if (b->val == val) {
        result = 1;
        break;
      }
      b = b->next;
    }
  } else {
    TM_START(0, RO);
    i = HASH(val);
    b = (bucket_t *)TM_LOAD(&set->buckets[i]);
    result = 0;
    while (b != NULL) {
      if (TM_LOAD(&b->val) == val) {
        result = 1;
        break;
      }
      b = (bucket_t *)TM_LOAD(&b->next);
    }
    TM_COMMIT;
  }

  return result;
}
コード例 #17
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_add(intset_t *set, val_t val, thread_data_t *td)
{
  int result, i;
  node_t *update[MAX_LEVEL + 1];
  node_t *node, *next;
  level_t level, l;
  val_t v;

# ifdef DEBUG
  printf("++> set_add(%d)\n", val);
  IO_FLUSH;
# endif

  if (!td) {
    node = set->head;
    for (i = set->level; i >= 0; i--) {
      next = node->forward[i];
      while (next->val < val) {
        node = next;
        next = node->forward[i];
      }
      update[i] = node;
    }
    node = node->forward[0];

    if (node->val == val) {
      result = 0;
    } else {
      l = random_level(set, main_seed);
      if (l > set->level) {
        for (i = set->level + 1; i <= l; i++)
          update[i] = set->head;
        set->level = l;
      }
      node = new_node(val, l, 0);
      for (i = 0; i <= l; i++) {
        node->forward[i] = update[i]->forward[i];
        update[i]->forward[i] = node;
      }
      result = 1;
    }
  } else {
    TM_START(1, RW);
    v = VAL_MIN; /* Avoid compiler warning (should not be necessary) */
    node = set->head;
    level = TM_LOAD(&set->level);
    for (i = level; i >= 0; i--) {
      next = (node_t *)TM_LOAD(&node->forward[i]);
      while (1) {
        v = TM_LOAD(&next->val);
        if (v >= val)
          break;
        node = next;
        next = (node_t *)TM_LOAD(&node->forward[i]);
      }
      update[i] = node;
    }

    if (v == val) {
      result = 0;
    } else {
      l = random_level(set, td->seed);
      if (l > level) {
        for (i = level + 1; i <= l; i++)
          update[i] = set->head;
        TM_STORE(&set->level, l);
      }
      node = new_node(val, l, 1);
      for (i = 0; i <= l; i++) {
        node->forward[i] = (node_t *)TM_LOAD(&update[i]->forward[i]);
        TM_STORE(&update[i]->forward[i], node);
      }
      result = 1;
    }
    TM_COMMIT;
  }

  return result;
}
コード例 #18
0
ファイル: pos-list.c プロジェクト: kunulee/f-stm
int t_t_pos_list_insert( char * name , void *_key, void * _val , unsigned long val_size, int thread_num){ 
	//normal: // not thread mechanism
	if( flags_num & NORMAL_ROUTINE ){ 
		#if (KEONWOO_DEBUG == 1)
		PR_DEBUG("[%s] [%d]:key [%d]:val\n", __func__, *(int*)_key , *(int*)_val ) ; 	 
		#endif 
		//Normal Mechanism start here.	
		struct list_head * head ; 	
		struct list_node * node ; 	
		unsigned long * key, * val ; 	
		int i ; 	
	
		key = (unsigned long *)_key ; 	
		val = (unsigned long *)_val ; 	
		head = (struct list_head *)pos_get_prime_object(name); 
		if( head == NULL ){ 
			PR_DEBUG("[head point] is NULL\n") ;	
			//Error exit return -1; 
			return -1; 	
		}	
		lock() ;
		node = (struct list_node *)pos_malloc(name, sizeof(struct list_node)) ; 	
		/* TM_POS_MALLOC(name , sizeof(struct list_node)); */ 
		unlock() ; 	
		if( node == NULL ){ 
			PR_DEBUG("[node address] is NULL\n") ; 	
			//Error exit return -1; 
			return -1; 	
		}
		for( i = 0 ; i < KEY_SIZE ; i++ ){ 
			node->key[i] = key[i] ; 	
		}
		pos_clflush_cache_range(node->key, KEY_SIZE*sizeof(unsigned long));

        	lock() ;
        	node->value = (unsigned long *)pos_malloc(name, val_size);
		/* TM_POS_MALLOC(name , val_size) */ 
       		unlock() ;
		if( node->value == NULL ){ 
			PR_DEBUG("[node->valude address] is NULL\n");	
			// Error exit return -1;
			return -1; 	
		}
   		pos_clflush_cache_range(&node->value, sizeof(node->value));
	       	memcpy(node->value, val, val_size);
    	   	pos_clflush_cache_range(node->value, val_size);
	
		if( flags_num & LOCK_ROUTINE ){ 
			#if (KEONWOO_DEBUG == 1)
			PR_DEBUG("[LOCK()] called\n") ; 	
			#endif 
			llock() ; 
			node->next = head->head;  	
			pos_clflush_cache_range(&node->next , sizeof(node->next)) ; 
		 	head->head = node ; 	 
			pos_clflush_cache_range((void*)&head->head , sizeof(unsigned long)) ; 
			lunlock() ;
			return 0;   	
		}else if( flags_num & STM_ROUTINE ){ 
			TM_START(1,RW ) ; 	
			#if (KEONWOO_DEBUG == 1) 
			PR_DEBUG("[TM_START]\n") ; 
			#endif 
			node->next = head->head ; 	
			pos_clflush_cache_range(&node->next , sizeof(node->next)) ; 	
			PR_DEBUG("head->head : %p\n" , head->head) ; 	
			TM_STORE(&head->head , node) ; 	
			PR_DEBUG("a head->head : %p\n", head->head) ; 
			pos_clflush_cache_range((void*)&head->head, sizeof(unsigned long)) ; 		
			TM_COMMIT ; 
			return 0 ; 
		}else{ // flags_num & STM_NORMAL 
			#if (KEONWOO_DEBUG == 1)
			PR_DEBUG("[Normal]\n") ;
			#endif 
			node->next = head->head ; 
			pos_clflush_cache_range(&node->next , sizeof(node->next)) ; 	
			head->head = node ; 	
			pos_clflush_cache_range(&head->head , sizeof(unsigned long)) ; 	
			return  0;
		}
		return -1; 
	}else{ 
		PR_DEBUG("[flags_num] not set\n") ; 	
		return -1;
	}
}  
コード例 #19
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_contains(intset_t *set, val_t val, thread_data_t *td)
{
  int result;
  node_t *prev, *next;
  val_t v;

# ifdef DEBUG
  printf("++> set_contains(%d)\n", val);
  IO_FLUSH;
# endif

  if (td == NULL) {
    prev = set->head;
    next = prev->next;
    while (next->val < val) {
      prev = next;
      next = prev->next;
    }
    result = (next->val == val);
  } else if (td->unit_tx == 0) {
    TM_START(0, RO);
    prev = (node_t *)TM_LOAD(&set->head);
    next = (node_t *)TM_LOAD(&prev->next);
    while (1) {
      v = TM_LOAD(&next->val);
      if (v >= val)
        break;
      prev = next;
      next = (node_t *)TM_LOAD(&prev->next);
    }
    result = (v == val);
    TM_COMMIT;
  } 
#ifndef TM_COMPILER
  else {
    /* Unit transactions */
    stm_word_t ts, start_ts, val_ts;
  restart:
    start_ts = stm_get_clock();
    /* Head node is never removed */
    prev = (node_t *)TM_UNIT_LOAD(&set->head, &ts);
    next = (node_t *)TM_UNIT_LOAD(&prev->next, &ts);
    if (ts > start_ts)
      start_ts = ts;
    while (1) {
      v = TM_UNIT_LOAD(&next->val, &val_ts);
      if (val_ts > start_ts) {
        /* Restart traversal (could also backtrack) */
        goto restart;
      }
      if (v >= val)
        break;
      prev = next;
      next = (node_t *)TM_UNIT_LOAD(&prev->next, &ts);
      if (ts > start_ts) {
        /* Verify that node has not been modified (value and pointer are updated together) */
        TM_UNIT_LOAD(&prev->val, &val_ts);
        if (val_ts > start_ts) {
          /* Restart traversal (could also backtrack) */
          goto restart;
        }
        start_ts = ts;
      }
    }
    result = (v == val);
  }
#endif /* TM_COMPILER */

  return result;
}
コード例 #20
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_add(intset_t *set, val_t val, thread_data_t *td)
{
  int result;
  node_t *prev, *next;
  val_t v;

# ifdef DEBUG
  printf("++> set_add(%d)\n", val);
  IO_FLUSH;
# endif

  if (td == NULL) {
    prev = set->head;
    next = prev->next;
    while (next->val < val) {
      prev = next;
      next = prev->next;
    }
    result = (next->val != val);
    if (result) {
      prev->next = new_node(val, next, 0);
    }
  } else if (td->unit_tx == 0) {
    TM_START(1, RW);
    prev = (node_t *)TM_LOAD(&set->head);
    next = (node_t *)TM_LOAD(&prev->next);
    while (1) {
      v = TM_LOAD(&next->val);
      if (v >= val)
        break;
      prev = next;
      next = (node_t *)TM_LOAD(&prev->next);
    }
    result = (v != val);
    if (result) {
      TM_STORE(&prev->next, new_node(val, next, 1));
    }
    TM_COMMIT;
  } 
#ifndef TM_COMPILER
  else {
    /* Unit transactions */
    stm_word_t ts, start_ts, val_ts;
  restart:
    start_ts = stm_get_clock();
    /* Head node is never removed */
    prev = (node_t *)TM_UNIT_LOAD(&set->head, &ts);
    next = (node_t *)TM_UNIT_LOAD(&prev->next, &ts);
    if (ts > start_ts)
      start_ts = ts;
    while (1) {
      v = TM_UNIT_LOAD(&next->val, &val_ts);
      if (val_ts > start_ts) {
        /* Restart traversal (could also backtrack) */
        goto restart;
      }
      if (v >= val)
        break;
      prev = next;
      next = (node_t *)TM_UNIT_LOAD(&prev->next, &ts);
      if (ts > start_ts) {
        /* Verify that node has not been modified (value and pointer are updated together) */
        TM_UNIT_LOAD(&prev->val, &val_ts);
        if (val_ts > start_ts) {
          /* Restart traversal (could also backtrack) */
          goto restart;
        }
        start_ts = ts;
      }
    }
    result = (v != val);
    if (result) {
      node_t *n = new_node(val, next, 0);
      /* Make sure that there are no concurrent updates to that memory location */
      if (!TM_UNIT_STORE(&prev->next, n, &ts)) {
        free(n);
        goto restart;
      }
    }
  }
#endif /* ! TM_COMPILER */

  return result;
}
コード例 #21
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_remove(intset_t *set, val_t val, thread_data_t *td)
{
  int result;
  node_t *prev, *next;
  val_t v;
  node_t *n;

# ifdef DEBUG
  printf("++> set_remove(%d)\n", val);
  IO_FLUSH;
# endif

  if (td == NULL) {
    prev = set->head;
    next = prev->next;
    while (next->val < val) {
      prev = next;
      next = prev->next;
    }
    result = (next->val == val);
    if (result) {
      prev->next = next->next;
      free(next);
    }
  } else if (td->unit_tx == 0) {
    TM_START(2, RW);
    prev = (node_t *)TM_LOAD(&set->head);
    next = (node_t *)TM_LOAD(&prev->next);
    while (1) {
      v = TM_LOAD(&next->val);
      if (v >= val)
        break;
      prev = next;
      next = (node_t *)TM_LOAD(&prev->next);
    }
    result = (v == val);
    if (result) {
      n = (node_t *)TM_LOAD(&next->next);
      TM_STORE(&prev->next, n);
      /* Free memory (delayed until commit) */
      TM_FREE2(next, sizeof(node_t));
    }
    TM_COMMIT;
  } 
#ifndef TM_COMPILER
  else {
    /* Unit transactions */
    stm_word_t ts, start_ts, val_ts;
  restart:
    start_ts = stm_get_clock();
    /* Head node is never removed */
    prev = (node_t *)TM_UNIT_LOAD(&set->head, &ts);
    next = (node_t *)TM_UNIT_LOAD(&prev->next, &ts);
    if (ts > start_ts)
      start_ts = ts;
    while (1) {
      v = TM_UNIT_LOAD(&next->val, &val_ts);
      if (val_ts > start_ts) {
        /* Restart traversal (could also backtrack) */
        goto restart;
      }
      if (v >= val)
        break;
      prev = next;
      next = (node_t *)TM_UNIT_LOAD(&prev->next, &ts);
      if (ts > start_ts) {
        /* Verify that node has not been modified (value and pointer are updated together) */
        TM_UNIT_LOAD(&prev->val, &val_ts);
        if (val_ts > start_ts) {
          /* Restart traversal (could also backtrack) */
          goto restart;
        }
        start_ts = ts;
      }
    }
    result = (v == val);
    if (result) {
      /* Make sure that the transaction does not access versions more recent than start_ts */
      TM_START_TS(start_ts, restart);
      n = (node_t *)TM_LOAD(&next->next);
      TM_STORE(&prev->next, n);
      /* Free memory (delayed until commit) */
      TM_FREE2(next, sizeof(node_t));
      TM_COMMIT;
    }
  }
#endif /* ! TM_COMPILER */
  return result;
}
コード例 #22
0
ファイル: ns_turn_utils.c プロジェクト: SteppeChange/coturn
extern "C" void debug_ptr_del_func(void *ptr, const char* function, int line) {

	TM_START();

	del_tm_ptr(ptr,id);
}
コード例 #23
0
ファイル: intset.c プロジェクト: digideskio/tinystm
static int set_remove(intset_t *set, val_t val, thread_data_t *td)
{
  int result, i;
  node_t *update[MAX_LEVEL + 1];
  node_t *node, *next;
  level_t level;
  val_t v;

# ifdef DEBUG
  printf("++> set_remove(%d)\n", val);
  IO_FLUSH;
# endif

  if (!td) {
    node = set->head;
    for (i = set->level; i >= 0; i--) {
      next = node->forward[i];
      while (next->val < val) {
        node = next;
        next = node->forward[i];
      }
      update[i] = node;
    }
    node = node->forward[0];

    if (node->val != val) {
      result = 0;
    } else {
      for (i = 0; i <= set->level; i++) {
        if (update[i]->forward[i] == node)
          update[i]->forward[i] = node->forward[i];
      }
      while (set->level > 0 && set->head->forward[set->level]->forward[0] == NULL)
        set->level--;
      free(node);
      result = 1;
    }
  } else {
    TM_START(2, RW);
    v = VAL_MIN; /* Avoid compiler warning (should not be necessary) */
    node = set->head;
    level = TM_LOAD(&set->level);
    for (i = level; i >= 0; i--) {
      next = (node_t *)TM_LOAD(&node->forward[i]);
      while (1) {
        v = TM_LOAD(&next->val);
        if (v >= val)
          break;
        node = next;
        next = (node_t *)TM_LOAD(&node->forward[i]);
      }
      update[i] = node;
    }
    node = (node_t *)TM_LOAD(&node->forward[0]);

    if (v != val) {
      result = 0;
    } else {
      for (i = 0; i <= level; i++) {
        if ((node_t *)TM_LOAD(&update[i]->forward[i]) == node)
          TM_STORE(&update[i]->forward[i], (node_t *)TM_LOAD(&node->forward[i]));
      }
      i = level;
      while (i > 0 && (node_t *)TM_LOAD(&set->head->forward[i]) == set->tail)
        i--;
      if (i != level)
        TM_STORE(&set->level, i);
      /* Free memory (delayed until commit) */
      TM_FREE2(node, sizeof(node_t) + node->level * sizeof(node_t *));
      result = 1;
    }
    TM_COMMIT;
  }

  return result;
}
コード例 #24
0
ファイル: pos-list.c プロジェクト: kunulee/f-stm
int t_t_pos_list_remove( char * name , void *_key){ 
	if( flags_num & NORMAL_ROUTINE ){ 
		struct list_head * head ; 	
		struct list_node * node , ** prev_node ; 	
		// stm prev
		struct list_node * sprev_node ; 	
		struct list_node * next ;
		unsigned long * key ; 	
		
		key = (unsigned long *)_key ; 	
		head = (struct list_head *)pos_get_prime_object(name) ; 	
		
		if( flags_num & LOCK_ROUTINE ){ // if lock flags settings. 
			llock() ; //lock 
			prev_node = &head->head ; 	
			node = head->head ; 	
			while(node){ 
				if( key_cmp( node->key , key ) == 1 ){ 
					*prev_node = node->next ; 	
					PR_DEBUG("%p\n" , node->next) ;
					/* 
					pos_free(name , node->value) ; 	
					pos_free(name , node) ; 	
					*/
					pos_clflush_cache_range( prev_node , sizeof(struct list_node)) ; 	

					lunlock() ; //unlock 
					return 0 ; 	
				}
				prev_node = &node->next ; 	
				node = node->next ; 	
			}
			lunlock() ; //unlock
			return -1;	
		}else if( flags_num & STM_ROUTINE ){ //if stm flags settings. 
			/*PR_DEBUG("DA\n") ;
			TM_START(2,RW) ; 
			struct list_node * p , * n ; 	
			p = (struct list_node *)TM_LOAD(&head->head) ; 		
			PR_DEBUG("A\n") ;
			n = (struct list_node *)TM_LOAD(&p->next) ; 	
			PR_DEBUG("D\n") ; 	
			PR_DEBUG("p = %p , n = %p\n" , p, n ) ; 
			while(1){ 
				if(key_cmp(n->key , key ) == 1){
					PR_DEBUG("%d fount\n" , *(int*)p->key) ;	
					break; 	
				}
				p = n ; 	
				n = (struct list_node *)TM_LOAD(&p->next);
			}
			PR_DEBUG("DD\n") ; 
			node = (struct list_node *)TM_LOAD(&n->next);	
			PR_DEBUG("DD\n") ; 
			TM_STORE(&p->next , node) ; 	
			PR_DEBUG("DD\n") ; 
			//TM_POS_FREE// 
			TM_COMMIT ; */ 
			TM_START(2,RW) ; 	
			#if (KEONWOO_DEBUG == 1 )
			PR_DEBUG("[TM_START]\n") ; 	
			#endif 
			sprev_node = (struct list_node *)TM_LOAD(&head->head); 	
			next = (struct list_node*)TM_LOAD(&sprev_node->next); 	
//			while( next || ((next==NULL)&&(sprev_node!=NULL))){ 
			while(sprev_node){ 
				if( (next==NULL) && (sprev_node!=NULL) ){
					
					PR_DEBUG("LastNode\n");
					if( key_cmp( sprev_node->key , key ) == 1){
						PR_DEBUG("[%d] [%d]\n" , *(int*)sprev_node->key,*(int*)key);
						PR_DEBUG("IN HERE\n") ;
						node = (struct list_node*)TM_LOAD(&sprev_node->next);
						if( node == NULL ) node = 0 ;
						PR_DEBUG("node ; %p\n" , node) ;
						//sprev_node = node ; 
						//head->head = node ; 	
						TM_STORE(&head->head,node);
						PR_DEBUG("head->head: %p\n" , head->head ) ;	
						//pos_clflush_cache_range(&sprev_node->next,sizeof(struct list_node)) ; 		
						break ;
					}
				}
				if( key_cmp( next->key , key ) == 1 ){ 
					node = (struct list_node *)TM_LOAD(&next->next); 	
					TM_STORE(&sprev_node->next ,node ); 	
					pos_clflush_cache_range(&sprev_node->next ,sizeof(struct list_node)) ; 	
					break; // out to while loop.
				}
				sprev_node = next ; 	
				next = (struct list_node *)TM_LOAD(&next->next);
			}
			 
			TM_COMMIT ; 	
			#if (KEONWOO_DEBUG == 1) 
			PR_DEBUG("[TM_COMMIT]\n") ;
			#endif 
		}
	}
}