sound/core/seq/seq_queue.c

Source file repositories/reference/linux-study-clean/sound/core/seq/seq_queue.c

File Facts

System
Linux kernel
Corpus path
sound/core/seq/seq_queue.c
Extension
.c
Size
17874 bytes
Lines
711
Domain
Driver Families
Bucket
sound/core
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (! queue_list[i]) {
			queue_list[i] = q;
			q->queue = i;
			num_queues++;
			return i;
		}
	}
	return -1;
}

static struct snd_seq_queue *queue_list_remove(int id, int client)
{
	struct snd_seq_queue *q;

	guard(spinlock_irqsave)(&queue_list_lock);
	q = queue_list[id];
	if (q) {
		guard(spinlock)(&q->owner_lock);
		if (q->owner == client) {
			/* found */
			q->klocked = 1;
			queue_list[id] = NULL;
			num_queues--;
			return q;
		}
	}
	return NULL;
}

/*----------------------------------------------------------------*/

/* create new queue (constructor) */
static struct snd_seq_queue *queue_new(int owner, int locked)
{
	struct snd_seq_queue *q;

	q = kzalloc_obj(*q);
	if (!q)
		return NULL;

	spin_lock_init(&q->owner_lock);
	spin_lock_init(&q->check_lock);
	mutex_init(&q->timer_mutex);
	snd_use_lock_init(&q->use_lock);
	q->queue = -1;

	q->tickq = snd_seq_prioq_new();
	q->timeq = snd_seq_prioq_new();
	q->timer = snd_seq_timer_new();
	if (q->tickq == NULL || q->timeq == NULL || q->timer == NULL) {
		snd_seq_prioq_delete(&q->tickq);
		snd_seq_prioq_delete(&q->timeq);
		snd_seq_timer_delete(&q->timer);
		kfree(q);
		return NULL;
	}

	q->owner = owner;
	q->locked = locked;
	q->klocked = 0;

	return q;
}

/* delete queue (destructor) */
static void queue_delete(struct snd_seq_queue *q)
{
	/* stop and release the timer */
	mutex_lock(&q->timer_mutex);
	snd_seq_timer_stop(q->timer);
	snd_seq_timer_close(q);
	mutex_unlock(&q->timer_mutex);
	/* wait until access free */
	snd_use_lock_sync(&q->use_lock);
	/* release resources... */
	snd_seq_prioq_delete(&q->tickq);
	snd_seq_prioq_delete(&q->timeq);
	snd_seq_timer_delete(&q->timer);

	kfree(q);
}


/*----------------------------------------------------------------*/

/* delete all existing queues */
void snd_seq_queues_delete(void)
{
	int i;

Annotation

Implementation Notes