af6f7412b631d665c28987412777d8d4e444ba41
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / pthread / timer_routines.c
1 /* Helper code for POSIX timer implementation on NPTL.
2    Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public License as
8    published by the Free Software Foundation; either version 2.1 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include <assert.h>
22 #include <errno.h>
23 #include <pthread.h>
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sysdep.h>
28 #include <time.h>
29 #include <unistd.h>
30 #include <sys/syscall.h>
31
32 #include "posix-timer.h"
33 #include <pthreadP.h>
34
35
36 /* Number of threads used.  */
37 #define THREAD_MAXNODES 16
38
39 /* Array containing the descriptors for the used threads.  */
40 static struct thread_node thread_array[THREAD_MAXNODES];
41
42 /* Static array with the structures for all the timers.  */
43 struct timer_node __timer_array[TIMER_MAX];
44
45 /* Global lock to protect operation on the lists.  */
46 pthread_mutex_t __timer_mutex = PTHREAD_MUTEX_INITIALIZER;
47
48 /* Variable to protext initialization.  */
49 pthread_once_t __timer_init_once_control = PTHREAD_ONCE_INIT;
50
51 /* Nonzero if initialization of timer implementation failed.  */
52 int __timer_init_failed;
53
54 /* Node for the thread used to deliver signals.  */
55 struct thread_node __timer_signal_thread_rclk;
56 #ifdef _POSIX_CPUTIME
57 struct thread_node __timer_signal_thread_pclk;
58 #endif
59 #ifdef _POSIX_THREAD_CPUTIME
60 struct thread_node __timer_signal_thread_tclk;
61 #endif
62
63 /* Lists to keep free and used timers and threads.  */
64 struct list_links timer_free_list;
65 struct list_links thread_free_list;
66 struct list_links thread_active_list;
67
68
69 #ifdef __NR_rt_sigqueueinfo
70 extern int __syscall_rt_sigqueueinfo (int, int, siginfo_t *);
71 #endif
72
73
74 /* List handling functions.  */
75 static inline void
76 list_init (struct list_links *list)
77 {
78   list->next = list->prev = list;
79 }
80
81 static inline void
82 list_append (struct list_links *list, struct list_links *newp)
83 {
84   newp->prev = list->prev;
85   newp->next = list;
86   list->prev->next = newp;
87   list->prev = newp;
88 }
89
90 static inline void
91 list_insbefore (struct list_links *list, struct list_links *newp)
92 {
93   list_append (list, newp);
94 }
95
96 /*
97  * Like list_unlink_ip, except that calling it on a node that
98  * is already unlinked is disastrous rather than a noop.
99  */
100
101 static inline void
102 list_unlink (struct list_links *list)
103 {
104   struct list_links *lnext = list->next, *lprev = list->prev;
105
106   lnext->prev = lprev;
107   lprev->next = lnext;
108 }
109
110 static inline struct list_links *
111 list_first (struct list_links *list)
112 {
113   return list->next;
114 }
115
116 static inline struct list_links *
117 list_null (struct list_links *list)
118 {
119   return list;
120 }
121
122 static inline struct list_links *
123 list_next (struct list_links *list)
124 {
125   return list->next;
126 }
127
128 static inline int
129 list_isempty (struct list_links *list)
130 {
131   return list->next == list;
132 }
133
134
135 /* Functions build on top of the list functions.  */
136 static inline struct thread_node *
137 thread_links2ptr (struct list_links *list)
138 {
139   return (struct thread_node *) ((char *) list
140                                  - offsetof (struct thread_node, links));
141 }
142
143 static inline struct timer_node *
144 timer_links2ptr (struct list_links *list)
145 {
146   return (struct timer_node *) ((char *) list
147                                 - offsetof (struct timer_node, links));
148 }
149
150
151 /* Initialize a newly allocated thread structure.  */
152 static void
153 thread_init (struct thread_node *thread, const pthread_attr_t *attr, clockid_t clock_id)
154 {
155   if (attr != NULL)
156     thread->attr = *attr;
157   else
158     {
159       pthread_attr_init (&thread->attr);
160       pthread_attr_setdetachstate (&thread->attr, PTHREAD_CREATE_DETACHED);
161     }
162
163   thread->exists = 0;
164   list_init (&thread->timer_queue);
165   pthread_cond_init (&thread->cond, 0);
166   thread->current_timer = 0;
167   thread->captured = pthread_self ();
168   thread->clock_id = clock_id;
169 }
170
171
172 /* Initialize the global lists, and acquire global resources.  Error
173    reporting is done by storing a non-zero value to the global variable
174    timer_init_failed.  */
175 static void
176 init_module (void)
177 {
178   int i;
179
180   list_init (&timer_free_list);
181   list_init (&thread_free_list);
182   list_init (&thread_active_list);
183
184   for (i = 0; i < TIMER_MAX; ++i)
185     {
186       list_append (&timer_free_list, &__timer_array[i].links);
187       __timer_array[i].inuse = TIMER_FREE;
188     }
189
190   for (i = 0; i < THREAD_MAXNODES; ++i)
191     list_append (&thread_free_list, &thread_array[i].links);
192
193   thread_init (&__timer_signal_thread_rclk, 0, CLOCK_REALTIME);
194 #ifdef _POSIX_CPUTIME
195   thread_init (&__timer_signal_thread_pclk, 0, CLOCK_PROCESS_CPUTIME_ID);
196 #endif
197 #ifdef _POSIX_THREAD_CPUTIME
198   thread_init (&__timer_signal_thread_tclk, 0, CLOCK_THREAD_CPUTIME_ID);
199 #endif
200 }
201
202
203 /* This is a handler executed in a child process after a fork()
204    occurs.  It reinitializes the module, resetting all of the data
205    structures to their initial state.  The mutex is initialized in
206    case it was locked in the parent process.  */
207 static void
208 reinit_after_fork (void)
209 {
210   init_module ();
211   pthread_mutex_init (&__timer_mutex, 0);
212 }
213
214
215 /* Called once form pthread_once in timer_init. This initializes the
216    module and ensures that reinit_after_fork will be executed in any
217    child process.  */
218 void
219 __timer_init_once (void)
220 {
221   init_module ();
222   pthread_atfork (0, 0, reinit_after_fork);
223 }
224
225
226 /* Deinitialize a thread that is about to be deallocated.  */
227 static void
228 thread_deinit (struct thread_node *thread)
229 {
230   assert (list_isempty (&thread->timer_queue));
231   pthread_cond_destroy (&thread->cond);
232 }
233
234
235 /* Allocate a thread structure from the global free list.  Global
236    mutex lock must be held by caller.  The thread is moved to
237    the active list. */
238 struct thread_node *
239 __timer_thread_alloc (const pthread_attr_t *desired_attr, clockid_t clock_id)
240 {
241   struct list_links *node = list_first (&thread_free_list);
242
243   if (node != list_null (&thread_free_list))
244     {
245       struct thread_node *thread = thread_links2ptr (node);
246       list_unlink (node);
247       thread_init (thread, desired_attr, clock_id);
248       list_append (&thread_active_list, node);
249       return thread;
250     }
251
252   return 0;
253 }
254
255
256 /* Return a thread structure to the global free list.  Global lock
257    must be held by caller.  */
258 void
259 __timer_thread_dealloc (struct thread_node *thread)
260 {
261   thread_deinit (thread);
262   list_unlink (&thread->links);
263   list_append (&thread_free_list, &thread->links);
264 }
265
266
267 /* Each of our threads which terminates executes this cleanup
268    handler. We never terminate threads ourselves; if a thread gets here
269    it means that the evil application has killed it.  If the thread has
270    timers, these require servicing and so we must hire a replacement
271    thread right away.  We must also unblock another thread that may
272    have been waiting for this thread to finish servicing a timer (see
273    timer_delete()).  */
274
275 static void
276 thread_cleanup (void *val)
277 {
278   if (val != NULL)
279     {
280       struct thread_node *thread = val;
281
282       /* How did the signal thread get killed?  */
283       assert (thread != &__timer_signal_thread_rclk);
284 #ifdef _POSIX_CPUTIME
285       assert (thread != &__timer_signal_thread_pclk);
286 #endif
287 #ifdef _POSIX_THREAD_CPUTIME
288       assert (thread != &__timer_signal_thread_tclk);
289 #endif
290
291       pthread_mutex_lock (&__timer_mutex);
292
293       thread->exists = 0;
294
295       /* We are no longer processing a timer event.  */
296       thread->current_timer = 0;
297
298       if (list_isempty (&thread->timer_queue))
299         __timer_thread_dealloc (thread);
300       else
301         (void) __timer_thread_start (thread);
302
303       pthread_mutex_unlock (&__timer_mutex);
304
305       /* Unblock potentially blocked timer_delete().  */
306       pthread_cond_broadcast (&thread->cond);
307     }
308 }
309
310
311 /* Handle a timer which is supposed to go off now.  */
312 static void
313 thread_expire_timer (struct thread_node *self, struct timer_node *timer)
314 {
315   self->current_timer = timer; /* Lets timer_delete know timer is running. */
316
317   pthread_mutex_unlock (&__timer_mutex);
318
319   switch (__builtin_expect (timer->event.sigev_notify, SIGEV_SIGNAL))
320     {
321     case SIGEV_NONE:
322       assert (! "timer_create should never have created such a timer");
323       break;
324
325     case SIGEV_SIGNAL:
326 #ifdef __NR_rt_sigqueueinfo
327       {
328         siginfo_t info;
329
330         /* First, clear the siginfo_t structure, so that we don't pass our
331            stack content to other tasks.  */
332         memset (&info, 0, sizeof (siginfo_t));
333         /* We must pass the information about the data in a siginfo_t
334            value.  */
335         info.si_signo = timer->event.sigev_signo;
336         info.si_code = SI_TIMER;
337         info.si_pid = timer->creator_pid;
338         info.si_uid = getuid ();
339         info.si_value = timer->event.sigev_value;
340
341         INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid, info.si_signo, &info);
342       }
343 #else
344       if (pthread_kill (self->captured, timer->event.sigev_signo) != 0)
345         {
346           if (pthread_kill (self->id, timer->event.sigev_signo) != 0)
347             abort ();
348         }
349 #endif
350       break;
351
352     case SIGEV_THREAD:
353       timer->event.sigev_notify_function (timer->event.sigev_value);
354       break;
355
356     default:
357       assert (! "unknown event");
358       break;
359     }
360
361   pthread_mutex_lock (&__timer_mutex);
362
363   self->current_timer = 0;
364
365   pthread_cond_broadcast (&self->cond);
366 }
367
368
369 /* Thread function; executed by each timer thread. The job of this
370    function is to wait on the thread's timer queue and expire the
371    timers in chronological order as close to their scheduled time as
372    possible.  */
373 static void
374 __attribute__ ((noreturn))
375 thread_func (void *arg)
376 {
377   struct thread_node *self = arg;
378
379   /* Register cleanup handler, in case rogue application terminates
380      this thread.  (This cannot happen to __timer_signal_thread, which
381      doesn't invoke application callbacks). */
382
383   pthread_cleanup_push (thread_cleanup, self);
384
385   pthread_mutex_lock (&__timer_mutex);
386
387   while (1)
388     {
389       struct list_links *first;
390       struct timer_node *timer = NULL;
391
392       /* While the timer queue is not empty, inspect the first node.  */
393       first = list_first (&self->timer_queue);
394       if (first != list_null (&self->timer_queue))
395         {
396           struct timespec now;
397
398           timer = timer_links2ptr (first);
399
400           /* This assumes that the elements of the list of one thread
401              are all for the same clock.  */
402           clock_gettime (timer->clock, &now);
403
404           while (1)
405             {
406               /* If the timer is due or overdue, remove it from the queue.
407                  If it's a periodic timer, re-compute its new time and
408                  requeue it.  Either way, perform the timer expiry. */
409               if (timespec_compare (&now, &timer->expirytime) < 0)
410                 break;
411
412               list_unlink_ip (first);
413
414               if (__builtin_expect (timer->value.it_interval.tv_sec, 0) != 0
415                   || timer->value.it_interval.tv_nsec != 0)
416                 {
417                   timer->overrun_count = 0;
418                   timespec_add (&timer->expirytime, &timer->expirytime,
419                                 &timer->value.it_interval);
420                   while (timespec_compare (&timer->expirytime, &now) < 0)
421                     {
422                       timespec_add (&timer->expirytime, &timer->expirytime,
423                                     &timer->value.it_interval);
424                       if (timer->overrun_count < DELAYTIMER_MAX)
425                         ++timer->overrun_count;
426                     }
427                   __timer_thread_queue_timer (self, timer);
428                 }
429
430               thread_expire_timer (self, timer);
431
432               first = list_first (&self->timer_queue);
433               if (first == list_null (&self->timer_queue))
434                 break;
435
436               timer = timer_links2ptr (first);
437             }
438         }
439
440       /* If the queue is not empty, wait until the expiry time of the
441          first node.  Otherwise wait indefinitely.  Insertions at the
442          head of the queue must wake up the thread by broadcasting
443          this condition variable.  */
444       if (timer != NULL)
445         pthread_cond_timedwait (&self->cond, &__timer_mutex,
446                                 &timer->expirytime);
447       else
448         pthread_cond_wait (&self->cond, &__timer_mutex);
449     }
450   /* This macro will never be executed since the while loop loops
451      forever - but we have to add it for proper nesting.  */
452   pthread_cleanup_pop (1);
453 }
454
455
456 /* Enqueue a timer in wakeup order in the thread's timer queue.
457    Returns 1 if the timer was inserted at the head of the queue,
458    causing the queue's next wakeup time to change. */
459
460 int
461 __timer_thread_queue_timer (struct thread_node *thread,
462                             struct timer_node *insert)
463 {
464   struct list_links *iter;
465   int athead = 1;
466
467   for (iter = list_first (&thread->timer_queue);
468        iter != list_null (&thread->timer_queue);
469         iter = list_next (iter))
470     {
471       struct timer_node *timer = timer_links2ptr (iter);
472
473       if (timespec_compare (&insert->expirytime, &timer->expirytime) < 0)
474           break;
475       athead = 0;
476     }
477
478   list_insbefore (iter, &insert->links);
479   return athead;
480 }
481
482
483 /* Start a thread and associate it with the given thread node.  Global
484    lock must be held by caller.  */
485 int
486 __timer_thread_start (struct thread_node *thread)
487 {
488   int retval = 1;
489
490   assert (!thread->exists);
491   thread->exists = 1;
492
493   if (pthread_create (&thread->id, &thread->attr,
494                       (void *(*) (void *)) thread_func, thread) != 0)
495     {
496       thread->exists = 0;
497       retval = -1;
498     }
499
500   return retval;
501 }
502
503
504 void
505 __timer_thread_wakeup (struct thread_node *thread)
506 {
507   pthread_cond_broadcast (&thread->cond);
508 }
509
510
511 /* Compare two pthread_attr_t thread attributes for exact equality.
512    Returns 1 if they are equal, otherwise zero if they are not equal
513    or contain illegal values.  This version is NPTL-specific for
514    performance reason.  One could use the access functions to get the
515    values of all the fields of the attribute structure.  */
516 static int
517 thread_attr_compare (const pthread_attr_t *left, const pthread_attr_t *right)
518 {
519   struct pthread_attr *ileft = (struct pthread_attr *) left;
520   struct pthread_attr *iright = (struct pthread_attr *) right;
521
522   return (ileft->flags == iright->flags
523           && ileft->schedpolicy == iright->schedpolicy
524           && (ileft->schedparam.sched_priority
525               == iright->schedparam.sched_priority));
526 }
527
528
529 /* Search the list of active threads and find one which has matching
530    attributes.  Global mutex lock must be held by caller.  */
531 struct thread_node *
532 __timer_thread_find_matching (const pthread_attr_t *desired_attr,
533                               clockid_t desired_clock_id)
534 {
535   struct list_links *iter = list_first (&thread_active_list);
536
537   while (iter != list_null (&thread_active_list))
538     {
539       struct thread_node *candidate = thread_links2ptr (iter);
540
541       if (thread_attr_compare (desired_attr, &candidate->attr)
542           && desired_clock_id == candidate->clock_id)
543         return candidate;
544
545       iter = list_next (iter);
546     }
547
548   return NULL;
549 }
550
551
552 /* Grab a free timer structure from the global free list.  The global
553    lock must be held by the caller.  */
554 struct timer_node *
555 __timer_alloc (void)
556 {
557   struct list_links *node = list_first (&timer_free_list);
558
559   if (node != list_null (&timer_free_list))
560     {
561       struct timer_node *timer = timer_links2ptr (node);
562       list_unlink_ip (node);
563       timer->inuse = TIMER_INUSE;
564       timer->refcount = 1;
565       return timer;
566     }
567
568   return NULL;
569 }
570
571
572 /* Return a timer structure to the global free list.  The global lock
573    must be held by the caller.  */
574 void
575 __timer_dealloc (struct timer_node *timer)
576 {
577   assert (timer->refcount == 0);
578   timer->thread = NULL; /* Break association between timer and thread.  */
579   timer->inuse = TIMER_FREE;
580   list_append (&timer_free_list, &timer->links);
581 }
582
583
584 /* Thread cancellation handler which unlocks a mutex.  */
585 void
586 __timer_mutex_cancel_handler (void *arg)
587 {
588   pthread_mutex_unlock (arg);
589 }