//////////////////////////////////////////////////////////////////////////
// Copyright (c) 2002 Xilinx, Inc.  All rights reserved.
//
//      XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A 
//  	COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
//  	ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR 
//  	STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
//  	IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE 
//  	FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.  
//  	XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO 
//  	THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO 
//  	ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE 
//  	FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY 
//  	AND FITNESS FOR A PARTICULAR PURPOSE.
// $Id: mutex.c,v 1.1.2.2 2003/03/14 22:22:37 mohan Exp $
//////////////////////////////////////////////////////////////////////////
/***************************************************************************/
/**
 * @file mutex.c 
 * 
 * Mutex handling routines.
 ***************************************************************************/
#include <sys/mutex.h>
#include <sys/process.h>

#ifdef CONFIG_MUTEX	/* Include the functions only if configured by user */

/**
 * Array of mutex structures. They are used to keep track of allocated
 * mutex. Also used for other bookkeeping operations on Mutex.
 */
mutex mutex_heap[MAX_MUTEX] ;	/* Memory for allocating mutex */ 
int *opb_semaphore_start_addr = (int *)0xffff3000 ;
extern signed char current_pid ;

void mutex_heap_init()
{
  unsigned int i = 0 ;
  for( ; i < MAX_MUTEX; i++ ){
    mutex_heap[i].mutex_id = -1 ;
    //mutex_heap[i].process_id = -1 ;
    //mutex_heap[i].mutex_val = 0 ; /* Need to do something.. */
  }
}

int mutex_init( mutex **mymutex )
{
  unsigned int i = 0 ;
  for( ; i < MAX_MUTEX; i++ ){
    if( mutex_heap[i].mutex_id == -1 ){
      mutex_heap[i].mutex_id = i ;
      /* etc, etc... */
      *mymutex = &mutex_heap[i] ;
      return 0 ;
    }
  }
  return -1 ;
}

int mutex_lock( mutex *mymutex )
{
  int mvalue = 0 ;
	
  if( mymutex->mutex_id == -1 ) return -1 ;
  while( !mvalue ) {
    mvalue = *(opb_semaphore_start_addr + mymutex->mutex_id) ;
  }
  mymutex->process_id = current_pid ;
  return 0 ;
}

int mutex_unlock( mutex *mymutex )
{
  if( mymutex->mutex_id == -1 ) return -1 ;
  if( mymutex->process_id != current_pid ) return -1 ;
  mymutex->process_id = -1 ;
  *(opb_semaphore_start_addr + mymutex->mutex_id) = 1 ;
  return 0 ;
}

int mutex_destroy( mutex *mymutex )
{
  if( mymutex->mutex_id == -1 ) return -1 ;
  mymutex->mutex_id = -1 ;
  return 0 ;
}

#endif
