00001
00002
00003
00004
00005 #include <routix/system.h>
00006 #include <routix/8254.h>
00007 #include <routix/8259.h>
00008 #include <routix/debug.h>
00009 #include <routix/task.h>
00010 #include <routix/kalloc.h>
00011 #include <routix/time.h>
00012 #include <routix/sched.h>
00013 #include <routix/atomic.h>
00014 #include <routix/timer.h>
00015 #include <sys/list.h>
00016
00017
00018
00019 dword jiffies=0;
00020
00021
00022 volatile timer_t *timer_inicio=NULL;
00023
00024
00025 LIST_NEW(timer_t) timer_list = LIST_INITIALIZER;
00026
00027 void actualizar_timers(void);
00028 inline static int insert_timer(timer_t *nuevo);
00029 inline static int remove_timer(timer_t *timer);
00030
00031
00032 void timertick_handler()
00033 {
00034
00035 endOfInterrupt();
00036
00037
00038 jiffies++;
00039
00040
00041 if ( ! (jiffies % FINTERRUPCION) ) actualizar_reloj(jiffies);
00042
00043
00044 actualizar_timers();
00045
00046
00047
00048 floppy_procesar_buffer();
00049
00050
00051
00052 if ( actual ) {
00053
00054 actual->cuenta -= 1;
00055 actual->tiempo_cpu++;
00056
00057
00058 if ( actual->cuenta <= 0 ) {
00059
00060 actual->cuenta = actual->prioridad;
00061 scheduler();
00062 __asm__ ("nop");
00063 }
00064 }
00065
00066
00067 else {
00068 scheduler();
00069 }
00070
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 void actualizar_timers(void)
00102 {
00103 timer_t *tmp;
00104 timer_t *toclean;
00105
00106
00107 for(tmp=HEADER_NEXT(timer_list); tmp ;) {
00108
00109 if ( TIMER_TICKS(tmp) > jiffies )
00110 break;
00111
00112
00113 (*(TIMER_FUNCTION(tmp)))(tmp);
00114
00115
00116 LIST_DEL(timer_list,timer_list,tmp);
00117
00118 toclean=tmp;
00119
00120
00121 tmp=LIST_NEXT(timer_list,tmp);
00122
00123
00124 clean_timer(toclean);
00125
00126 }
00127
00128 }
00129
00130
00131 spinlock_t timer_lock = 1;
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 inline static int insert_timer(timer_t *nuevo)
00172 {
00173
00174 START_ATOMIC_OPERATION;
00175
00176 timer_t *tmp;
00177
00178 if ( nuevo == NULL ) { return 0; }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 LIST_FOREACH(tmp,timer_list,timer_list) {
00192
00193
00194
00195 if ( TIMER_TICKS(tmp) >= TIMER_TICKS(nuevo) )
00196 break;
00197 }
00198
00199
00200 if ( tmp==NULL ) {
00201 LIST_ADD_TAIL(timer_list,timer_list,nuevo);
00202 }
00203
00204
00205 else {
00206 LIST_INSERT_BEFORE(timer_list,timer_list,tmp,nuevo);
00207 }
00208
00209
00210
00211
00212 FINISH_ATOMIC_OPERATION;
00213
00214 return 1;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 inline static int remove_timer(timer_t *timer)
00254 {
00255
00256 START_ATOMIC_OPERATION;
00257
00258 timer_t *tmp;
00259
00260
00261
00262 #ifdef SECURE_TIMER_OPER
00263
00264 LIST_FOREACH(tmp,timer_list,timer_list) {
00265 if ( tmp==timer )
00266 break;
00267 }
00268
00269
00270 if ( tmp==NULL ) {
00271 FINISH_ATOMIC_OPERATION;
00272 return -1;
00273 }
00274
00275 #endif
00276
00277
00278 LIST_DEL(timer_list,timer_list,timer);
00279
00280
00281 FINISH_ATOMIC_OPERATION;
00282
00283 return 0;
00284
00285 }
00286
00287
00288 inline timer_t *create_timer(dword ticks, task_struct_t *proceso, void (*func)(struct timer_t *info), void *data)
00289 {
00290 timer_t *timer = (timer_t *) malloc(sizeof(timer_t));
00291
00292 if ( timer==NULL)
00293 return NULL;
00294
00295 TIMER_TICKS(timer)=jiffies+ticks;
00296 TIMER_PROCESS(timer)=proceso;
00297 TIMER_FUNCTION(timer)=func;
00298 TIMER_DATA(timer)=data;
00299
00300 insert_timer(timer);
00301
00302 return timer;
00303 }
00304
00305 inline int clean_timer(timer_t *timer)
00306 {
00307
00308 if ( timer==NULL )
00309 return -1;
00310
00311
00312
00313
00314 if ( remove_timer(timer) == -1 )
00315 return -1;
00316
00317
00318 free(timer);
00319
00320 return 1;
00321 }
00322
00323
00326 inline void timer_dump(void)
00327 {
00328 timer_t *tmp;
00329
00330 START_ATOMIC_OPERATION;
00331
00332 kprintf("Pid\n");
00333 LIST_FOREACH(tmp,timer_list,timer_list) {
00334 kprintf("%d\n", TASK_PID(TIMER_PROCESS(tmp)));
00335 }
00336
00337 FINISH_ATOMIC_OPERATION;
00338
00339 }