Beispiel #1
0
gu_to_t *gu_to_create (int len, gu_seqno_t seqno)
{
    gu_to_t *ret;

    assert (seqno >= 0);

    if (len <= 0) {
        gu_error ("Negative length parameter: %d", len);
        return NULL;
    }

    ret = GU_CALLOC (1, gu_to_t);
    
    if (ret) {

        /* Make queue length a power of 2 */
        ret->qlen = 1;
        while (ret->qlen < len) {
            // unsigned, can be bigger than any integer
            ret->qlen = ret->qlen << 1;
        }
        ret->qmask = ret->qlen - 1;
        ret->seqno = seqno;

        ret->queue = GU_CALLOC (ret->qlen, to_waiter_t);

        if (ret->queue) {
            ssize_t i;
            for (i = 0; i < ret->qlen; i++) {
                to_waiter_t *w = ret->queue + i;
#ifdef TO_USE_SIGNAL
                gu_cond_init (&w->cond, NULL);
#else
                pthread_mutex_init (&w->mtx, NULL);
#endif
                w->state       = RELEASED;
            }
            gu_mutex_init (&ret->lock, NULL);
        
            return ret;
        }
        gu_free (ret);
    }

    return NULL;
}
gcs_sm_t*
gcs_sm_create (long len, long n)
{
    if ((len < 2 /* 2 is minimum */) || (len & (len - 1))) {
        gu_error ("Monitor length parameter is not a power of 2: %ld", len);
        return NULL;
    }

    if (n < 1) {
        gu_error ("Invalid monitor concurrency parameter: %ld", n);
        return NULL;
    }

    size_t sm_size = sizeof(gcs_sm_t) +
        len * sizeof(((gcs_sm_t*)(0))->wait_q[0]);

    gcs_sm_t* sm = static_cast<gcs_sm_t*>(gu_malloc(sm_size));

    if (sm) {
        sm_init_stats (&sm->stats);
        gu_mutex_init (&sm->lock, NULL);
#ifdef GCS_SM_GRAB_RELEASE
        gu_cond_init  (&sm->cond, NULL);
        sm->cond_wait   = 0;
#endif /* GCS_SM_GRAB_RELEASE */
        sm->wait_q_len  = len;
        sm->wait_q_mask = sm->wait_q_len - 1;
        sm->wait_q_head = 1;
        sm->wait_q_tail = 0;
        sm->users       = 0;
        sm->entered     = 0;
        sm->ret         = 0;
#ifdef GCS_SM_CONCURRENCY
        sm->cc          = n; // concurrency param.
#endif /* GCS_SM_CONCURRENCY */
        sm->pause       = false;
        memset (sm->wait_q, 0, sm->wait_q_len * sizeof(sm->wait_q[0]));
    }

    return sm;
}
/* Creates FIFO object. Since it practically consists of array of (void*),
 * the length can be chosen arbitrarily high - to minimize the risk
 * of overflow situation.
 */
gcs_fifo_lite_t* gcs_fifo_lite_create (size_t length, size_t item_size)
{
    gcs_fifo_lite_t* ret = NULL;
    uint64_t l = 1;

    /* check limits */
    if (length < 1 || item_size < 1)
        return NULL;

    /* Find real length. It must be power of 2*/
    while (l < length) l = l << 1;

    if (l * item_size > (uint64_t)GU_LONG_MAX) {
        gu_error ("Resulting FIFO size %lld exceeds signed limit: %lld",
                  (long long)(l*item_size), (long long)GU_LONG_MAX);
        return NULL;
    }

    ret = GU_CALLOC (1, gcs_fifo_lite_t);

    if (ret) {
        ret->length    = l;
        ret->item_size = item_size;
	ret->mask      = ret->length - 1;
        ret->closed    = true;
	ret->queue     = gu_malloc (ret->length * item_size);

	if (ret->queue) {
	    gu_mutex_init (&ret->lock,     NULL);
	    gu_cond_init  (&ret->put_cond, NULL);
	    gu_cond_init  (&ret->get_cond, NULL);
	    /* everything else must be initialized to 0 by calloc */
	}
	else {
	    gu_free (ret);
	    ret = NULL;
	}
    }

    return ret;
}