Beispiel #1
0
static void swRingBuffer_collect(swRingBuffer *object)
{
    swRingBuffer_item *item;
    sw_atomic_t *free_count = &object->free_count;

    int count = object->free_count;
    int i;
    uint32_t n_size;

    for (i = 0; i < count; i++)
    {
        item = (swRingBuffer_item *) ((char *) object->memory + object->collect_offset);
        if (item->lock == 0)
        {
            n_size = item->length + sizeof(swRingBuffer_item);

            object->collect_offset += n_size;

            if (object->collect_offset + sizeof(swRingBuffer_item) > object->size
                    || object->collect_offset >= object->size)
            {
                object->collect_offset = 0;
                object->status = 0;
            }
            sw_atomic_fetch_sub(free_count, 1);
        }
        else
        {
            break;
        }
    }
}
Beispiel #2
0
PHP_METHOD(swoole_atomic, sub)
{
    long sub_value = 1;
    sw_atomic_t *atomic = swoole_get_object(getThis());

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &sub_value) == FAILURE)
    {
        RETURN_FALSE;
    }

    RETURN_LONG(sw_atomic_fetch_sub(atomic, (uint32_t) sub_value));
}
Beispiel #3
0
int swRingQueue_pop(swRingQueue *queue, void **ele)
{
	if (!(queue->num > 0))
		return -1;
	int cur_head_index = queue->head;
	char * cur_head_flag_index = queue->flags + cur_head_index;

	while (!sw_atomic_cmp_set(cur_head_flag_index, 2, 3))
	{
		cur_head_index = queue->head;
		cur_head_flag_index = queue->flags + cur_head_index;
	}
	//TODO 取模操作可以优化
	int update_head_index = (cur_head_index + 1) % queue->size;
	sw_atomic_cmp_set(&queue->head, cur_head_index, update_head_index);
	*ele = *(queue->data + cur_head_index);

	sw_atomic_fetch_sub(cur_head_flag_index, 3);
	sw_atomic_fetch_sub(&queue->num, 1);
	return 0;
}
Beispiel #4
0
static void* swThreadPool_loop(void *arg)
{
    swThreadParam *param = arg;
    swThreadPool *pool = param->object;

    int id = param->pti;
    int ret;
    void *task;

    if (pool->onStart)
    {
        pool->onStart(pool, id);
    }

    while (SwooleG.running)
    {
        pool->cond.lock(&pool->cond);

        if (pool->shutdown)
        {
            pool->cond.unlock(&pool->cond);
            swTrace("thread [%d] will exit\n", id);
            pthread_exit(NULL);
        }

        if (pool->task_num == 0)
        {
            pool->cond.wait(&pool->cond);
        }

        swTrace("thread [%d] is starting to work\n", id);

        ret = swRingQueue_pop(&pool->queue, &task);
        pool->cond.unlock(&pool->cond);

        if (ret >= 0)
        {
            sw_atomic_t *task_num = &pool->task_num;
            sw_atomic_fetch_sub(task_num, 1);

            pool->onTask(pool, (void *) task, ret);
        }
    }

    if (pool->onStop)
    {
        pool->onStop(pool, id);
    }

    pthread_exit(NULL);
    return NULL;
}
Beispiel #5
0
int swTableRow_del(swTable *table, char *key, int keylen)
{
    swTableRow *row = swTable_hash(table, key, keylen);
    uint32_t crc32 = swoole_crc32(key, keylen);
    sw_atomic_t *lock = &row->lock;

    //no exists
    if (!row->active)
    {
        return SW_ERR;
    }

    sw_spinlock(lock);

    if (row->next == NULL)
    {
        if (row->crc32 == crc32)
        {
            table->rows_list[row->list_index] = NULL;
            if (table->iterator->skip_count > table->compress_threshold)
            {
                swTable_compress_list(table);
            }
            bzero(row, sizeof(swTableRow));
            goto delete_element;
        }
        else
        {
            goto not_exists;
        }
    }
    else
    {
        swTableRow *tmp = row;
        swTableRow *prev = NULL;

        while (tmp)
        {
            if (tmp->crc32 == crc32)
            {
                break;
            }
            prev = tmp;
            tmp = tmp->next;
        }

        if (tmp == NULL)
        {
            not_exists:
            sw_spinlock_release(lock);
            return SW_ERR;
        }

        //when the deleting element is root, we should move the first element's data to root,
        //and remove the element from the collision list.
        if (tmp == row)
        {
            tmp = tmp->next;
            row->next = tmp->next;

            if (table->iterator->skip_count > table->compress_threshold)
            {
                swTable_compress_list(table);
            }

            memcpy(row->data, tmp->data, table->item_size);
        }

        if (prev)
        {
            prev->next = tmp->next;
        }
        table->lock.lock(&table->lock);
        bzero(tmp, sizeof(swTableRow));
        table->pool->free(table->pool, tmp);
        table->lock.unlock(&table->lock);
    }

    delete_element:
    sw_atomic_fetch_sub(&(table->row_num), 1);
    sw_spinlock_release(lock);

    return SW_OK;
}
Beispiel #6
0
int swTableRow_del(swTable *table, char *key, int keylen)
{
    if (keylen > SW_TABLE_KEY_SIZE)
    {
        keylen = SW_TABLE_KEY_SIZE;
    }

    swTableRow *row = swTable_hash(table, key, keylen);
    //no exists
    if (!row->active)
    {
        return SW_ERR;
    }

    swTableRow_lock(row);
    if (row->next == NULL)
    {
        if (strncmp(row->key, key, keylen) == 0)
        {
            bzero(row, sizeof(swTableRow) + table->item_size);
            goto delete_element;
        }
        else
        {
            goto not_exists;
        }
    }
    else
    {
        swTableRow *tmp = row;
        swTableRow *prev = NULL;

        while (tmp)
        {
            if ((strncmp(tmp->key, key, keylen) == 0))
            {
                break;
            }
            prev = tmp;
            tmp = tmp->next;
        }

        if (tmp == NULL)
        {
            not_exists:
            swTableRow_unlock(row);
            return SW_ERR;
        }

        //when the deleting element is root, we should move the first element's data to root,
        //and remove the element from the collision list.
        if (tmp == row)
        {
            tmp = tmp->next;
            row->next = tmp->next;
            memcpy(row->key, tmp->key, strlen(tmp->key));
            memcpy(row->data, tmp->data, table->item_size);
        }
        if (prev)
        {
            prev->next = tmp->next;
        }
        table->lock.lock(&table->lock);
        bzero(tmp, sizeof(swTableRow) + table->item_size);
        table->pool->free(table->pool, tmp);
        table->lock.unlock(&table->lock);
    }

    delete_element:
    sw_atomic_fetch_sub(&(table->row_num), 1);
    swTableRow_unlock(row);

    return SW_OK;
}
Beispiel #7
0
int swTableRow_del(swTable *table, char *key, int keylen)
{
    swTableRow *row = swTable_hash(table, key, keylen);
    uint32_t crc32 = swoole_crc32(key, keylen);
    sw_atomic_t *lock = &row->lock;
    int i = 0;

    sw_spinlock(lock);
    if (row->active)
    {
        for (;; i++)
        {
            if (row->crc32 == crc32)
            {
                if (i > 0)
                {
                    table->lock.lock(&table->lock);
                    table->pool->free(table->pool, row);
                    table->lock.unlock(&table->lock);
                }
                break;
            }
            else if (row->next == NULL)
            {
                sw_spinlock_release(lock);
                return SW_ERR;
            }
            else
            {
                row = row->next;
            }
        }

#ifdef SW_TABLE_USE_LINKED_LIST
        if (row->list_prev != NULL)
        {
            row->list_prev->list_next = row->list_next;
        }
        else
        {
            table->head = row->list_next;
        }

        if (row->list_next != NULL)
        {
            row->list_next->list_prev = row->list_prev;
        }
        else
        {
            table->tail = row->list_prev;
        }

        if (table->iterator->tmp_row == row)
        {
            table->iterator->tmp_row = row->list_next;
        }
#endif
    }

    if (row->active)
    {
        sw_atomic_fetch_sub(&(table->row_num), 1);
    }

    row->active = 0;
    sw_spinlock_release(lock);
    return SW_OK;
}