00001
00006 #include "routix/system.h"
00007 #include "routix/task.h"
00008 #include "routix/paging.h"
00009 #include "routix/kalloc.h"
00010 #include "error.h"
00011 #include "routix/file.h"
00012 #include "string.h"
00013
00014 #include "sys/list.h"
00015
00016
00017 tss_t tss;
00018
00019 void inicializarTss(tss_t *tss, word cs, word ds, dword eip, dword esp, dword eflags)
00020 {
00021 tss->ss0 = DESC_DATA;
00022 tss->cs=cs;
00023 tss->ds=ds;
00024 tss->es=ds;
00025 tss->fs=ds;
00026 tss->gs=ds;
00027 tss->ss=ds;
00028 tss->eip=eip;
00029 tss->esp=esp;
00030 tss->eflags=eflags;
00031 tss->ldt=0;
00032 tss->t=0;
00033 tss->cr3=POSICION_DIR_PAGINAS;
00034 }
00035
00036
00037
00038 dword *inicializar_task(dword *stack, word cs, word ds, dword eip, dword esp, dword eflags)
00039 {
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 stack--;
00064 *stack-- = ds;
00065 *stack-- = esp;
00066 *stack-- = eflags;
00067 *stack-- = cs;
00068 *stack-- = eip;
00069 *stack-- = 0;
00070 *stack-- = 0;
00071 *stack-- = 0;
00072 *stack-- = 0;
00073 *stack-- = 0;
00074 *stack-- = 0;
00075 *stack-- = 0;
00076 *stack-- = ds;
00077 *stack-- = ds;
00078 *stack-- = ds;
00079 *stack = ds;
00080
00081 return stack;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 inline pid_t get_new_pid(void)
00112 {
00113 static pid_t pid=2;
00114
00115 return(pid++);
00116 }
00117
00118
00119
00120
00121 volatile int tareas_activas=0;
00122
00123 void inc_tareas_activas()
00124 {
00125 ++tareas_activas;
00126 }
00127
00128 inline void dormir_task(task_struct_t *tarea)
00129 {
00130
00131 cli();
00132
00133
00134 tarea->estado = TASK_INTERRUMPIBLE;
00135 tarea->cuenta=tarea->prioridad;
00136
00137 --tareas_activas;
00138
00139
00140
00141
00142
00143
00144 sti();
00145 }
00146
00147 inline void despertar_task(task_struct_t *tarea)
00148 {
00149
00150 cli();
00151
00152 tarea->estado = TASK_RUNNING;
00153 tareas_activas++;
00154
00155
00156
00157
00158
00159
00160 sti();
00161 }
00162
00163
00164 inline void sleep_init()
00165 {
00166 cli();
00167
00168 if ( init_task->estado==TASK_RUNNING ) {
00169 init_task->estado=TASK_STOPPED;
00170 tareas_activas--;
00171 }
00172 sti();
00173 }
00174
00175 inline void wakeup_init()
00176 {
00177 cli();
00178 if (init_task->estado!=TASK_RUNNING) {
00179 init_task->estado=TASK_RUNNING;
00180 tareas_activas++;
00181 }
00182 sti();
00183 }
00184
00185
00186 task_struct_t *init_new_task(word cs, word ds, dword eip, dword esp, dword eflags, char *descripcion, word prioridad)
00187 {
00188 task_struct_t *nueva;
00189 dword esp0;
00190
00191
00192 if ( (nueva = (task_struct_t *) kmalloc_page()) == NULL ) {
00193 return NULL;
00194 }
00195
00196
00197 memset(nueva, 0, PAGINA_SIZE);
00198
00199
00200 esp0 = (dword) nueva + 4092;
00201
00202
00203 if ( (nueva->cr3 = (addr_t) make_pdt()) == NULL ) {
00204 kfree_page((addr_t)nueva);
00205 return NULL;
00206 }
00207
00208 nueva->cr3_backup = nueva->cr3;
00209
00210
00211
00212 strcpy( nueva->descripcion, descripcion);
00213
00214
00215
00216
00217
00218 nueva->estado = TASK_STOPPED;
00219
00220 nueva->prioridad = prioridad;
00221
00222 nueva->err_no = 0;
00223
00224
00225 nueva->cuenta = prioridad;
00226 nueva->tiempo_cpu = 0;
00227
00228
00229 nueva->esp0 = (dword) inicializar_task((dword *)esp0,cs,ds,eip,esp,eflags);
00230
00231 word j;
00232 for (j=0 ; j<MAX_FILES_POR_TAREA; j++)
00233 nueva->open_files[j] = NULL;
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 if ( ! insertar_tarea(nueva) ) {
00245
00246 kpanic("aca");
00247
00248
00249
00250 kfree_page((addr_t)nueva);
00251
00252 return NULL;
00253 }
00254
00255
00256
00257
00258
00259
00260 return nueva;
00261 }
00262
00263
00264
00265
00266
00267 int insertar_tarea(task_struct_t *nueva)
00268 {
00269 task_struct_t *tmp;
00270
00271 if ( nueva == NULL ) { return 0; }
00272
00273 cli();
00274
00275
00276 tmp = tareas_inicio;
00277
00278 if ( tareas_inicio == NULL ) { tareas_inicio = nueva; }
00279
00280 else {
00281
00282
00283 for ( tmp = tareas_inicio; tmp->proxima != NULL ; tmp = tmp->proxima );
00284
00285
00286 tmp->proxima = nueva;
00287 }
00288
00289
00290 nueva->proxima = NULL;
00291
00292 sti();
00293 return 1;
00294 }
00295
00296
00297
00298 task_struct_t *encontrar_proceso_por_pid(pid_t pid)
00299 {
00300 task_struct_t *tmp;
00301
00302 for( tmp = tareas_inicio; tmp && (tmp->pid != pid); tmp = tmp->proxima) ;
00303
00304 return tmp;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313 void tomar_nombre_tarea (const char *viejo, char *nuevo)
00314 {
00315 char *aux = (char *) (viejo + strlen(viejo));
00316 int i=12;
00317 for ( ; (aux > viejo) && (*aux!='/') && i>0 ; aux--);
00318
00319 strcpy(nuevo, aux);
00320 nuevo = str_to_lower (nuevo);
00321 }
00322
00325 int remover_task (task_struct_t *tarea)
00326 {
00327 task_struct_t *aux;
00328
00329 for ( aux = tareas_inicio ; aux!=NULL ; aux=aux->proxima) {
00330 if (aux->proxima == tarea) {
00331 aux->proxima = tarea->proxima;
00332 return 0;
00333 }
00334 }
00335 return -1;
00336 }