source: trunk/kernel/kern/alarm.c @ 176

Last change on this file since 176 was 23, checked in by alain, 8 years ago

Introduce syscalls.

File size: 3.9 KB
Line 
1/*
2 * kern/time.c - thread time related management
3 *
4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
6 *
7 * This file is part of ALMOS-kernel.
8 *
9 * ALMOS-kernel is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2.0 of the License.
12 *
13 * ALMOS-kernel is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <types.h>
24#include <thread.h>
25#include <task.h>
26#include <scheduler.h>
27#include <time.h>
28#include <list.h>
29#include <rt_timer.h>
30#include <kmagics.h>
31
32error_t alarm_wait(struct alarm_info_s *info, uint_t msec)
33{
34        register uint_t tm_now;
35        struct cpu_s *cpu;
36        struct alarm_s *alarm_mgr;
37        struct list_entry *iter;
38        struct alarm_info_s *current;
39        uint_t irq_state;
40
41        cpu       = current_cpu;
42        alarm_mgr = &cpu->alarm_mgr;
43
44        cpu_disable_all_irq(&irq_state);
45
46        tm_now          = cpu_get_ticks(cpu) * MSEC_PER_TICK;
47        info->signature = ALRM_INFO_ID;
48        info->tm_wakeup = tm_now + msec;
49
50        if(list_empty(&alarm_mgr->wait_queue))
51                list_add_first(&alarm_mgr->wait_queue, &info->list);
52        else
53        {
54                list_foreach_forward(&alarm_mgr->wait_queue, iter)
55                {
56                        current = list_element(iter, struct alarm_info_s, list);
57     
58                        if(info->tm_wakeup <= current->tm_wakeup) 
59                        {
60                                list_add_pred(iter, &info->list);
61                                goto NEXT_TRAITMENT;
62                        }
63                }
64                list_add_last(&alarm_mgr->wait_queue, &info->list);
65        }
66
67NEXT_TRAITMENT:
68        cpu_restore_irq(irq_state);
69        return 0;
70}
71
72void alarm_clock(struct alarm_s *alarm, uint_t ticks_nr)
73{
74        register uint_t tm_msec;
75        register struct list_entry *iter;
76        register struct alarm_info_s *info;
77 
78        tm_msec = ticks_nr * MSEC_PER_TICK;
79
80        list_foreach_forward(&alarm->wait_queue, iter)
81        {
82                info = list_element(iter, struct alarm_info_s, list);
83
84                assert((info->signature == ALRM_INFO_ID) && "Not an ALRM info object");
85
86                if(tm_msec < info->tm_wakeup)
87                        break;
88   
89                list_unlink(iter);
90                event_send(info->event, current_cpu->gid);
91        }
92}
93
94error_t alarm_manager_init(struct alarm_s *alarm)
95{
96        list_root_init(&alarm->wait_queue);
97        return 0;
98}
99
100
101#if CONFIG_THREAD_TIME_STAT
102
103inline void tm_sleep_compute(struct thread_s *thread)
104{
105        uint_t tm_now;
106
107        if(thread->type == TH_IDLE)
108                return;
109
110        rt_timer_read(&tm_now);
111        thread->info.tm_sleep += (tm_now - thread->info.tm_tmp);
112        thread->info.tm_tmp    = tm_now;
113}
114
115inline void tm_usr_compute(struct thread_s *thread)
116{ 
117        uint_t tm_now;
118
119        rt_timer_read(&tm_now);
120        thread->info.tm_usr += (tm_now - thread->info.tm_tmp);
121        thread->info.tm_tmp  = tm_now;
122}
123
124inline void tm_sys_compute(struct thread_s *thread)
125{ 
126        uint_t tm_now;
127
128        rt_timer_read(&tm_now);
129        thread->info.tm_sys += (tm_now - thread->info.tm_tmp);
130        thread->info.tm_tmp  = tm_now;
131}
132
133inline void tm_wait_compute(struct thread_s *thread)
134{
135        uint_t tm_now;
136
137        if(thread->type == TH_IDLE)
138                return;
139
140        rt_timer_read(&tm_now);
141        thread->info.tm_wait += (tm_now - thread->info.tm_tmp);
142        thread->info.tm_tmp   = tm_now;
143        thread->info.tm_exec  = tm_now;
144}
145
146inline void tm_exit_compute(struct thread_s *thread)
147{
148        uint_t tm_now;
149 
150        rt_timer_read(&tm_now);
151        thread->info.tm_sys += tm_now - thread->info.tm_tmp;
152        thread->info.tm_dead = tm_now;
153}
154
155inline void tm_born_compute(struct thread_s *thread)
156{
157        uint_t tm_now;
158 
159        rt_timer_read(&tm_now);
160        thread->info.tm_born = tm_now;
161        thread->info.tm_tmp  = tm_now;
162        thread->info.tm_exec = tm_now;
163}
164
165inline void tm_create_compute(struct thread_s *thread)
166{
167        rt_timer_read(&thread->info.tm_create);
168}
169
170
171#endif  /* CONFIG_THREAD_TIME_STAT */
Note: See TracBrowser for help on using the repository browser.