Contiki 2.5
ctimer.c
Go to the documentation of this file.
1 /**
2  * \addtogroup ctimer
3  * @{
4  */
5 
6 /*
7  * Copyright (c) 2006, Swedish Institute of Computer Science.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the Institute nor the names of its contributors
19  * may be used to endorse or promote products derived from this software
20  * without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * This file is part of the Contiki operating system.
35  *
36  * $Id: ctimer.c,v 1.1 2010/06/14 07:34:36 adamdunkels Exp $
37  */
38 
39 /**
40  * \file
41  * Callback timer implementation
42  * \author
43  * Adam Dunkels <adam@sics.se>
44  */
45 
46 #include "sys/ctimer.h"
47 #include "contiki.h"
48 #include "lib/list.h"
49 
50 LIST(ctimer_list);
51 
52 static char initialized;
53 
54 #define DEBUG 0
55 #if DEBUG
56 #include <stdio.h>
57 #define PRINTF(...) printf(__VA_ARGS__)
58 #else
59 #define PRINTF(...)
60 #endif
61 
62 /*---------------------------------------------------------------------------*/
63 PROCESS(ctimer_process, "Ctimer process");
64 PROCESS_THREAD(ctimer_process, ev, data)
65 {
66  struct ctimer *c;
67  PROCESS_BEGIN();
68 
69  for(c = list_head(ctimer_list); c != NULL; c = c->next) {
70  etimer_set(&c->etimer, c->etimer.timer.interval);
71  }
72  initialized = 1;
73 
74  while(1) {
75  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_TIMER);
76  for(c = list_head(ctimer_list); c != NULL; c = c->next) {
77  if(&c->etimer == data) {
78  list_remove(ctimer_list, c);
80  if(c->f != NULL) {
81  c->f(c->ptr);
82  }
83  PROCESS_CONTEXT_END(c->p);
84  break;
85  }
86  }
87  }
88  PROCESS_END();
89 }
90 /*---------------------------------------------------------------------------*/
91 void
93 {
94  initialized = 0;
95  list_init(ctimer_list);
96  process_start(&ctimer_process, NULL);
97 }
98 /*---------------------------------------------------------------------------*/
99 void
100 ctimer_set(struct ctimer *c, clock_time_t t,
101  void (*f)(void *), void *ptr)
102 {
103  PRINTF("ctimer_set %p %u\n", c, (unsigned)t);
104  c->p = PROCESS_CURRENT();
105  c->f = f;
106  c->ptr = ptr;
107  if(initialized) {
108  PROCESS_CONTEXT_BEGIN(&ctimer_process);
109  etimer_set(&c->etimer, t);
110  PROCESS_CONTEXT_END(&ctimer_process);
111  } else {
112  c->etimer.timer.interval = t;
113  }
114 
115  list_remove(ctimer_list, c);
116  list_add(ctimer_list, c);
117 }
118 /*---------------------------------------------------------------------------*/
119 void
120 ctimer_reset(struct ctimer *c)
121 {
122  if(initialized) {
123  PROCESS_CONTEXT_BEGIN(&ctimer_process);
124  etimer_reset(&c->etimer);
125  PROCESS_CONTEXT_END(&ctimer_process);
126  }
127 
128  list_remove(ctimer_list, c);
129  list_add(ctimer_list, c);
130 }
131 /*---------------------------------------------------------------------------*/
132 void
133 ctimer_restart(struct ctimer *c)
134 {
135  if(initialized) {
136  PROCESS_CONTEXT_BEGIN(&ctimer_process);
137  etimer_restart(&c->etimer);
138  PROCESS_CONTEXT_END(&ctimer_process);
139  }
140 
141  list_remove(ctimer_list, c);
142  list_add(ctimer_list, c);
143 }
144 /*---------------------------------------------------------------------------*/
145 void
146 ctimer_stop(struct ctimer *c)
147 {
148  if(initialized) {
149  etimer_stop(&c->etimer);
150  } else {
151  c->etimer.next = NULL;
152  c->etimer.p = PROCESS_NONE;
153  }
154  list_remove(ctimer_list, c);
155 }
156 /*---------------------------------------------------------------------------*/
157 int
158 ctimer_expired(struct ctimer *c)
159 {
160  struct ctimer *t;
161  if(initialized) {
162  return etimer_expired(&c->etimer);
163  }
164  for(t = list_head(ctimer_list); t != NULL; t = t->next) {
165  if(t == c) {
166  return 0;
167  }
168  }
169  return 1;
170 }
171 /*---------------------------------------------------------------------------*/
172 /** @} */