コード例 #1
0
/******************************************************************************
* Function: jpeg_queue_abort
* Description: Aborts the queue object
* Input parameters:
*   p_queue            - The pointer to queue object to be aborted.
* Return values:
*     JPEGERR_SUCCESS
*     JPEGERR_ENULLPTR
* Notes: none
*****************************************************************************/
int  jpeg_queue_abort(jpeg_queue_t  *p_queue)
{
    jpeg_q_t *p_q;
    if(!p_queue) {
        JPEG_DBG_ERROR("jpeg_queue_abort: failed with empty queue pointer\n");
        return JPEGERR_ENULLPTR;
    }
    p_q = (jpeg_q_t *)(*p_queue);
    if (!p_q) {
        JPEG_DBG_ERROR("jpeg_queue_abort: failed with empty queue\n");
        return JPEGERR_ENULLPTR;
    }

    // Abort
    os_mutex_lock(&(p_q->mutex));
    if (p_q->state == QUEUE_STATE_TIMEWAIT)
    {
		// Change queue state
        p_q->state = QUEUE_STATE_ABORT;
		// Signal the dequeue function
        os_cond_signal(&(p_q->get_cond));
        while (QUEUE_STATE_ABORT == p_q->state)
		{
			// Wait unitil abort can be unblocked
			os_cond_wait(&(p_q->abort_cond), &(p_q->mutex));
		}
	}
    p_q->state = QUEUE_STATE_ABORTED;
    os_mutex_unlock(&(p_q->mutex));

    return JPEGERR_SUCCESS;
}
コード例 #2
0
/******************************************************************************
* Function: jpege_queue_enqueue
* Description: Enqueue a sequence of entry. It accepts the double pointer to the
*              entry to be enqueued and the number of entries in the
*              array, appends the entries sequentially to the tail of queue.
*              The number of entries to be enqueued is checked against
*              the valid slots of the queue, and
*              return fail if it is larger than the valid size.
* Input parameters:
*   queue              - The queue object.
*   pp_enqueue_buf     - The double pointer to enqueued entry(s) .
*   enqueue_entry_cnt  - The number of enqueued entry(s).
* Return values:
*     JPEGERR_SUCCESS
*     JPEGERR_EFAILED
*     JPEGERR_ENULLPTR
* (See jpegerr.h for description of error values.)
* Notes: none
*****************************************************************************/
int jpeg_queue_enqueue(
    jpeg_queue_t    queue,
    void            **pp_enqueue_entry,
    uint32_t        enqueue_entry_cnt)
{
    uint32_t        i, q_index;
    jpeg_q_t        *p_q;

    // Input parameter validation
    if ((!pp_enqueue_entry) || (!enqueue_entry_cnt))
    {
        JPEG_DBG_ERROR("jpeg_queue_enqueue: failed with input parameter check\n");
        return JPEGERR_EBADPARM;
    }
    p_q = (jpeg_q_t *)queue;
    if (!p_q)
    {
        JPEG_DBG_ERROR("jpeg_queue_enqueue: failed with empty queue pointer\n");
        return JPEGERR_ENULLPTR;
    }

    // Enqueue entry(s) to the queue
    os_mutex_lock(&(p_q->mutex));

    // Reject if the enqueued entry(s) are greater than valid slots left:
    // queue_cnt is current number of entries in queue,
    // it plus the number of entry to be enqueued can not exceed the
    // number of entries allowed inside queue.
    if ((p_q->queue_cnt + enqueue_entry_cnt) > MAX_QUEUE_NUM)
    {
        JPEG_DBG_ERROR("jpeg_queue_enqueue: enqueuing more entries than valid queue slots\n");
        os_mutex_unlock(&(p_q->mutex));
        return JPEGERR_EFAILED;
    }

    // Enqueue the entry
    for (i = 0; i < enqueue_entry_cnt; i++)
    {
        // Appends the entries sequentially to the tail of queue.
        q_index = QUEUE_MOD(p_q->queue_tail + i);
        p_q->queue_pool[q_index].p_data  = *(pp_enqueue_entry + i);
    }

    // Update the tail of queue and entries number
    p_q->queue_tail = QUEUE_MOD(p_q->queue_tail + enqueue_entry_cnt);
    p_q->queue_cnt  += enqueue_entry_cnt;

    // Signal that enqueuing entries is done
    os_cond_signal(&(p_q->get_cond));
    os_mutex_unlock(&(p_q->mutex));
    return JPEGERR_SUCCESS;
}
コード例 #3
0
ファイル: locked_queue.hpp プロジェクト: EQ4/genesis
    // returns 0 on success or GenesisErrorNoMem
    int __attribute__((warn_unused_result)) push(T item) {
        OsMutexLocker locker(_mutex);

        int err = ensure_capacity(_length + 1);
        if (err)
            return err;

        _length += 1;
        _items[_end] = item;
        _end = (_end + 1) % _capacity;
        os_cond_signal(_cond, _mutex);
        return 0;
    }
