/* $Header: /sys/linux-0.96a/kernel/semop.c,v 0.3 1992/06/01 01:57:34 root Exp root $
 * kernel/semop.c: Provides mutual exclusion using schedule() and sleep()
 *
 * $Log: semop.c,v $
 * Revision 0.3  1992/06/01  01:57:34  root
 * Added copyright notice.
 *
 * Revision 0.2  1992/05/31  22:17:02  root
 * binary semops seem to work now. still have to implement generic semops.
 *
 * Revision 0.1  1992/05/31  14:08:57  root
 * Initial revision.
 *
 * Copyright 1992 by H. H. Bergman.
 */

/* XXX maybe put optional time out on sema locks? */

#include <asm/semop.h>

/* DMA channels 0..7
 * 0 is reserved (DRAM refresh??). Not sure about 4.
 */
semaphore sema_dma_channel[8] = { {0, NULL},
				  {1, NULL},
				  {1, NULL},
				  {1, NULL},
				  {0, NULL},
				  {1, NULL},
				  {1, NULL},
				  {1, NULL}
};

/* First allocate a DMA channel, then if it is a slave channel,
 * then use this sema to avoid concurrent use of DMA channels 1..3
 */
semaphore sema_dma_slave = {1, NULL};

/* not sure whether this is needed for DMA channels 4..7 */
semaphore sema_dma_master = {1, NULL};



/* generic P(s,r):
 *
 *	do {
 *	    n := 0;
 *	    do {
 *		< n, s.avail := s.avail, n >;		(* indivisible swap *)
 *		sleep_on(s.queue);
 *	    } while (n<r);	(* must grab all 'r' elems at once *)
 *	    n := n-r;
 *	
 *	    while (n>0) {
 *		< n, s.avail := s.avail, n >;
 *		.... etcetera
 */

/* lock 'req' elements or sleep if not enough available */
void semaP(semaphore * sem, unsigned int req)
{
	unsigned int n;

} /* semaP */

/* release 'rel' elements */
void semaV(semaphore * sem, unsigned int rel)
{

} /* semaV */


#if 0		/* 1 for testing */

semaphore t, s = {0x12345678, NULL};
volatile int x = 0x87654321;

void sleep_on(struct task_struct **p)
{
	printf("sleep");
}

void wake_up(struct task_struct **p)
{
	printf("wakeup");
}

void panic(const char *s)
{
	printf("panic: %s\n", s);
}


int main (void)
{
	printf("before: s.avail = %x, x = %x\n", s.avail, x);
	x = sema_atomic_swap(&(s.avail), x);
	printf("after : s.avail = %x, x = %x\n", s.avail, x);

	sema_init(&t, 1);
	printf("after init: avail=%x, queue=%x\n", t.avail, (unsigned int) t.waitqueue);
	bsemaP(&t);
	printf("after bsemaP: avail=%x, queue=%x\n", t.avail, (unsigned int) t.waitqueue);
	bsemaV(&t);
	printf("after bsemaV 1: avail=%x, queue=%x\n", t.avail, (unsigned int) t.waitqueue);
	bsemaV(&t);
	printf("after bsemaV 2: avail=%x, queue=%x\n", t.avail, (unsigned int) t.waitqueue);
	exit(0);
}

#endif

