initial commit
[pfinal.git] / Routix / include / routix / task.h
blob2352fb19a98b5c5dfdeef1362a3898019f41e2f9
1 /* task.h */
3 #ifndef __ROUTIX_TASK
4 #define __ROUTIX_TASK
7 #include <routix/system.h>
8 #include <routix/paging.h>
9 #include <sys/list.h>
10 #include <routix/allocwrap.h>
11 #include <routix/kalloc.h>
12 #include <sys/types.h>
13 #include <signal.h>
14 #include <sys/bitmap.h>
15 #include <routix/thread.h>
16 #include <routix/file.h>
17 #include <routix/kalloc.h>
20 #define MAX_TASKS 7
22 typedef struct task_t {
23 word previos_task_link;
24 dword esp0;
25 word ss0;
26 dword esp1;
27 word ss1;
28 dword esp2;
29 word ss2;
30 dword cr3;
31 dword eip;
32 dword eflags;
33 dword eax;
34 dword ecx;
35 dword edx;
36 dword ebx;
37 dword esp;
38 dword ebp;
39 dword esi;
40 dword edi;
41 word es;
42 word cs;
43 word ss;
44 word ds;
45 word fs;
46 word gs;
47 word ldt;
48 word t;
49 word iomap;
50 } task_t;
52 //! TSS completo de la arquitectura IA32
53 typedef struct tss_t {
54 word previos_task_link;
55 word reservado0;
56 dword esp0;
57 word ss0;
58 word reservado1;
59 dword esp1;
60 word ss1;
61 word reservado2;
62 dword esp2;
63 word ss2;
64 word reservado3;
65 dword cr3;
66 dword eip;
67 dword eflags;
68 dword eax;
69 dword ecx;
70 dword edx;
71 dword ebx;
72 dword esp;
73 dword ebp;
74 dword esi;
75 dword edi;
76 word es;
77 word reservado4;
78 word cs;
79 word reservado5;
80 word ss;
81 word reservado6;
82 word ds;
83 word reservado7;
84 word fs;
85 word reservado8;
86 word gs;
87 word reservado9;
88 word ldt;
89 word reservado10;
90 word t;
91 word iomap;
92 } tss_t;
94 //! Esta estructura posee todos los registros que se "pop"ean del stack de modo kernel antes de ejecutar una tarea
95 struct int_regs_ext
97 dword gs;
98 dword fs;
99 dword es;
100 dword ds;
101 dword eax;
102 dword ebx;
103 dword ecx;
104 dword edx;
105 dword edi;
106 dword esi;
107 dword ebp;
108 dword eip;
109 dword cs;
110 dword eflags;
111 dword esp;
112 dword ss;
116 extern tss_t tss;
117 extern task_t tarea[];
118 void inicializarTss(tss_t *tss, word cs, word ds, dword eip, dword esp, dword eflags);
120 inline pid_t get_new_pid(void);
122 #define ltr(selector) __asm__ __volatile__("ltr %w0" : : "a" (selector));
126 #define MAX_PAGINAS_POR_TAREA 16
127 #define MAX_DESCRIPTION 64
129 //! Aquí están contenida toda la información relacionada con handlers, máscaras y señales pendientes
130 struct task_signals {
131 struct sigaction signal[SIGMAX];
132 unsigned char sigcount[SIGMAX];
133 unsigned long sigpending; //Señales pendientes
134 sigset_t sigmask;
135 addr_t sigcheck_addr; //Aca guardo la dir del hardcode de la llamada a SYS_SIGNALS | SYS_SIGNAL_CHECK
138 // Estas variables contienen la cantidad de alocaciones y liberacion de estructuras de señales
139 // (solo para control de leaks)
140 extern unsigned int task_signals_alloc, task_signals_free;
142 extern unsigned int umalloc_alloc, umalloc_free;
144 //! Retorna la dirección donde se ubica la estructura task_signals asociada con task
145 #define TASK_SIGNALS(task) (task->_signals)
146 //! Retorna la máscara de señales pendientes
147 #define TASK_SIGPENDING(task) (TASK_SIGNALS(task)->sigpending)
148 //! Retorna la máscara de señales inhibidas
149 #define TASK_SIGMASK(task) (TASK_SIGNALS(task)->sigmask)
150 //! Retorna la ubicación del wrapper que se ejecuta al finalizar un handler de señal
151 #define TASK_SIGADDR(task) (TASK_SIGNALS(task)->sigcheck_addr)
152 //! Permite el acceso a la estructura sigaction de la señal signo en la tarea task
153 #define TASK_SIGNAL(task, signo) (TASK_SIGNALS(task)->signal[signo])
154 //! Handler de la señal signo
155 #define TASK_SIGNAL_HANDLER(task,signo) (TASK_SIGNAL(task,signo).sa_handler)
156 //! Máscara de señales inhibidas mientras se ejecuta la señal signo
157 #define TASK_SIGNAL_MASK(task,signo) (TASK_SIGNAL(task,signo).sa_mask)
158 //! Flags de la señal signo en la tarea task
159 #define TASK_SIGNAL_FLAGS(task,signo) (TASK_SIGNAL(task,signo).sa_flags)
160 //! Aloca una estructura task_signals para la tarea tasr
161 #define TASK_SIGNALS_ALLOC(task) TASK_SIGNALS(task) = (struct task_signals *) \
162 MALLOC(MM_TASK_SIGNALS,sizeof(struct task_signals)); \
163 task_signals_alloc++;
164 //! Libera la estructura task_signals asociada a la tarea task
165 #define TASK_SIGNALS_FREE(task) FREE(MM_TASK_SIGNALS,TASK_SIGNALS(task)); \
166 task_signals_free++;
168 #define TASK_SIGNALS_INIT(task) memset(TASK_SIGNALS(task), 0, sizeof(struct task_signals))
169 //! Cantidad de señales encoladas del tipo signo en la tarea task
170 #define TASK_SIGNAL_COUNT(task, signo) ((TASK_SIGNALS(task)->sigcount)[signo])
172 struct std_header {
173 struct std_header *next;
174 struct std_header *prev;
177 //! Este es el task_struct, pilar fundamental de Routix
178 typedef struct task_struct_t
180 dword esp0;
181 dword cr3;
182 dword cr3_backup;
183 pid_t pid;
184 struct task_struct_t *proxima;
185 char descripcion[MAX_DESCRIPTION];
186 byte estado;
187 word prioridad;
188 word cuenta;
189 dword tiempo_cpu;
190 struct file *open_files [MAX_FILES_POR_TAREA]; //definido en file.h
191 word num_code, num_data, num_stack; //Cantidad de paginas de Codigo, Datos y stack
192 int err_no;
193 struct user_page *mcode;
194 struct user_page *mdata;
195 struct user_page *mstack;
196 struct task_struct_t *padre;
197 int retorno;
198 // LIST_NEW(struct zombie_queue) zombie_header;
199 LIST_DATA(task_struct_t) io_pending; // Este proceso puede pertenecer a una lista
200 // de entrada/salida, estando pendiente (mientras
201 // se lee o escribe de disco por medio de disco)
202 // ver "blockcache.c".
203 LIST_NEW(struct task_struct_t) childs; // Header de una lista con los hijosl proceso
204 LIST_DATA(task_struct_t) brothers; // Nodo de la lista que contiene a todos sus "bros"
206 struct task_signals *_signals;
208 struct sigaction signals[SIGMAX];
209 unsigned long sigpending; //Señales pendientes
210 addr_t sigcheck_addr; //Aca guardo la dir del hardcode de la llamada a SYS_SIGNALS | SYS_SIGNAL_CHECK
211 sigset_t sigmask;
213 unsigned int thread_count;
214 LIST_NEW(struct thread_struct_t) threads; // Header de la lista enlazada que contiene a todos los threads
215 // del proceso
216 BITMAP(thread_bitmap, MAX_THREADS_PER_PROCESS); // Bitmap indicador de threads del proceso
220 } task_struct_t ;
222 typedef struct thread_struct_t
224 dword esp0;
225 dword cr3;
226 dword cr3_backup;
227 pid_t tid;
228 struct user_page *mstack;
229 task_struct_t *task; // Puntero al proceso que contiene al thread
230 byte estado;
231 word prioridad;
232 word cuenta;
233 dword tiempo_cpu;
234 LIST_DATA(thread_struct_t) threads; // Convierte a esta estructura en nodo de una lista
236 } thread_struct_t;
239 #define TASK_STACK_USER(t) (t->esp0)
240 #define TASK_CR3(t) (t->cr3)
241 #define TASK_CR3_BACKUP(t) (t->cr3_backup)
242 #define TASK_PID(t) (t->pid)
243 #define TASK_DESCRIPTION(t) (t->descripcion)
244 #define TASK_STATE(t) (t->estado)
245 #define TASK_PRIORITY(t) (t->prioridad)
246 #define TASK_COUNT(t) (t->cuenta)
247 #define TASK_CPUTIME(t) (t->tiempo_cpu)
248 #define TASK_CODEPAGES(t) (t->num_code)
249 #define TASK_DATAPAGES(t) (t->num_data)
250 #define TASK_STACKPAGES(t) (t->num_stack)
251 #define TASK_ERRNO(t) (t->err_no)
252 #define TASK_PPID(t) (t->padre->pid)
253 #define TASK_PARENT(t) (t->padre)
255 enum estado { TASK_RUNNING, TASK_STOPPED, TASK_INTERRUMPIBLE, TASK_ININTERRUMPIBLE, TASK_ZOMBIE, TASK_CLEAN };
257 extern task_struct_t *init_task, *pre_init_task;
258 inline void sleep_init();
259 inline void wakeup_init();
261 // Estructura que describe las paginas utilizadas por las tareas
262 #define PAGINA_DATA 0 //pagina de datos
263 #define PAGINA_CODE 1 //pagina de codigo
264 #define PAGINA_STACK 0 //pagina de stack
265 #define PAGINA_ALLOC 2 //pagina alocada dinamicamente
267 struct user_page
269 addr_t dir, vdir;
270 word count;
271 dword flags;
272 struct user_page *next;
278 // Variables externas
279 extern task_struct_t *tareas_inicio;
280 extern task_struct_t *actual;
282 // Funciones para el manejo de tareas
283 task_struct_t *init_new_task(word cs, word ds, dword eip, dword esp, dword eflags, char *descripcion, word prioridad);
284 thread_struct_t * init_new_thread(word cs, word ds, dword eip, dword esp, dword eflags, char *descripcion, word prioridad);
286 task_struct_t *encontrar_proceso_por_pid(pid_t pid);
287 void tomar_nombre_tarea (const char *viejo, char *nuevo);
288 inline void dormir_task(task_struct_t *tarea);
289 inline void despertar_task(task_struct_t *tarea);
290 int insertar_tarea(task_struct_t *nueva);
291 int remover_task (task_struct_t *tarea);
294 // Macro para reschedulear, genera una llamada a la int 0x51 quien busca la próxima tarea a correr
295 #define _reschedule() __asm__ __volatile__("int $0x51")
298 //! Ubicación lógica del código de una tarea
299 #define TASK_TEXT 0x80000000
300 //! Ubicación lógica de los datos de una tarea
301 #define TASK_DATA 0x88000000
302 //! Ubicación lógica del stack de modo usuario de una tarea
303 #define TASK_STACK 0x90000000
305 // Ubicacion logica de una pagina de kernel que poseera permisos de usuario para contener algunos wrappers
306 // (como por ejemplo, una llamada a Syscall EXIT cuando termina el main de una tarea).
307 // EL pedido de la pagina, y la asignacion del código de EXIT está realizado en Kmain.c
308 #define EXIT_TASK (TASK_TEXT - PAGINA_SIZE)
310 /// \def Prioridad inicial de un nuevo proceso creado por medio de exec
311 #define START_PRIORITY 1
313 // Cantidad de páginas del stack de una tarea
314 extern int TASK_STACK_SIZE;
316 //! Retorna el contexto de la tarea task cuando esta pasa a modo kernel vía interrupción
317 #define GET_CONTEXT(task) ((struct int_regs_ext *) ((task->esp0 & 0xfffff000) + PAGINA_SIZE - sizeof(struct int_regs_ext)))
319 // Definiciones para debuggear memory leaks
321 extern int num_mallocs, num_frees;
322 extern int num_alloc_signals, num_free_signals;
325 // Estructura utilizada para almacenar información básica de un ejecutable
326 struct exec_file
328 // Tamaño en bytes de cada segmento
329 size_t code_len, data_len, bss_len;
330 // Offset de la ubicación de cada segmento en el archivo
331 unsigned int code_off, data_off, bss_off;
332 // Tamaño en páginas del segmento de código, datos y datos+bss
333 unsigned int code_pages, data_pages, alldata_pages;
336 //! Lee el header y obtiene toda la información base de un tipo COFF32 y lo coloca en *coff
337 int read_coff_header (int fd, struct exec_file *coff);
340 /*! \brief retorna la direccion de comienzo del proximo thread a crear
341 * \param task_struct de la tarea
342 * \return direccion de comienzo del stack de user del thread o NULL en caso contrario
344 addr_t thread_get_stack_address(task_struct_t *task);
346 /*! \brief libera del bitmap el bit correspondiente a la address
347 * \param task_struct de la tarea
348 * \param address direccion del stack
349 * \return nada por ahora
350 * \note es utilizado cuando se libera un stack de un thread(por ej. cuando el thread finaliza)
352 int thread_release_stack(task_struct_t *task, addr_t address);
355 #endif // __ROUTIX_TASK