コード例 #4
0
static void run_write(void *userdata) {
    OrderedMapFile *omf = (OrderedMapFile *)userdata;

    for (;;) {
        OrderedMapFileBatch *batch = nullptr;
        omf->queue.shift(&batch);
        if (!batch || !omf->running)
            break;

        // compute transaction size
        int transaction_size = get_transaction_size(batch);
        omf->write_buffer.resize(transaction_size);

        uint8_t *transaction_ptr = (uint8_t*)omf->write_buffer.raw();
        write_uint32be(&transaction_ptr[4], transaction_size);
        write_uint32be(&transaction_ptr[8], batch->puts.length());
        write_uint32be(&transaction_ptr[12], batch->dels.length());

        int offset = TRANSACTION_METADATA_SIZE;
        for (int i = 0; i < batch->puts.length(); i += 1) {
            OrderedMapFilePut *put = &batch->puts.at(i);
            write_uint32be(&transaction_ptr[offset], put->key->size); offset += 4;
            write_uint32be(&transaction_ptr[offset], put->value->size); offset += 4;
            memcpy(&transaction_ptr[offset], put->key->data, put->key->size); offset += put->key->size;
            memcpy(&transaction_ptr[offset], put->value->data, put->value->size); offset += put->value->size;
        }
        for (int i = 0; i < batch->dels.length(); i += 1) {
            OrderedMapFileDel *del = &batch->dels.at(i);
            write_uint32be(&transaction_ptr[offset], del->key->size); offset += 4;
            memcpy(&transaction_ptr[offset], del->key->data, del->key->size); offset += del->key->size;
        }
        assert(offset == transaction_size);

        ordered_map_file_batch_destroy(batch);

        // compute crc32
        write_uint32be(&transaction_ptr[0], crc32(0, &transaction_ptr[4], transaction_size - 4));

        // append to file
        size_t amt_written = fwrite(transaction_ptr, 1, transaction_size, omf->file);
        if (amt_written != (size_t)transaction_size)
            panic("write to disk failed");

        os_mutex_lock(omf->mutex);
        os_cond_signal(omf->cond, omf->mutex);
        os_mutex_unlock(omf->mutex);
    }
}
コード例 #5
0
ファイル: obj_direct.c プロジェクト: GBuella/nvml
static void *
test_worker(void *arg)
{
	/* check before pool is closed, then let main continue */
	UT_ASSERTne(obj_direct(thread_oid), NULL);
	os_mutex_lock(&lock1);
	cond1 = 1;
	os_cond_signal(&sync_cond1);
	os_mutex_unlock(&lock1);

	/* wait for main thread to free & close, then check */
	os_mutex_lock(&lock2);
	while (!cond2)
		os_cond_wait(&sync_cond2, &lock2);
	os_mutex_unlock(&lock2);
	UT_ASSERTeq(obj_direct(thread_oid), NULL);
	return NULL;
}
コード例 #6
0
ファイル: audio_graph.cpp プロジェクト: EQ4/genesis
static void render_node_run(struct GenesisNode *node) {
    const struct GenesisNodeDescriptor *node_descriptor = genesis_node_descriptor(node);
    struct AudioGraph *ag = (struct AudioGraph *)genesis_node_descriptor_userdata(node_descriptor);
    struct GenesisPort *audio_in_port = genesis_node_port(node, 0);

    int input_frame_count = genesis_audio_in_port_fill_count(audio_in_port);
    float *in_buf = genesis_audio_in_port_read_ptr(audio_in_port);
    GenesisAudioFileStream *afs = ag->render_stream;


    int frames_left = ag->render_frame_count - ag->render_frame_index;
    int write_count = min(input_frame_count, frames_left);

    if (write_count > 0) {
        int err;
        if ((err = genesis_audio_file_stream_write(afs, in_buf, write_count))) {
            panic("TODO handle this error");
        }

        long new_index = ag->render_frame_index.load() + write_count;
        assert(new_index <= ag->render_frame_count);
        bool done = new_index == ag->render_frame_count;

        if (done) {
            if ((err = genesis_audio_file_stream_close(afs))) {
                panic("TODO handle this error");
            }
        }

        ag->render_frame_index.store(new_index);
        ag->play_head_changed_flag.clear();

        if (done) {
            os_cond_signal(ag->render_cond, nullptr);
        }

        genesis_audio_in_port_advance_read_ptr(audio_in_port, write_count);
    }
}
コード例 #7
0
ファイル: obj_direct.c プロジェクト: GBuella/nvml
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_direct");

	if (argc != 3)
		UT_FATAL("usage: %s [directory] [# of pools]", argv[0]);

	unsigned npools = ATOU(argv[2]);
	const char *dir = argv[1];
	int r;

	os_mutex_init(&lock1);
	os_mutex_init(&lock2);
	os_cond_init(&sync_cond1);
	os_cond_init(&sync_cond2);
	cond1 = cond2 = 0;

	PMEMobjpool **pops = MALLOC(npools * sizeof(PMEMobjpool *));
	UT_ASSERTne(pops, NULL);

	size_t length = strlen(dir) + MAX_PATH_LEN;
	char *path = MALLOC(length);
	for (unsigned i = 0; i < npools; ++i) {
		int ret = snprintf(path, length, "%s"OS_DIR_SEP_STR"testfile%d",
			dir, i);
		if (ret < 0 || ret >= length)
			UT_FATAL("!snprintf");
		pops[i] = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL,
				S_IWUSR | S_IRUSR);

		if (pops[i] == NULL)
			UT_FATAL("!pmemobj_create");
	}

	PMEMoid *oids = MALLOC(npools * sizeof(PMEMoid));
	UT_ASSERTne(oids, NULL);
	PMEMoid *tmpoids = MALLOC(npools * sizeof(PMEMoid));
	UT_ASSERTne(tmpoids, NULL);

	oids[0] = OID_NULL;
	UT_ASSERTeq(obj_direct(oids[0]), NULL);

	for (unsigned i = 0; i < npools; ++i) {
		oids[i] = (PMEMoid) {pops[i]->uuid_lo, 0};
		UT_ASSERTeq(obj_direct(oids[i]), NULL);

		uint64_t off = pops[i]->heap_offset;
		oids[i] = (PMEMoid) {pops[i]->uuid_lo, off};
		UT_ASSERTeq((char *)obj_direct(oids[i]) - off,
			(char *)pops[i]);

		r = pmemobj_alloc(pops[i], &tmpoids[i], 100, 1, NULL, NULL);
		UT_ASSERTeq(r, 0);
	}

	r = pmemobj_alloc(pops[0], &thread_oid, 100, 2, NULL, NULL);
	UT_ASSERTeq(r, 0);
	UT_ASSERTne(obj_direct(thread_oid), NULL);

	os_thread_t t;
	PTHREAD_CREATE(&t, NULL, test_worker, NULL);

	/* wait for the worker thread to perform the first check */
	os_mutex_lock(&lock1);
	while (!cond1)
		os_cond_wait(&sync_cond1, &lock1);
	os_mutex_unlock(&lock1);

	for (unsigned i = 0; i < npools; ++i) {
		UT_ASSERTne(obj_direct(tmpoids[i]), NULL);

		pmemobj_free(&tmpoids[i]);

		UT_ASSERTeq(obj_direct(tmpoids[i]), NULL);
		pmemobj_close(pops[i]);
		UT_ASSERTeq(obj_direct(oids[i]), NULL);
	}

	/* signal the worker that we're free and closed */
	os_mutex_lock(&lock2);
	cond2 = 1;
	os_cond_signal(&sync_cond2);
	os_mutex_unlock(&lock2);

	PTHREAD_JOIN(&t, NULL);
	os_cond_destroy(&sync_cond1);
	os_cond_destroy(&sync_cond2);
	os_mutex_destroy(&lock1);
	os_mutex_destroy(&lock2);
	FREE(pops);
	FREE(tmpoids);
	FREE(oids);

	DONE(NULL);
}
コード例 #8
0
ファイル: locked_queue.hpp プロジェクト: EQ4/genesis
 void wakeup_all() {
     OsMutexLocker locker(_mutex);
     _shutdown = true;
     os_cond_signal(_cond, _mutex);
 }
