OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc1/] [newlib/] [libc/] [sys/] [linux/] [linuxthreads/] [timer_create.c] - Diff between revs 207 and 345

Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 345
/* Copyright (C) 2000 Free Software Foundation, Inc.
/* Copyright (C) 2000 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   This file is part of the GNU C Library.
   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
 
 
   The GNU C Library is free software; you can redistribute it and/or
   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.
   License, or (at your option) any later version.
 
 
   The GNU C Library is distributed in the hope that it will be useful,
   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.
   Library General Public License for more details.
 
 
   You should have received a copy of the GNU Library General Public
   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */
   Boston, MA 02111-1307, USA.  */
 
 
#include <errno.h>
#include <errno.h>
#include <signal.h>
#include <signal.h>
#include <pthread.h>
#include <pthread.h>
#include <time.h>
#include <time.h>
#include <unistd.h>
#include <unistd.h>
 
 
#include "posix-timer.h"
#include "posix-timer.h"
 
 
 
 
/* Create new per-process timer using CLOCK.  */
/* Create new per-process timer using CLOCK.  */
int
int
timer_create (clock_id, evp, timerid)
timer_create (clock_id, evp, timerid)
     clockid_t clock_id;
     clockid_t clock_id;
     struct sigevent *evp;
     struct sigevent *evp;
     timer_t *timerid;
     timer_t *timerid;
{
{
  int retval = -1;
  int retval = -1;
  struct timer_node *newtimer = NULL;
  struct timer_node *newtimer = NULL;
  struct thread_node *thread = NULL;
  struct thread_node *thread = NULL;
 
 
  if (clock_id != CLOCK_REALTIME
  if (clock_id != CLOCK_REALTIME
#ifdef _POSIX_CPUTIME
#ifdef _POSIX_CPUTIME
      && clock_id != CLOCK_PROCESS_CPUTIME_ID
      && clock_id != CLOCK_PROCESS_CPUTIME_ID
#endif
#endif
#ifdef _POSIX_THREAD_CPUTIME
#ifdef _POSIX_THREAD_CPUTIME
      && clock_id != CLOCK_THREAD_CPUTIME_ID
      && clock_id != CLOCK_THREAD_CPUTIME_ID
#endif
#endif
      )
      )
    {
    {
      __set_errno (EINVAL);
      __set_errno (EINVAL);
      return -1;
      return -1;
    }
    }
 
 
  pthread_once (&__timer_init_once_control, __timer_init_once);
  pthread_once (&__timer_init_once_control, __timer_init_once);
 
 
  if (__timer_init_failed)
  if (__timer_init_failed)
    {
    {
      __set_errno (ENOMEM);
      __set_errno (ENOMEM);
      return -1;
      return -1;
    }
    }
 
 
  pthread_mutex_lock (&__timer_mutex);
  pthread_mutex_lock (&__timer_mutex);
 
 
  newtimer = __timer_alloc ();
  newtimer = __timer_alloc ();
  if (__builtin_expect (newtimer == NULL, 0))
  if (__builtin_expect (newtimer == NULL, 0))
    {
    {
      __set_errno (EAGAIN);
      __set_errno (EAGAIN);
      goto unlock_bail;
      goto unlock_bail;
    }
    }
 
 
  if (evp != NULL)
  if (evp != NULL)
    newtimer->event = *evp;
    newtimer->event = *evp;
  else
  else
    {
    {
      newtimer->event.sigev_notify = SIGEV_SIGNAL;
      newtimer->event.sigev_notify = SIGEV_SIGNAL;
      newtimer->event.sigev_signo = SIGALRM;
      newtimer->event.sigev_signo = SIGALRM;
      newtimer->event.sigev_value.sival_int = timer_ptr2id (newtimer);
      newtimer->event.sigev_value.sival_int = timer_ptr2id (newtimer);
      newtimer->event.sigev_notify_function = 0;
      newtimer->event.sigev_notify_function = 0;
    }
    }
 
 
  newtimer->event.sigev_notify_attributes = &newtimer->attr;
  newtimer->event.sigev_notify_attributes = &newtimer->attr;
  newtimer->creator_pid = getpid ();
  newtimer->creator_pid = getpid ();
 
 
  switch (__builtin_expect (newtimer->event.sigev_notify, SIGEV_SIGNAL))
  switch (__builtin_expect (newtimer->event.sigev_notify, SIGEV_SIGNAL))
    {
    {
    case SIGEV_NONE:
    case SIGEV_NONE:
      /* This is a strange choice!  */
      /* This is a strange choice!  */
      break;
      break;
 
 
    case SIGEV_SIGNAL:
    case SIGEV_SIGNAL:
      /* We have a global thread for delivering timed signals.
      /* We have a global thread for delivering timed signals.
         If it is not running, try to start it up.  */
         If it is not running, try to start it up.  */
      switch (clock_id)
      switch (clock_id)
        {
        {
        case CLOCK_REALTIME:
        case CLOCK_REALTIME:
        default:
        default:
          thread = &__timer_signal_thread_rclk;
          thread = &__timer_signal_thread_rclk;
          break;
          break;
#ifdef _POSIX_CPUTIME
#ifdef _POSIX_CPUTIME
        case CLOCK_PROCESS_CPUTIME_ID:
        case CLOCK_PROCESS_CPUTIME_ID:
          thread = &__timer_signal_thread_pclk;
          thread = &__timer_signal_thread_pclk;
          break;
          break;
#endif
#endif
#ifdef _POSIX_THREAD_CPUTIME
#ifdef _POSIX_THREAD_CPUTIME
        case CLOCK_THREAD_CPUTIME_ID:
        case CLOCK_THREAD_CPUTIME_ID:
          thread = &__timer_signal_thread_tclk;
          thread = &__timer_signal_thread_tclk;
          break;
          break;
#endif
#endif
        }
        }
 
 
      if (! thread->exists)
      if (! thread->exists)
        {
        {
          if (__builtin_expect (__timer_thread_start (thread),
          if (__builtin_expect (__timer_thread_start (thread),
                                1) < 0)
                                1) < 0)
            {
            {
              __set_errno (EAGAIN);
              __set_errno (EAGAIN);
              goto unlock_bail;
              goto unlock_bail;
            }
            }
        }
        }
      break;
      break;
 
 
    case SIGEV_THREAD:
    case SIGEV_THREAD:
      /* Copy over thread attributes or set up default ones.  */
      /* Copy over thread attributes or set up default ones.  */
      if (evp->sigev_notify_attributes)
      if (evp->sigev_notify_attributes)
        newtimer->attr = *(pthread_attr_t *) evp->sigev_notify_attributes;
        newtimer->attr = *(pthread_attr_t *) evp->sigev_notify_attributes;
      else
      else
        pthread_attr_init (&newtimer->attr);
        pthread_attr_init (&newtimer->attr);
 
 
      /* Ensure thread attributes call for deatched thread.  */
      /* Ensure thread attributes call for deatched thread.  */
      pthread_attr_setdetachstate (&newtimer->attr, PTHREAD_CREATE_DETACHED);
      pthread_attr_setdetachstate (&newtimer->attr, PTHREAD_CREATE_DETACHED);
 
 
      /* Try to find existing thread having the right attributes.  */
      /* Try to find existing thread having the right attributes.  */
      thread = __timer_thread_find_matching (&newtimer->attr, clock_id);
      thread = __timer_thread_find_matching (&newtimer->attr, clock_id);
 
 
      /* If no existing thread has these attributes, try to allocate one.  */
      /* If no existing thread has these attributes, try to allocate one.  */
      if (thread == NULL)
      if (thread == NULL)
        thread = __timer_thread_alloc (&newtimer->attr, clock_id);
        thread = __timer_thread_alloc (&newtimer->attr, clock_id);
 
 
      /* Out of luck; no threads are available.  */
      /* Out of luck; no threads are available.  */
      if (__builtin_expect (thread == NULL, 0))
      if (__builtin_expect (thread == NULL, 0))
        {
        {
          __set_errno (EAGAIN);
          __set_errno (EAGAIN);
          goto unlock_bail;
          goto unlock_bail;
        }
        }
 
 
      /* If the thread is not running already, try to start it.  */
      /* If the thread is not running already, try to start it.  */
      if (! thread->exists
      if (! thread->exists
          && __builtin_expect (! __timer_thread_start (thread), 0))
          && __builtin_expect (! __timer_thread_start (thread), 0))
        {
        {
          __set_errno (EAGAIN);
          __set_errno (EAGAIN);
          goto unlock_bail;
          goto unlock_bail;
        }
        }
      break;
      break;
 
 
    default:
    default:
      __set_errno (EINVAL);
      __set_errno (EINVAL);
      goto unlock_bail;
      goto unlock_bail;
    }
    }
 
 
  newtimer->clock = clock_id;
  newtimer->clock = clock_id;
  newtimer->abstime = 0;
  newtimer->abstime = 0;
  newtimer->armed = 0;
  newtimer->armed = 0;
  newtimer->thread = thread;
  newtimer->thread = thread;
 
 
  *timerid = timer_ptr2id (newtimer);
  *timerid = timer_ptr2id (newtimer);
  retval = 0;
  retval = 0;
 
 
  if (__builtin_expect (retval, 0) == -1)
  if (__builtin_expect (retval, 0) == -1)
    {
    {
    unlock_bail:
    unlock_bail:
      if (thread != NULL)
      if (thread != NULL)
        __timer_thread_dealloc (thread);
        __timer_thread_dealloc (thread);
      if (newtimer != NULL)
      if (newtimer != NULL)
        __timer_dealloc (newtimer);
        __timer_dealloc (newtimer);
    }
    }
 
 
  pthread_mutex_unlock (&__timer_mutex);
  pthread_mutex_unlock (&__timer_mutex);
 
 
  return retval;
  return retval;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.