/*
 *  ALSA sequencer Memory Manager
 *  Copyright (c) 1998 by Frank van de Pol <frank@vande-pol.demon.nl>
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#ifndef __SND_SEQ_MEMORYMGR_H
#define __SND_SEQ_MEMORYMGR_H

#include "../../include/seq_kernel.h"

typedef struct pool pool_t;

/* container for sequencer event (internal use)*/
typedef struct snd_seq_event_cell_t {
	struct snd_seq_event_cell_t *ptr_l;	/* pointer to left leaf */
	struct snd_seq_event_cell_t *ptr_r;	/* pointer to right leaf */
	pool_t *pool;				/* used pool */
	snd_seq_event_t event;
} snd_seq_event_cell_t;

/* design note: the pool is a contigious block of memory, if we dynamicly
   want to add additional cells to the pool be better store this in another
   pool as we need to know the base address of the pool when releasing
   memory. */

struct pool {
	snd_seq_event_cell_t *ptr;	/* pointer to start of pool */
	snd_seq_event_cell_t *free;	/* pointer to the head of the free list */

	int total_elements;
	int available;

	/* statistics */
	int min_available;
	int event_alloc_nopool;
	int event_alloc_failures;
	int event_alloc_success;

	spinlock_t lock;
};

/* release this cell */
extern void snd_seq_cell_free(snd_seq_event_cell_t* cell);

/* return pointer to cell, NULL on failure */
extern snd_seq_event_cell_t *snd_seq_cell_alloc(pool_t *pool);

/* duplicate event, NULL on failure */
extern snd_seq_event_cell_t *snd_seq_event_dup(pool_t *pool, snd_seq_event_t *event, int atomic);
extern snd_seq_event_cell_t *snd_seq_event_dup_from_user(pool_t *pool, snd_seq_event_t *event);

/* duplicate event cell, NULL on failure */
extern snd_seq_event_cell_t *snd_seq_cell_dup(pool_t *pool, snd_seq_event_cell_t *event, int atomic);

/* return number of unused (free) cells */
extern int snd_seq_unused_cells(pool_t *pool);

/* return total number of allocated cells */
extern int snd_seq_total_cells(pool_t *pool);

/* init pool - allocate events */
extern int snd_seq_pool_init(pool_t *pool, int events);

/* done pool - free events */
extern int snd_seq_pool_done(pool_t *pool);

/* create pool */
extern pool_t *snd_seq_pool_new(void);

/* remove pool */
extern int snd_seq_pool_delete(pool_t **pool);

/* init memory */
extern void snd_sequencer_memory_init(void);
            
/* release event memory */
extern void snd_sequencer_memory_done(void);

#endif
