00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "src/common/shared.hpp"
00011 #include "src/collection/avltree.hpp"
00012 #include "src/memory/memset.hpp"
00013 #include "src/memory/align.hpp"
00014 #include "src/memory/heap.hpp"
00015 #include "src/thread/timer.hpp"
00016 #include "src/thread/process.hpp"
00017 #include "src/arch/x86/rtc.hpp"
00018 #include "src/ipc/lock.hpp"
00019
00020 namespace Thread {
00034 namespace Timer {
00035
00036
00037 struct Memory::Heap::heapbox timer_thread_heapbox;
00038
00039 struct timer_struct {
00040 timer_proc proc;
00041 int arg1, arg2;
00042 uint32 nextExec;
00043 uint32 interval;
00044 };
00045
00049
00050 #define lnDb3 do {} while(0)
00051
00052 #define MAX_TIMERS_CNT 1000
00053
00056
00057
00058 int timer_struct_cmp(struct timer_struct *a, struct timer_struct *b) {
00059 if (a->nextExec > b->nextExec)
00060 return 1;
00061 if (a->nextExec < b->nextExec)
00062 return -1;
00063
00064 uint32 A= reinterpret_cast<uint32>(a);
00065 uint32 B= reinterpret_cast<uint32>(b);
00066 if (A>B)
00067 return 1;
00068 if (A<B)
00069 return 1;
00070
00071
00072 return 0;
00073 }
00074
00075 using namespace Collection;
00076
00077 class AvlTree<struct timer_struct*, timer_struct_cmp> *tmrs;
00078 class AvlTree<struct timer_struct*, timer_struct_cmp> *tmrs_pom;
00079
00080 volatile uint32 timers_cnt=0;
00081
00082 class IPC::Lock::lock_t tmrs_lock(const_cast<char*>("timers"));
00083
00084
00085 void TimerThread () {
00086 struct Option<struct timer_struct*> item;
00087 struct timer_struct *ts;
00088 while(1) {
00089 uint32 fl;
00090 ENTER_CRITICAL(fl);
00091 lnDb3 ;
00092 tmrs_lock.lock();
00093 lnDb3 ;
00094 for (item= tmrs->findMin();
00095 !item.isNone();
00096 item=tmrs->findMin()) {
00097 ts= item.get();
00098
00099 if (ts->nextExec > Arch::x86::RTC::up_time)
00100 break;
00101 tmrs->remove(ts);
00102 timers_cnt--;
00103
00104 tmrs_pom->insert(ts);
00109 (*(uint32*)0xb8024)++;
00110 }
00111
00112 tmrs_lock.ulock();
00113 LEAVE_CRITICAL(fl);
00114 lnDb3 ;
00115
00116
00117 for (item= tmrs_pom->findMin();
00118 !item.isNone();
00119 item= tmrs_pom->findMin()) {
00120 ts= item.get();
00121 tmrs_pom->remove(ts);
00122
00123 if (ts->proc(ts->arg1,ts->arg2) == 1) {
00124 ts->nextExec += ts->interval;
00125
00126 ENTER_CRITICAL(fl);
00127 lnDb3 ;
00128 tmrs_lock.lock();
00129 lnDb3 ;
00130 tmrs->insert(ts);
00131 tmrs_lock.ulock();
00132 LEAVE_CRITICAL(fl);
00133 lnDb3 ;
00134 } else {
00135
00136 timer_thread_heapbox.free(ts);
00137 }
00138
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 Thread::sleep(1);
00154 }
00155 }
00156
00161 struct timer_handle add(timer_proc proc, uint32 interval, int arg1, int arg2) {
00162 struct timer_struct *ts;
00163 ts= static_cast<struct timer_struct*>(timer_thread_heapbox.malloc(sizeof(struct timer_struct),1,"timer struct",null));
00164 ts->proc=proc;
00165 ts->arg1=arg1;
00166 ts->arg2=arg2;
00167 ts->interval=interval;
00168 ts->nextExec= Arch::x86::RTC::up_time+ interval;
00169 uint32 fl; ENTER_CRITICAL(fl);
00170 lnDb3 ;
00171 tmrs_lock.lock();
00172 lnDb3 ;
00173 if (timers_cnt > MAX_TIMERS_CNT) {
00174
00175 sysfail("too many timers");
00176 tmrs_lock.ulock();
00177 LEAVE_CRITICAL(fl);
00178 timer_thread_heapbox.free(ts);
00179
00180 return timer_handle();
00181 }
00182 tmrs->insert(ts);
00183 timers_cnt ++;
00184 tmrs_lock.ulock();
00185 LEAVE_CRITICAL(fl);
00186 lnDb3 ;
00187 return timer_handle(reinterpret_cast<uint32>(ts));
00188 }
00189
00190 bool remove(struct timer_handle &hndl) {
00191 uint32 fl;
00192 ENTER_CRITICAL(fl);
00193 lnDb3 ;
00194 tmrs_lock.lock();
00195 lnDb3 ;
00196 bool x= tmrs->remove(reinterpret_cast<struct timer_struct*>(hndl.d));
00197 timers_cnt --;
00198 tmrs_lock.ulock();
00199 LEAVE_CRITICAL(fl);
00200 timer_thread_heapbox.free(reinterpret_cast<struct timer_struct*>(hndl.d));
00201 lnDb3 ;
00202 hndl=0;
00203 return x;
00204 }
00205
00206 void initTimerThread() {
00207 Memory::Heap::allocate_heapbox(&timer_thread_heapbox, "timer thread");
00208
00209
00210
00211 tmrs = new class Collection::AvlTree<struct timer_struct*, timer_struct_cmp>;
00212 tmrs_pom = new class Collection::AvlTree<struct timer_struct*, timer_struct_cmp>;
00213 Thread::kernel_process.create_thread(true, (uint32)&TimerThread, 2, 2, const_cast<char*>("timers"));
00214 }
00215
00216
00217 }
00218 }
00219
00220