#ifdef not
static char rcsid[] = "$Id: ompsm_lib.c,v 1.17 2001/04/25 15:14:50 a-hasega Exp $";
#endif
/* 
 * $RWC_Release: Omni-1.6 $
 * $RWC_Copyright:
 *  Omni Compiler Software Version 1.5-1.6
 *  Copyright (C) 2002 PC Cluster Consortium
 *  
 *  This software is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version
 *  2.1 published by the Free Software Foundation.
 *  
 *  Omni Compiler Software Version 1.0-1.4
 *  Copyright (C) 1999, 2000, 2001.
 *   Tsukuba Research Center, Real World Computing Partnership, Japan.
 *  
 *  Please check the Copyright and License information in the files named
 *  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
 *  Software release kit.
 *  
 *  
 *  $
 */
#include <stdlib.h>
#include "ompsm.h"
#include "../include/omp.h"

/*
 * OMP standard library function
 */

int omp_get_thread_num()
{
  if ((NOT_IN_PARALLEL) || (IN_NESTED_PARALLEL)) {
    return 0;
  } else {
    return _ompc_node_id;
  }
}

int omp_get_thread_num_() { return omp_get_thread_num(); }

int omp_get_num_threads()
{
  if ((NOT_IN_PARALLEL) || (IN_NESTED_PARALLEL)) {
    return 1;
  } else {
    return _ompc_n_node;
  }
}

int omp_get_num_threads_() { return omp_get_num_threads(); }

void omp_set_num_threads(int num)
{
    if(num <= 0){
	fprintf(stderr, "omp_set_num_threads: argument must be positive.\n");
	_ompc_fatal("ompc_set_num_threads");
    }
    if ( _ompc_max_threads < num ){
	fprintf(stderr, "set fail: %d exceeds max parallel number %d\n",
		num, _ompc_max_threads);
	_ompc_fatal("ompc_set_num_threads");
    }
    fprintf(stderr, "cannot change the number of thread in this mode\n");
}

void omp_set_num_threads_(int *num) {  omp_set_num_threads(*num); }

int omp_get_max_threads()
{
    return _ompc_num_threads;
}

int omp_get_max_threads_() { return omp_get_max_threads(); }

int omp_get_num_procs()
{
    return _ompc_n_proc;
}

int omp_get_num_procs_() { return omp_get_num_procs(); }

int omp_in_parallel()
{
    return (IN_PARALLEL);
}

int omp_in_parallel_() { return omp_in_parallel(); }

void omp_set_dynamic(int dynamic_thds)
{
  _ompc_dynamic = dynamic_thds;
  if (dynamic_thds) {
    fprintf(stderr,"dynamic allocation is not supported\n");
  }
}

void omp_set_dynamic_(int *dynamic_thds){ omp_set_dynamic(*dynamic_thds); }

int omp_get_dynamic()
{
    return 0 /*_ompc_dynamic*/; /* not implmented */
}

int omp_get_dynamic_() { return omp_get_dynamic(); }

void omp_set_nested(int n_nested)
{
  _ompc_nested = n_nested;
  if (n_nested) {
    fprintf(stderr,"nested parallelism is not supported\n");
  }
}

void omp_set_nested_(int *n_nested){ omp_set_nested(*n_nested); }

int omp_get_nested()
{
    return 0 /*_ompc_nested */; 
}

int omp_get_nested_() { return omp_get_nested(); }

/*
 * Lock Functions
 */
void omp_init_lock(omp_lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_INIT_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();
}

void omp_init_lock_(_omf77Lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_INIT_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();
}


void omp_destroy_lock(omp_lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_DESTROY_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();
}

void omp_destroy_lock_(_omf77Lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_DESTROY_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();
}


void omp_set_lock(omp_lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_LOCK_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();
}

void omp_set_lock_(_omf77Lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_LOCK_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();
}


void omp_unset_lock(omp_lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_UNLOCK_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();
}

void omp_unset_lock_(_omf77Lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_UNLOCK_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();
}


int omp_test_lock(omp_lock_t *lock)
{
  int ret;

  OMPSM_LIB_IN ();
  ret = OMPSM_TEST_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();

  return ret;
}

int omp_test_lock_(_omf77Lock_t *lock)
{
  int ret;

  OMPSM_LIB_IN ();
  ret = OMPSM_TEST_SLOCK((_ompc_lock_t *)lock);
  OMPSM_LIB_OUT ();

  return ret;
}


void 
omp_init_nest_lock(omp_nest_lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_INIT_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();
}

void 
omp_init_nest_lock_(_omf77Lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_INIT_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();
}


void 
omp_destroy_nest_lock(omp_nest_lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_DESTROY_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();
}

void 
omp_destroy_nest_lock_(_omf77Lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_DESTROY_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();
}


void 
omp_set_nest_lock(omp_nest_lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_LOCK_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();
}

void 
omp_set_nest_lock_(_omf77Lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_LOCK_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();
}


void omp_unset_nest_lock(omp_nest_lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_UNLOCK_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();
}

void omp_unset_nest_lock_(_omf77Lock_t *lock)
{
  OMPSM_LIB_IN ();
  OMPSM_UNLOCK_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();
}


int
omp_test_nest_lock(omp_nest_lock_t *lock)
{
  int ret;

  OMPSM_LIB_IN ();
  ret = OMPSM_TESTLOCK_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_OUT ();

  return ret;
}

int omp_test_nest_lock_(_omf77Lock_t *lock)
{
  int ret;

  OMPSM_LIB_IN ();
  ret = OMPSM_TESTLOCK_NLOCK((_ompc_nest_lock_t *)lock);
  OMPSM_LIB_IN ();

  return ret;
}


/*
 * global memory allocater
 */
void *
ompsm_galloc (int sz, int mode, int arg)
{
  void * ret;

  OMPSM_LIB_IN ();
  ret = (void *) OMPSM_GALLOC(sz, mode, arg);
  OMPSM_LIB_OUT ();

  return ret;
}


/* 
 * Timer routine
 */
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>


double omp_get_wtime()
{
    double t;
    struct timeval tv;
    gettimeofday(&tv, NULL);
    t = (double)(tv.tv_sec) + ((double)(tv.tv_usec))/1.0e6;
    return t ;
}


double omp_get_wtime_()
{
  return omp_get_wtime(); 
}


double omp_get_wtick()
{
  double t1,t2;
  t1 = omp_get_wtime();
 again:
  t2 = omp_get_wtime();
  if(t1 == t2) {
    goto again;
  }
  return t2-t1;
}


double omp_get_wtick_()
{
  return omp_get_wtick(); 
}

