/**CFile*******************************************************************
  PackageName [mc]
  Synopsis    [Package 'mc' provides a symbolic ACTLW model checker]

  FileName    [mcThread.c]
  Revision    [$Revision: 76 $]
  Date        [$Date: 2013-04-26 14:26:09 +0200 (pet, 26 apr 2013) $]
  Author      [Robert Meolic (meolic@uni-mb.si)]
  Description [File mcThread.c contains functions needed if using
               threads.]
  SeeAlso     [mc.h, mcInt.h]

  Copyright   [This file is part of EST (Efficient Symbolic Tools).
               Copyright (C) 2003, 2013
               UM-FERI, Smetanova ulica 17, SI-2000 Maribor, Slovenia

               EST 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.

               EST 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., 51 Franklin Street, Fifth Floor,
               Boston, MA 02110-1301 USA.]
  ************************************************************************/

#include "mcInt.h"

#ifdef USETHREADS

#include <pthread.h>
#include <sched.h>

/*-----------------------------------------------------------------------*/
/* Constant declarations                                                 */
/*-----------------------------------------------------------------------*/

/*-----------------------------------------------------------------------*/
/* Variable declarations                                                 */
/*-----------------------------------------------------------------------*/

/**AutomaticStart*********************************************************/

/*-----------------------------------------------------------------------*/
/* Static function prototypes                                            */
/*-----------------------------------------------------------------------*/

/**AutomaticEnd***********************************************************/

/*-----------------------------------------------------------------------*/
/* Definition of thread functions                                        */
/*-----------------------------------------------------------------------*/

/**Function****************************************************************
  Synopsis    []
  Description []
  SideEffects []
  SeeAlso     []
  ************************************************************************/

void
McCheckACTL_Thr(void *args)
{
  struct funparam {
    int par;
    Est_String name;
    Est_String f;
    int parserSettings;
    int *thread_done;
  };

  int par;
  Est_String name;
  Est_String f;
  int parserSettings;

  par = ((struct funparam *) args)->par;
  name = ((struct funparam *) args)->name;
  f = ((struct funparam *) args)->f;
  parserSettings = ((struct funparam *) args)->parserSettings;

  Mc_CheckACTL(par,name,f,parserSettings);

  *((struct funparam *) args)->thread_done = 1;

  return;
}

/**Function****************************************************************
  Synopsis    []
  Description []
  SideEffects []
  SeeAlso     []
  ************************************************************************/

void
McCheckACTLString_Thr(void *args)
{
  struct funparam {
    int par;
    Est_String name;
    Est_String f;
    int parserSettings;
    int *thread_done;
  };

  int par;
  Est_String name;
  Est_String f;
  int parserSettings;

  par = ((struct funparam *) args)->par;
  name = ((struct funparam *) args)->name;
  f = ((struct funparam *) args)->f;
  parserSettings = ((struct funparam *) args)->parserSettings;

  Mc_CheckACTLString(par,name,f,parserSettings);

  *((struct funparam *) args)->thread_done = 1;

  return;
}

/**Function****************************************************************
  Synopsis    []
  Description []
  SideEffects []
  SeeAlso     []
  ************************************************************************/

void
McCheckACTLFile_Thr(void *args)
{
  struct funparam {
    int par;
    Est_String name;
    Est_String f;
    int parserSettings;
    int *thread_done;
  };

  int par;
  Est_String name;
  Est_String f;
  int parserSettings;

  par = ((struct funparam *) args)->par;
  name = ((struct funparam *) args)->name;
  f = ((struct funparam *) args)->f;
  parserSettings = ((struct funparam *) args)->parserSettings;

  Mc_CheckACTLFile(par,name,f,parserSettings);

  *((struct funparam *) args)->thread_done = 1;

  return;
}

/*-----------------------------------------------------------------------*/
/* Definition of exported functions                                      */
/*-----------------------------------------------------------------------*/

/*-----------------------------------------------------------------------*/
/* Definition of internal functions                                      */
/*-----------------------------------------------------------------------*/

/**Function****************************************************************
  Synopsis    []
  Description []
  SideEffects []
  SeeAlso     []
  ************************************************************************/

