Exemple #1
0
static void * api_main_loop(void * itf) {

	rh_aout_api_itf self = (rh_aout_api_itf)itf;

    struct sles_api_instance * instance = (struct sles_api_instance *)itf;

    rh_aout_itf * array;

    int len;

    for(;;) {

    	poll_cmd_pipe(self);

        process_cmd_pipe(self);

        if( bucket_lock( instance->aout_itf_bucket, (void***)&array, &len ) == 0 ) {

            int i;
            for(i=0; i<len; i++)
                (*(array[i]))->update(array[i]);

            bucket_unlock( instance->aout_itf_bucket );
        }
    }

    return NULL;
}
Exemple #2
0
static int recv_consumed_buffer_cmd(rh_aout_api_itf self, rh_asmp_itf asmp_itf) {

	struct sles_api_instance * api_instance = (struct sles_api_instance *)self;

	int len;
	rh_aout_itf * array;
	int e = 0;

	if( bucket_lock( api_instance->aout_itf_bucket, (void***)&array, &len ) == 0 ) {

		int i;
		for(i=0; i<len; i++) {

			rh_asmp_itf audio_sample;
			rh_aout_itf audio_channel = array[i];

			if( (*audio_channel)->get_sample(audio_channel, &audio_sample) == 0 ) {

				if( audio_sample == asmp_itf ) {

					struct aout_instance * channel_instance =
						(struct aout_instance *)audio_channel;

					e = buffer_queue_return_drain_buffer( &channel_instance->bq );

					break;
				}
			}
		}

		bucket_unlock( api_instance->aout_itf_bucket );
	}

	return e;
}
Exemple #3
0
static int stop(rh_aout_api_itf self, rh_asmp_itf asmp_itf) {

    struct sles_api_instance * api_instance = (struct sles_api_instance *)self;

    int len;
    rh_aout_itf * array;
    int e = 0;

    if( bucket_lock( api_instance->aout_itf_bucket, (void***)&array, &len ) == 0 ) {

        int i;
        for(i=0; i<len; i++) {

            rh_asmp_itf audio_sample;
            rh_aout_itf audio_channel = array[i];

            if( (*audio_channel)->get_sample(audio_channel, &audio_sample) == 0 ) {

                if( audio_sample == asmp_itf ) {

                    e = (*audio_channel)->stop(audio_channel);
                    (*audio_channel)->set_sample(audio_channel, NULL);

                    break;
                }
            }
        }

        bucket_unlock( api_instance->aout_itf_bucket );
    }

    return e;
}
Exemple #4
0
/*
 * heap_get_bestfit_block --
 *	extracts a memory block of equal size index
 */
int
heap_get_bestfit_block(PMEMobjpool *pop, struct bucket *b,
	struct memory_block *m)
{
	if (bucket_lock(b) != 0)
		return EAGAIN;

	int i;
	uint32_t units = m->size_idx;
	for (i = 0; i < MAX_BUCKET_REFILL; ++i) {
		if (bucket_get_rm_block_bestfit(b, m) != 0)
			heap_ensure_bucket_filled(pop, b, 1);
		else
			break;
	}

	if (i == MAX_BUCKET_REFILL) {
		bucket_unlock(b);
		return ENOMEM;
	}

	if (units != m->size_idx)
		heap_recycle_block(pop, b, m, units);

	bucket_unlock(b);

	return 0;
}
Exemple #5
0
/*
 * heap_get_exact_block --
 *	extracts exactly this memory block and cuts it accordingly
 */
int
heap_get_exact_block(PMEMobjpool *pop, struct bucket *b,
	struct memory_block *m, uint32_t units)
{
	if (bucket_lock(b) != 0)
		return EAGAIN;

	if (bucket_get_rm_block_exact(b, *m) != 0)
		return ENOMEM;

	if (units != m->size_idx)
		heap_recycle_block(pop, b, m, units);

	bucket_unlock(b);