コード例 #9
0
/******************************************************************************
* Function: jpeg_queue_dequeue
* Description: Dequeue a entry from the queue.  It returns the double pointer
*              to the entry to be denqueued from the head of queue,
*              and accepts the number of time in mini-seconds that it conditional  .
*              waits if the queue if empty.
* Input parameters:
*   queue              - The queue object.
*   pp_dequeue_buffer  - The double pointer to dequeued entry.
*   ms                 - The time out in minisecond
* Return values:
*     JPEGERR_SUCCESS
*     JPEGERR_EFAILED
*     JPEGERR_ENULLPTR
*     JPEGERR_ETIMEDOUT
* Notes: none
*****************************************************************************/
int jpeg_queue_dequeue(
    jpeg_queue_t   queue,
    void           **pp_dequeue_entry,
    uint32_t       time_out_ms)
{
    uint32_t   q_index;
    jpeg_q_t   *p_q;
    int        rc;

    // Input parameter validation
    if (!pp_dequeue_entry)
    {
        JPEG_DBG_ERROR("jpeg_queue_dequeue: failed with input parameter check\n");
        return JPEGERR_EBADPARM;
    }
    p_q = (jpeg_q_t *)queue;
    if (!p_q)
    {
        JPEG_DBG_ERROR("jpeg_queue_dequeue: failed with empty queue pointer\n");
        return JPEGERR_ENULLPTR;
    }

    os_mutex_lock(&(p_q->mutex));

    if (p_q->state == QUEUE_STATE_ABORTED)
    {
        os_mutex_unlock(&(p_q->mutex));
        JPEG_DBG_ERROR("jpeg_queue_dequeue: Aborted \n");
        return JPEGERR_EFAILED;
    }

    // Check if queue is empty:
    // queue_cnt is current number of entries in queue.
    while (p_q->queue_cnt <= 0 && QUEUE_STATE_ABORT != p_q->state)
    {
        p_q->state = QUEUE_STATE_TIMEWAIT;
        // fails after conditional waiting time_out_ms in milli-seconds
        rc = os_cond_timedwait(&(p_q->get_cond), &(p_q->mutex), time_out_ms);
        if (JPEG_FAILED(rc))
        {
            JPEG_DBG_ERROR("jpeg_queue_dequeue: failed with empty queue\n");
            if (QUEUE_STATE_ABORT == p_q->state)
            {
                p_q->state = QUEUE_STATE_ABORTED;
                os_cond_signal(&(p_q->abort_cond));
            }
            p_q->state = QUEUE_STATE_IDLE;
            os_mutex_unlock(&(p_q->mutex));
            return rc;
        }
    }

    if (QUEUE_STATE_ABORT == p_q->state)
    {
        p_q->state = QUEUE_STATE_IDLE;
        // signal abort cond
        os_cond_signal(&(p_q->abort_cond));
        os_mutex_unlock(&(p_q->mutex));
        JPEG_DBG_ERROR("jpeg_queue_dequeue: failed with abort\n");
        return JPEGERR_EFAILED;
    }

    // Dequeue an entry from queue
    q_index = p_q->queue_head;

    // Dequeue the entry from the head of queue
    *pp_dequeue_entry = p_q->queue_pool[q_index].p_data;

    // Update the head of queue and entries number
    p_q->queue_head = QUEUE_MOD(p_q->queue_head + 1);
    p_q->queue_cnt  -= 1;
    p_q->state = QUEUE_STATE_IDLE;

    os_mutex_unlock(&(p_q->mutex));
    return JPEGERR_SUCCESS;
}