void
Mc_CheckACTL_Thr(int par, Est_String name, Est_String f, int parserSettings)
{
  struct {
    int par;
    Est_String name;
    Est_String f;
    int parserSettings;
    int *thread_done;
  } funparam;

  pthread_t thread;
  pthread_attr_t attr;
  struct sched_param param;

  int thread_done;

  /*
  pthread_attr_init(&attr);
  pthread_attr_setstacksize(&attr,262144);
  pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);
  pthread_attr_setschedpolicy(&attr,SCHED_OTHER);
  param.sched_priority = sched_get_priority_min(SCHED_OTHER);
  pthread_attr_setschedparam(&attr, &param);
  */

  funparam.par = par;
  funparam.name = name;
  funparam.f = f;
  funparam.parserSettings = parserSettings;
  funparam.thread_done = &thread_done;

  /* POSIX */
  thread_done = 0;
  if (pthread_create(&thread,NULL,(void *)&McCheckACTL_Thr,&funparam)) {
    printf("Error: pthread_create\n");
  } else {
    sched_yield();
    while (!thread_done) {
#ifdef TCLOUT
      Tcl_DoOneEvent(TCL_DONT_WAIT);
#endif
    }
    if (pthread_join(thread,NULL)) {
      printf("Error: pthread_join\n");
    }
  }

  return;
}


/**Function****************************************************************
  Synopsis    []
  Description []
  SideEffects []
  SeeAlso     []
  ************************************************************************/

void
Mc_CheckACTLString_Thr(int par, Est_String name, Est_String f, int parserSettings)
{
  struct {
    int par;
    Est_String name;
    Est_String f;
    int parserSettings;
    int *thread_done;
  } funparam;

  pthread_t thread;
  pthread_attr_t attr;
  struct sched_param param;

  int thread_done;

  /*
  pthread_attr_init(&attr);
  pthread_attr_setstacksize(&attr,262144);
  pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);
  pthread_attr_setschedpolicy(&attr,SCHED_OTHER);
  param.sched_priority = sched_get_priority_min(SCHED_OTHER);
  pthread_attr_setschedparam(&attr, &param);
  */

  funparam.par = par;
  funparam.name = name;
  funparam.f = f;
  funparam.parserSettings = parserSettings;
  funparam.thread_done = &thread_done;

  /* POSIX */
  thread_done = 0;
  if (pthread_create(&thread,NULL,(void *)&McCheckACTLString_Thr,&funparam)) {
    printf("Error: pthread_create\n");
  } else {
    sched_yield();
    while (!thread_done) {
#ifdef TCLOUT
      Tcl_DoOneEvent(TCL_DONT_WAIT);
#endif
    }
    if (pthread_join(thread,NULL)) {
      printf("Error: pthread_join\n");
    }
  }

  return;
}

/**Function****************************************************************
  Synopsis    []
  Description []
  SideEffects []
  SeeAlso     []
  ************************************************************************/

void
Mc_CheckACTLFile_Thr(int par, Est_String name, Est_String f, int parserSettings)
{
  struct {
    int par;
    Est_String name;
    Est_String f;
    int parserSettings;
    int *thread_done;
  } funparam;

  pthread_t thread;
  pthread_attr_t attr;
  struct sched_param param;

  int thread_done;

  /*
  pthread_attr_init(&attr);
  pthread_attr_setstacksize(&attr,262144);
  pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);
  pthread_attr_setschedpolicy(&attr,SCHED_OTHER);
  param.sched_priority = sched_get_priority_min(SCHED_OTHER);
  pthread_attr_setschedparam(&attr, &param);
  */

  funparam.par = par;
  funparam.name = name;
  funparam.f = f;
  funparam.parserSettings = parserSettings;
  funparam.thread_done = &thread_done;

  /* POSIX */
  thread_done = 0;
  if (pthread_create(&thread,NULL,(void *)&McCheckACTLFile_Thr,&funparam)) {
    printf("Error: pthread_create\n");
  } else {
    sched_yield();
    while (!thread_done) {
#ifdef TCLOUT
      Tcl_DoOneEvent(TCL_DONT_WAIT);
#endif
    }
    if (pthread_join(thread,NULL)) {
      printf("Error: pthread_join\n");
    }
  }

  return;
}

#else /* USETHREADS */

void
Mc_CheckACTL_Thr(int par, Est_String name, Est_String f, int parserSettings)
{
  return;
}

void
Mc_CheckACTLString_Thr(int par, Est_String name, Est_String f, int parserSettings)
{
  return;
}

void
Mc_CheckACTLFile_Thr(int par, Est_String name, Est_String f, int parserSettings)
{
  return;
}

#endif /* USETHREADS */