	return 0;
}
Exemple #6
0
static int close_all_channels(rh_aout_api_itf self) {

    struct sles_api_instance * api_instance = (struct sles_api_instance *)self;

    int len;
    rh_aout_itf * array;

    if( bucket_lock( api_instance->aout_itf_bucket, (void***)&array, &len ) == 0 ) {

        int i;
        for(i=0; i<len; i++)
			if(array[i])
				(*(array[i]))->close(&array[i]);

        bucket_unlock( api_instance->aout_itf_bucket );
    }

    return 0;
}
Exemple #7
0
static int _play(rh_aout_api_itf self, rh_asmp_itf asmp_itf, int loop_flag) {

    struct sles_api_instance * api_instance = (struct sles_api_instance *)self;

    int len;
    rh_aout_itf * array;
    int e = 0;

    for(;;) {
        int found = 0;
        if( bucket_lock( api_instance->aout_itf_bucket, (void***)&array, &len ) == 0 ) {

            int i;

            // is this sample already assigned to a channel? try to find its channel.

            for(i=0; i<len; i++) {

                rh_asmp_itf audio_sample;
                rh_aout_itf audio_channel = array[i];

                if( (*audio_channel)->get_sample(audio_channel, &audio_sample) == 0 ) {

                    if( audio_sample == asmp_itf ) {

                        found = 1;

                        if(loop_flag)
                            e = (*audio_channel)->loop(audio_channel);
                        else
                            e = (*audio_channel)->play(audio_channel);

                        break;
                    }
                }
            }

            if(!found) {

                // sample not yet assigned to a channel, find and empty one and assign it.

                for(i=0; i<len; i++) {

                    rh_asmp_itf audio_sample;
                    rh_aout_itf audio_channel = array[i];

                    if( (*audio_channel)->get_sample(audio_channel, &audio_sample) == 0 ) {

                        if( audio_sample == NULL ) {

                            found = 1;

                            (*audio_channel)->set_sample(audio_channel, asmp_itf);

                            (*audio_channel)->open(
                                audio_channel,
                                (*asmp_itf)->channels(asmp_itf),
                                (*asmp_itf)->samplerate(asmp_itf),
                                (*asmp_itf)->samplesize(asmp_itf) );

                            if(loop_flag)
                                e = (*audio_channel)->loop(audio_channel);
                            else
                                e = (*audio_channel)->play(audio_channel);

                            break;
                        }
                    }
                }
            }

            bucket_unlock( api_instance->aout_itf_bucket );
        }

        if(!found) {
            // no empty channels available, create a new channel and try again.
            if((e = add_channels(self, 1)) != 0)
                break;
        }
        else
            break;
    }

    return e;
}
Exemple #8
0
/*
 * heap_degrade_run_if_empty -- makes a chunk out of an empty run
 */
int
heap_degrade_run_if_empty(PMEMobjpool *pop, struct bucket *b,
	struct memory_block m)
{
	struct zone *z = &pop->heap->layout->zones[m.zone_id];
	struct chunk_header *hdr = &z->chunk_headers[m.chunk_id];
	ASSERT(hdr->type == CHUNK_TYPE_RUN);

	struct chunk_run *run = (struct chunk_run *)&z->chunks[m.chunk_id];

	int err = 0;
	if ((err = pthread_mutex_lock(heap_get_run_lock(pop, m))) != 0)
		return err;

	int i;
	for (i = 0; i < bucket_bitmap_nval(b) - 1; ++i)
		if (run->bitmap[i] != 0)
			goto out;

	if (run->bitmap[i] != bucket_bitmap_lastval(b))
		goto out;

	m.block_off = 0;
	m.size_idx = RUN_UNIT_MAX;
	uint32_t size_idx_sum = 0;
	while (size_idx_sum != bucket_bitmap_nallocs(b)) {
		if (bucket_get_rm_block_exact(b, m) != 0) {
			ERR("persistent and volatile state mismatched");
			ASSERT(0);
		}

		size_idx_sum += m.size_idx;

		m.block_off += RUN_UNIT_MAX;
		if (m.block_off + RUN_UNIT_MAX > bucket_bitmap_nallocs(b))
			m.size_idx = bucket_bitmap_nallocs(b) - m.block_off;
		else
			m.size_idx = RUN_UNIT_MAX;
	}

	struct bucket *defb = pop->heap->buckets[DEFAULT_BUCKET];
	if ((err = bucket_lock(defb)) != 0) {
		ERR("Failed to lock default bucket");
		ASSERT(0);
	}

	m.block_off = 0;
	m.size_idx = 1;
	heap_chunk_init(pop, hdr, CHUNK_TYPE_FREE, m.size_idx);

	uint64_t *mhdr;
	uint64_t op_result;
	struct memory_block fm =
			heap_free_block(pop, defb, m, &mhdr, &op_result);
	VALGRIND_ADD_TO_TX(mhdr, sizeof (*mhdr));
	*mhdr = op_result;
	VALGRIND_REMOVE_FROM_TX(mhdr, sizeof (*mhdr));
	pop->persist(mhdr, sizeof (*mhdr));

	if ((err = bucket_insert_block(defb, fm)) != 0) {
		ERR("Failed to update heap volatile state");
	}

	bucket_unlock(defb);

out:
	if (pthread_mutex_unlock(heap_get_run_lock(pop, m)) != 0) {
		ERR("Failed to release run lock");
		ASSERT(0);
	}

	return err;
}