OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [newlib-1.18.0/] [newlib/] [libc/] [sys/] [linux/] [linuxthreads/] [timer_create.c] - Blame information for rev 829

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/* Copyright (C) 2000 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
4
 
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Library General Public License as
7
   published by the Free Software Foundation; either version 2 of the
8
   License, or (at your option) any later version.
9
 
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Library General Public License for more details.
14
 
15
   You should have received a copy of the GNU Library General Public
16
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
17
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
   Boston, MA 02111-1307, USA.  */
19
 
20
#include <errno.h>
21
#include <signal.h>
22
#include <pthread.h>
23
#include <time.h>
24
#include <unistd.h>
25
 
26
#include "posix-timer.h"
27
 
28
 
29
/* Create new per-process timer using CLOCK.  */
30
int
31
timer_create (clock_id, evp, timerid)
32
     clockid_t clock_id;
33
     struct sigevent *evp;
34
     timer_t *timerid;
35
{
36
  int retval = -1;
37
  struct timer_node *newtimer = NULL;
38
  struct thread_node *thread = NULL;
39
 
40
  if (clock_id != CLOCK_REALTIME
41
#ifdef _POSIX_CPUTIME
42
      && clock_id != CLOCK_PROCESS_CPUTIME_ID
43
#endif
44
#ifdef _POSIX_THREAD_CPUTIME
45
      && clock_id != CLOCK_THREAD_CPUTIME_ID
46
#endif
47
      )
48
    {
49
      __set_errno (EINVAL);
50
      return -1;
51
    }
52
 
53
  pthread_once (&__timer_init_once_control, __timer_init_once);
54
 
55
  if (__timer_init_failed)
56
    {
57
      __set_errno (ENOMEM);
58
      return -1;
59
    }
60
 
61
  pthread_mutex_lock (&__timer_mutex);
62
 
63
  newtimer = __timer_alloc ();
64
  if (__builtin_expect (newtimer == NULL, 0))
65
    {
66
      __set_errno (EAGAIN);
67
      goto unlock_bail;
68
    }
69
 
70
  if (evp != NULL)
71
    newtimer->event = *evp;
72
  else
73
    {
74
      newtimer->event.sigev_notify = SIGEV_SIGNAL;
75
      newtimer->event.sigev_signo = SIGALRM;
76
      newtimer->event.sigev_value.sival_int = timer_ptr2id (newtimer);
77
      newtimer->event.sigev_notify_function = 0;
78
    }
79
 
80
  newtimer->event.sigev_notify_attributes = &newtimer->attr;
81
  newtimer->creator_pid = getpid ();
82
 
83
  switch (__builtin_expect (newtimer->event.sigev_notify, SIGEV_SIGNAL))
84
    {
85
    case SIGEV_NONE:
86
      /* This is a strange choice!  */
87
      break;
88
 
89
    case SIGEV_SIGNAL:
90
      /* We have a global thread for delivering timed signals.
91
         If it is not running, try to start it up.  */
92
      switch (clock_id)
93
        {
94
        case CLOCK_REALTIME:
95
        default:
96
          thread = &__timer_signal_thread_rclk;
97
          break;
98
#ifdef _POSIX_CPUTIME
99
        case CLOCK_PROCESS_CPUTIME_ID:
100
          thread = &__timer_signal_thread_pclk;
101
          break;
102
#endif
103
#ifdef _POSIX_THREAD_CPUTIME
104
        case CLOCK_THREAD_CPUTIME_ID:
105
          thread = &__timer_signal_thread_tclk;
106
          break;
107
#endif
108
        }
109
 
110
      if (! thread->exists)
111
        {
112
          if (__builtin_expect (__timer_thread_start (thread),
113
                                1) < 0)
114
            {
115
              __set_errno (EAGAIN);
116
              goto unlock_bail;
117
            }
118
        }
119
      break;
120
 
121
    case SIGEV_THREAD:
122
      /* Copy over thread attributes or set up default ones.  */
123
      if (evp->sigev_notify_attributes)
124
        newtimer->attr = *(pthread_attr_t *) evp->sigev_notify_attributes;
125
      else
126
        pthread_attr_init (&newtimer->attr);
127
 
128
      /* Ensure thread attributes call for deatched thread.  */
129
      pthread_attr_setdetachstate (&newtimer->attr, PTHREAD_CREATE_DETACHED);
130
 
131
      /* Try to find existing thread having the right attributes.  */
132
      thread = __timer_thread_find_matching (&newtimer->attr, clock_id);
133
 
134
      /* If no existing thread has these attributes, try to allocate one.  */
135
      if (thread == NULL)
136
        thread = __timer_thread_alloc (&newtimer->attr, clock_id);
137
 
138
      /* Out of luck; no threads are available.  */
139
      if (__builtin_expect (thread == NULL, 0))
140
        {
141
          __set_errno (EAGAIN);
142
          goto unlock_bail;
143
        }
144
 
145
      /* If the thread is not running already, try to start it.  */
146
      if (! thread->exists
147
          && __builtin_expect (! __timer_thread_start (thread), 0))
148
        {
149
          __set_errno (EAGAIN);
150
          goto unlock_bail;
151
        }
152
      break;
153
 
154
    default:
155
      __set_errno (EINVAL);
156
      goto unlock_bail;
157
    }
158
 
159
  newtimer->clock = clock_id;
160
  newtimer->abstime = 0;
161
  newtimer->armed = 0;
162
  newtimer->thread = thread;
163
 
164
  *timerid = timer_ptr2id (newtimer);
165
  retval = 0;
166
 
167
  if (__builtin_expect (retval, 0) == -1)
168
    {
169
    unlock_bail:
170
      if (thread != NULL)
171
        __timer_thread_dealloc (thread);
172
      if (newtimer != NULL)
173
        __timer_dealloc (newtimer);
174
    }
175
 
176
  pthread_mutex_unlock (&__timer_mutex);
177
 
178
  return retval;
179
}

powered by: WebSVN 2.1.0

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