/* This file is part of Lcrzo.
*/

int lcrzo_time_pause_usec(lcrzo_uint32 usec)
#if defined LCRZODEF_SYSTEM_Unix
{ struct timeval tv1, tv2;
  int ret, oldprio;
  lcrzo_uint32 time_sleep_threshold1, time_sleep_threshold2, time_sleep_threshold3;

  lcrzo_er(lcrzo_global_get_time_sleep_1threshold(&time_sleep_threshold1));
  lcrzo_er(lcrzo_global_get_time_sleep_2threshold(&time_sleep_threshold2));
  lcrzo_er(lcrzo_global_get_time_sleep_3threshold(&time_sleep_threshold3));

  if (usec<time_sleep_threshold1)
  { ret=gettimeofday(&tv1, NULL);
    if (ret) return(LCRZO_ERR_FUGETTIMEOFDAY);
    tv2=tv1;
    /*on boucle en attendant l'heure*/
    while( (lcrzo_uint32)( (tv2.tv_sec-tv1.tv_sec)*1000000+
			   (tv2.tv_usec-tv1.tv_usec) ) < usec )
    { ret=gettimeofday(&tv2, NULL);
      if (ret) return(LCRZO_ERR_FUGETTIMEOFDAY);
    }
  }
  else if (usec<time_sleep_threshold2)
  { ret=gettimeofday(&tv1, NULL);
    if (ret) return(LCRZO_ERR_FUGETTIMEOFDAY);
    tv2=tv1;
    /*pour consommer moins de ressources*/
    oldprio=getpriority(PRIO_PROCESS, 0);
    setpriority(PRIO_PROCESS, 0, +20);
    /*on boucle en attendant l'heure*/
    while( (lcrzo_uint32)( (tv2.tv_sec-tv1.tv_sec)*1000000+
			   (tv2.tv_usec-tv1.tv_usec) ) < usec )
    { ret=gettimeofday(&tv2, NULL);
      if (ret) return(LCRZO_ERR_FUGETTIMEOFDAY);
    }
    setpriority(PRIO_PROCESS, 0, oldprio);
  }
  else if (usec<time_sleep_threshold3)
  { /*utilise usleep*/
    usleep(usec);
  }
  else
  { /*utilise sleep*/
    sleep(usec/1000000);
  }

  errno=0; /*because Solaris sets errno to 4*/
  return(LCRZO_ERR_OK);
}
#elif defined LCRZODEF_SYSTEM_Windows
{ lcrzo_uint32 tickstart, tickend, i, n;
  lcrzo_uint32 time_sleep_threshold1, time_sleep_threshold2;
  lcrzo_priv_staticvars *psv;
  /*lcrzo_int8 oldprio;*/

  lcrzo_er(lcrzo_priv_staticvars_ptr_get(&psv));
  lcrzo_er(lcrzo_global_get_time_sleep_1threshold(&time_sleep_threshold1));
  lcrzo_er(lcrzo_global_get_time_sleep_2threshold(&time_sleep_threshold2));
  
  if (usec<time_sleep_threshold1 || usec<time_sleep_threshold2)
  { if (psv->time_sleep_usec_numberforloop==0)
    { /* compute values */
      psv->time_sleep_usec_numberforloop=1024;
      /* wait for a step */
      n=0;
      tickstart=GetTickCount();
      do 
      { tickend=GetTickCount();
      }
      while (tickend==tickstart);
      tickstart=tickend;
      /* wait for the next step */
      do 
      { tickend=GetTickCount();
        n++;
      }
      while (tickend==tickstart);
      /* compute true number of loop needed (for milliseconds, and not microsecond,
         because otherwise there is too much round) */  
      psv->time_sleep_usec_numberforloop = n / ( tickend-tickstart );
      /*printf("n=%u\n", ptr->time_sleep_usec_numberforloop);*/
    }
    /* lower the priority
    if (usec>=time_sleep_threshold1)
    { lcrzo_er(lcrzo_process_current_priority_get(&oldprio));
      lcrzo_er(lcrzo_process_current_priority_set(-99));
    } */
    /* loop the estimated time */
    n=(usec*psv->time_sleep_usec_numberforloop)/1000;
    for ( i=0 ; i<n ; i++ )
    { tickend=GetTickCount();
    }
    /* restore the priority
    if (usec>=time_sleep_threshold1)
    { lcrzo_er(lcrzo_process_current_priority_set(oldprio));
    } */
  }
  else
  { Sleep(usec/1000);
  }

  return(LCRZO_ERR_OK);
}
#else
 #error "Unknown value for LCRZODEF_SYSTEM"
#endif

