(thread_expire_timer): Remove assertion for SIGEV_NONE.
[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, 2004 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       break;
323
324     case SIGEV_SIGNAL:
325 #ifdef __NR_rt_sigqueueinfo
326       {
327         siginfo_t info;
328
329         /* First, clear the siginfo_t structure, so that we don't pass our
330            stack content to other tasks.  */
331         memset (&info, 0, sizeof (siginfo_t));
332         /* We must pass the information about the data in a siginfo_t
333            value.  */
334         info.si_signo = timer->event.sigev_signo;
335         info.si_code = SI_TIMER;
336         info.si_pid = timer->creator_pid;
337         info.si_uid = getuid ();
338         info.si_value = timer->event.sigev_value;
339
340         INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid, info.si_signo, &info);
341       }
342 #else
343       if (pthread_kill (self->captured, timer->event.sigev_signo) != 0)
344         {
345           if (pthread_kill (self->id, timer->event.sigev_signo) != 0)
346             abort ();
347         }
348 #endif
349       break;
350
351     case SIGEV_THREAD:
352       timer->event.sigev_notify_function (timer->event.sigev_value);
353       break;
354
355     default:
356       assert (! "unknown event");
357       break;
358     }
359
360   pthread_mutex_lock (&__timer_mutex);
361
362   self->current_timer = 0;
363
364   pthread_cond_broadcast (&self->cond);
365 }
366
367
368 /* Thread function; executed by each timer thread. The job of this
369    function is to wait on the thread's timer queue and expire the
370    timers in chronological order as close to their scheduled time as
371    possible.  */
372 static void
373 __attribute__ ((noreturn))
374 thread_func (void *arg)
375 {
376   struct thread_node *self = arg;
377
378   /* Register cleanup handler, in case rogue application terminates
379      this thread.  (This cannot happen to __timer_signal_thread, which
380      doesn't invoke application callbacks). */
381
382   pthread_cleanup_push (thread_cleanup, self);
383
384   pthread_mutex_lock (&__timer_mutex);
385
386   while (1)
387     {
388       struct list_links *first;
389       struct timer_node *timer = NULL;
390
391       /* While the timer queue is not empty, inspect the first node.  */
392       first = list_first (&self->timer_queue);
393       if (first != list_null (&self->timer_queue))
394         {
395           struct timespec now;
396
397           timer = timer_links2ptr (first);
398
399           /* This assumes that the elements of the list of one thread
400              are all for the same clock.  */
401           clock_gettime (timer->clock, &now);
402
403           while (1)
404             {
405               /* If the timer is due or overdue, remove it from the queue.
406                  If it's a periodic timer, re-compute its new time and
407                  requeue it.  Either way, perform the timer expiry. */
408               if (timespec_compare (&now, &timer->expirytime) < 0)
409                 break;
410
411               list_unlink_ip (first);
412
413               if (__builtin_expect (timer->value.it_interval.tv_sec, 0) != 0
414                   || timer->value.it_interval.tv_nsec != 0)
415                 {
416                   timer->overrun_count = 0;
417                   timespec_add (&timer->expirytime, &timer->expirytime,
418                                 &timer->value.it_interval);
419                   while (timespec_compare (&timer->expirytime, &now) < 0)
420                     {
421                       timespec_add (&timer->expirytime, &timer->expirytime,
422                                     &timer->value.it_interval);
423                       if (timer->overrun_count < DELAYTIMER_MAX)
424                         ++timer->overrun_count;
425                     }
426                   __timer_thread_queue_timer (self, timer);
427                 }
428
429               thread_expire_timer (self, timer);
430
431               first = list_first (&self->timer_queue);
432               if (first == list_null (&self->timer_queue))
433                 break;
434
435               timer = timer_links2ptr (first);
436             }
437         }
438
439       /* If the queue is not empty, wait until the expiry time of the
440          first node.  Otherwise wait indefinitely.  Insertions at the
441          head of the queue must wake up the thread by broadcasting
442          this condition variable.  */
443       if (timer != NULL)
444         pthread_cond_timedwait (&self->cond, &__timer_mutex,
445                                 &timer->expirytime);
446       else
447         pthread_cond_wait (&self->cond, &__timer_mutex);
448     }
449   /* This macro will never be executed since the while loop loops
450      forever - but we have to add it for proper nesting.  */
451   pthread_cleanup_pop (1);
452 }
453
454
455 /* Enqueue a timer in wakeup order in the thread's timer queue.
456    Returns 1 if the timer was inserted at the head of the queue,
457    causing the queue's next wakeup time to change. */
458
459 int
460 __timer_thread_queue_timer (struct thread_node *thread,
461                             struct timer_node *insert)
462 {
463   struct list_links *iter;
464   int athead = 1;
465
466   for (iter = list_first (&thread->timer_queue);
467        iter != list_null (&thread->timer_queue);
468         iter = list_next (iter))
469     {
470       struct timer_node *timer = timer_links2ptr (iter);
471
472       if (timespec_compare (&insert->expirytime, &timer->expirytime) < 0)
473           break;
474       athead = 0;
475     }
476
477   list_insbefore (iter, &insert->links);
478   return athead;
479 }
480
481
482 /* Start a thread and associate it with the given thread node.  Global
483    lock must be held by caller.  */
484 int
485 __timer_thread_start (struct thread_node *thread)
486 {
487   int retval = 1;
488
489   assert (!thread->exists);
490   thread->exists = 1;
491
492   if (pthread_create (&thread->id, &thread->attr,
493                       (void *(*) (void *)) thread_func, thread) != 0)
494     {
495       thread->exists = 0;
496       retval = -1;
497     }
498
499   return retval;
500 }
501
502
503 void
504 __timer_thread_wakeup (struct thread_node *thread)
505 {
506   pthread_cond_broadcast (&thread->cond);
507 }
508
509
510 /* Compare two pthread_attr_t thread attributes for exact equality.
511    Returns 1 if they are equal, otherwise zero if they are not equal
512    or contain illegal values.  This version is NPTL-specific for
513    performance reason.  One could use the access functions to get the
514    values of all the fields of the attribute structure.  */
515 static int
516 thread_attr_compare (const pthread_attr_t *left, const pthread_attr_t *right)
517 {
518   struct pthread_attr *ileft = (struct pthread_attr *) left;
519   struct pthread_attr *iright = (struct pthread_attr *) right;
520
521   return (ileft->flags == iright->flags
522           && ileft->schedpolicy == iright->schedpolicy
523           && (ileft->schedparam.sched_priority
524               == iright->schedparam.sched_priority)
525           && ileft->guardsize == iright->guardsize
526           && ileft->stackaddr == iright->stackaddr
527           && ileft->stacksize == iright->stacksize
528           && ((ileft->cpuset == NULL && iright->cpuset == NULL)
529               || (ileft->cpuset != NULL && iright->cpuset != NULL
530                   && ileft->cpusetsize == iright->cpusetsize
531                   && memcmp (ileft->cpuset, iright->cpuset,
532                              ileft->cpusetsize) == 0)));
533 }
534
535
536 /* Search the list of active threads and find one which has matching
537    attributes.  Global mutex lock must be held by caller.  */
538 struct thread_node *
539 __timer_thread_find_matching (const pthread_attr_t *desired_attr,
540                               clockid_t desired_clock_id)
541 {
542   struct list_links *iter = list_first (&thread_active_list);
543
544   while (iter != list_null (&thread_active_list))
545     {
546       struct thread_node *candidate = thread_links2ptr (iter);
547
548       if (thread_attr_compare (desired_attr, &candidate->attr)
549           && desired_clock_id == candidate->clock_id)
550         return candidate;
551
552       iter = list_next (iter);
553     }
554
555   return NULL;
556 }
557
558
559 /* Grab a free timer structure from the global free list.  The global
560    lock must be held by the caller.  */
561 struct timer_node *
562 __timer_alloc (void)
563 {
564   struct list_links *node = list_first (&timer_free_list);
565
566   if (node != list_null (&timer_free_list))
567     {
568       struct timer_node *timer = timer_links2ptr (node);
569       list_unlink_ip (node);
570       timer->inuse = TIMER_INUSE;
571       timer->refcount = 1;
572       return timer;
573     }
574
575   return NULL;
576 }
577
578
579 /* Return a timer structure to the global free list.  The global lock
580    must be held by the caller.  */
581 void
582 __timer_dealloc (struct timer_node *timer)
583 {
584   assert (timer->refcount == 0);
585   timer->thread = NULL; /* Break association between timer and thread.  */
586   timer->inuse = TIMER_FREE;
587   list_append (&timer_free_list, &timer->links);
588 }
589
590
591 /* Thread cancellation handler which unlocks a mutex.  */
592 void
593 __timer_mutex_cancel_handler (void *arg)
594 {
595   pthread_mutex_unlock (arg);
596 }