Ejemplo n.º 1
0
/**
 * Increments the global reference count of a managed value
 *
 * @pre h != NULL
 *
 * @post h->global_rc = h->global_rc@pre + 1
 *
 * @param Handle to update
 */
void PICC_handle_incr_ref_count(PICC_Handle *h)
{
    /* #ifdef CONTRACT_PRE_INV */
    /*     //inv */
    /*     PICC_Channel_inv(channel); */
    /* #endif */

    #ifdef CONTRACT_PRE
        //pre
        ASSERT(h != NULL );
    #endif

    #ifdef CONTRACT_POST
        // capture
        // int global_rc_at_pre = h->global_rc;
    #endif

    LOCK_HANDLE(h);
    h->global_rc++;
    RELEASE_HANDLE(h);

    /* #ifdef CONTRACT_POST_INV */
    /*     //inv */
    /*     PICC_Channel_inv(channel); */
    /* #endif */

    /* #ifdef CONTRACT_POST */
    /*     //post */
    /*     ASSERT(channel->global_rc == global_rc_at_pre + 1 );  */
    /*     // cannot be asserted ! as the lock is released we don't have any garanty */
    /* #endif */
}
Ejemplo n.º 2
0
static void *process_thread(void *par)
{
	struct genhistdb_struct *handle = (struct genhistdb_struct *)par;
	pthread_t self_thread;
	Node *node;
	hist_t *hist = NULL;
	int self_ind;
	if(!handle)
	      goto bailout;

	pthread_barrier_wait(&handle->barrier);

	if(handle->error != 0) {
		goto bailout;
	}
	self_thread = pthread_self();
	for(self_ind = 0; self_ind < handle->nr_threads; self_ind++) {
		if(handle->threads[self_ind] == self_thread)
		      break;
	}
	if(self_ind == handle->nr_threads) {
		printf("ERROR! I am not one of the started threads for this handle\n");
		goto bailout;
	}
	node = handle->per_thread_list[self_ind];

	while(node) {
		hist = gen_hist(node->name);
		LOCK_HANDLE(handle, self_ind);
		handle->completed++;
		if(!hist) {
			printf("Hist generation for %s failed\n", node->name);
		} else {
			handle->updated++;
			memcpy(&handle->hist_list[handle->hist_len], hist, sizeof(hist_t));
			free(hist);
			handle->hist_len++;
		}
		UNLOCK_HANDLE(handle, self_ind);
		node = node->next;
	}
bailout:
	pthread_exit(NULL);
}
Ejemplo n.º 3
0
/**
 * Decrements the global reference count of a managed value
 *
 * @pre h != NULL
 *
 * @post h->global_rc = h->global_rc@pre - 1
 *
 * @param Handle to update
 */
void PICC_handle_dec_ref_count(PICC_Handle **h)
{
    /* #ifdef CONTRACT_PRE_INV */
    /*     //inv */
    /*     PICC_Channel_inv(*channel); */
    /* #endif */

    #ifdef CONTRACT_PRE
        //pre
        ASSERT(*h != NULL );
    #endif

    #ifdef CONTRACT_POST
        // capture
        // int global_rc_at_pre = (*h)->global_rc;
    #endif

	// I think there is a problem here: what happens if global_rc is equal to one
	// and another thread was about to increment it but lost the race to acquire the lock ?
	//
	// moreover, for now the lock is alocated in the channel/handle with the previous
	// case in mind we cannot free it in the reclaim
	// I think a solution would be to have a pool of Lock witch contain the lock itself
	// and the value it's suposed to lock
	//
	// kind of:
	// struct{
	//   atomic_int cpt;
	//   void *content;
        // }
	//
	// in the function lock_alloc we would keep track of all the locks and we could
	// reuse the ones that have cpt == 0 && content == NULL
	//

    LOCK_HANDLE(*h);
    (*h)->global_rc--;

    if ((*h)->global_rc == 0) {
	RELEASE_HANDLE(*h);

	ALLOC_ERROR(reclaim_error);
        (*h)->reclaim(*h, &reclaim_error);
	*h = NULL;
        if (HAS_ERROR(reclaim_error))
            CRASH(&reclaim_error);
    }
    else{
	RELEASE_HANDLE(*h);
    }

    /* #ifdef CONTRACT_POST_INV */
    /*     if (*h != NULL) */
    /*         PICC_Channel_inv(*channel); */
    /* #endif */

    /* #ifdef CONTRACT_POST */
    /*     if(global_rc_at_pre > 1) */
    /*         ASSERT((*channel)->global_rc == global_rc_at_pre - 1 ); */
    //cannot be asserted see incr for the same comment
    /* #endif */
}