7 #include <routix/system.h>
8 #include <routix/paging.h>
10 #include <routix/allocwrap.h>
11 #include <routix/kalloc.h>
12 #include <sys/types.h>
14 #include <sys/bitmap.h>
15 #include <routix/thread.h>
16 #include <routix/file.h>
17 #include <routix/kalloc.h>
22 typedef struct task_t
{
23 word previos_task_link
;
52 //! TSS completo de la arquitectura IA32
53 typedef struct tss_t
{
54 word previos_task_link
;
94 //! Esta estructura posee todos los registros que se "pop"ean del stack de modo kernel antes de ejecutar una tarea
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
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)); \
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])
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
184 struct task_struct_t
*proxima
;
185 char descripcion
[MAX_DESCRIPTION
];
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
193 struct user_page
*mcode
;
194 struct user_page
*mdata
;
195 struct user_page
*mstack
;
196 struct task_struct_t
*padre
;
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
213 unsigned int thread_count
;
214 LIST_NEW(struct thread_struct_t
) threads
; // Header de la lista enlazada que contiene a todos los threads
216 BITMAP(thread_bitmap
, MAX_THREADS_PER_PROCESS
); // Bitmap indicador de threads del proceso
222 typedef struct thread_struct_t
228 struct user_page
*mstack
;
229 task_struct_t
*task
; // Puntero al proceso que contiene al thread
234 LIST_DATA(thread_struct_t
) threads
; // Convierte a esta estructura en nodo de una lista
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
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
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