1 /* Intel PRO/1000 Family Driver
2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
4 * Permission to use, copy, modify and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies, and that both the
7 * copyright notice and this permission notice appear in supporting documentation.
9 * Marcus Overhagen makes no representations about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
12 * MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
14 * OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
15 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40 static struct timer_info sTimerData
[MAX_TIMERS
];
41 static int sTimerCount
;
42 static timer_id sTimerNextId
;
43 static thread_id sTimerThread
;
44 static sem_id sTimerSem
;
45 static spinlock sTimerSpinlock
;
49 timer_thread(void *cookie
)
62 cpu
= disable_interrupts();
63 acquire_spinlock(&sTimerSpinlock
);
69 // find timer with smallest event time
71 timeout
= B_INFINITE_TIMEOUT
;
72 for (i
= 0; i
< sTimerCount
; i
++) {
73 if (sTimerData
[i
].next_event
< timeout
) {
74 timeout
= sTimerData
[i
].next_event
;
80 // timer is ready for execution, load func and cookie
81 ASSERT(index
>= 0 && index
< sTimerCount
);
82 func
= sTimerData
[index
].func
;
83 cookie
= sTimerData
[index
].cookie
;
84 if (sTimerData
[index
].periodic
) {
85 // periodic timer is ready, update the entry
86 sTimerData
[index
].next_event
+= sTimerData
[index
].interval
;
88 // single shot timer is ready, delete the entry
89 if (index
!= (sTimerCount
- 1) && sTimerCount
!= 1) {
90 memcpy(&sTimerData
[index
], &sTimerData
[sTimerCount
- 1], sizeof(struct timer_info
));
96 release_spinlock(&sTimerSpinlock
);
97 restore_interrupts(cpu
);
106 status
= acquire_sem_etc(sTimerSem
, 1, B_ABSOLUTE_TIMEOUT
, timeout
);
107 } while (status
!= B_BAD_SEM_ID
);
114 create_timer(timer_function func
, void *cookie
, bigtime_t interval
, uint32 flags
)
122 // Attention: flags are not real flags, as B_PERIODIC_TIMER is 3
124 cpu
= disable_interrupts();
125 acquire_spinlock(&sTimerSpinlock
);
127 if (sTimerCount
< MAX_TIMERS
) {
129 sTimerData
[sTimerCount
].id
= id
;
130 sTimerData
[sTimerCount
].func
= func
;
131 sTimerData
[sTimerCount
].cookie
= cookie
;
132 sTimerData
[sTimerCount
].next_event
= (flags
== B_ONE_SHOT_ABSOLUTE_TIMER
) ? interval
: system_time() + interval
;
133 sTimerData
[sTimerCount
].interval
= interval
;
134 sTimerData
[sTimerCount
].periodic
= flags
== B_PERIODIC_TIMER
;
141 release_spinlock(&sTimerSpinlock
);
142 restore_interrupts(cpu
);
145 release_sem_etc(sTimerSem
, 1, B_DO_NOT_RESCHEDULE
);
152 delete_timer(timer_id id
)
160 cpu
= disable_interrupts();
161 acquire_spinlock(&sTimerSpinlock
);
163 for (i
= 0; i
< sTimerCount
; i
++) {
164 if (sTimerData
[i
].id
== id
) {
165 if (i
!= (sTimerCount
- 1) && sTimerCount
!= 1) {
166 memcpy(&sTimerData
[i
], &sTimerData
[sTimerCount
- 1], sizeof(struct timer_info
));
174 release_spinlock(&sTimerSpinlock
);
175 restore_interrupts(cpu
);
180 release_sem_etc(sTimerSem
, 1, B_DO_NOT_RESCHEDULE
);
186 initialize_timer(void)
192 sTimerThread
= spawn_kernel_thread(timer_thread
, "ipro1000 timer", 80, 0);
193 sTimerSem
= create_sem(0, "ipro1000 timer");
194 set_sem_owner(sTimerSem
, B_SYSTEM_TEAM
);
196 if (sTimerSem
< 0 || sTimerThread
< 0) {
197 delete_sem(sTimerSem
);
198 kill_thread(sTimerThread
);
202 resume_thread(sTimerThread
);
208 terminate_timer(void)
210 status_t thread_return_value
;
212 delete_sem(sTimerSem
);
213 return wait_for_thread(sTimerThread
, &thread_return_value
);