Ufff... lo que se pueden complicar las cosas a veces...
Vereis, el otro día, tenía la libreria rulando tres hilos sin fallo alguno (estuve probando en la DS el programa durante mas de tres horas y todo perfecto).
Bueno, pues como estoy utilizando un nuevo sistema, bien diferente a como hice la primera implementacion y viendo que la cosa va de PM, me decido a intentar meter semaforos.
Al principio, todo mas o menos normal, los tipicos fallos de programacíon que se solventan pronto, pero luego, me doy cuenta de que el programa peta, por un error desconocido. Anulo el tema d elos semaforos y sigo con el mismo problema:
¿será que no restauro bien los registros? No, tanto el registro de estado como los registros del r0 al r12, pasando por sp,lr y pc, se restauran correctamente, eso no puede ser.
¿será un problema de reentrada en la interrupcion? Pues va a ser que no, puesto que que al entrar en el modo interrupcion, las interrupciones estan deshabilitadas y ademas, el registro IME tambien está deshabilitado
¿será un problema de pila? De mis funciones en ensamblador, no es desde luego y en el modo interrupcion se utiliza otra pila diferente, que mediante test, compruebo que no varía nada
¿será un problema de caché? Pudiera ser... pero nen, raro es que flusheando las cachés, los fallos se repitan
El fallo se manifiesta de dos formas: cuelgue directo o corrupcion de la pantalla superior espectacular
Pues bueno, yo comiendome el tarro durante horas y dandome de tortas por no encontrar el fallo

y... ¿que era?
Pues lo unico que podia ser: la parte de código que no es mía, procedente de LIBNDS, jejeje
Vereis, el problema es el siguiente: el ARM tiene un registro sp diferente para el modo interrupciones que en la DS, ese stack tiene una longitud de 256 bytes.
Puesto que hasta ahora, no había posibilidad de utilizar programación multihilo, si queriamos hacer que una aplicacion dependiese de una interrupcion (como por ejemplo, el reproductor de MOD), tenemos un problema con el tamaño de dicha pila
Entonces, al parecer, los creadres de LIBNDS tuvieron la idea de conmutar al modo sistema (las funciones se ejecutan en dicho modo, normalmente), para poder aprovechar la pila y ahí la CAGARON
¿por que? Pues porque aunque los programadores solemos pensar que las entradas en la pila, son simetricas (si hay un push, luego habrá un pop, etc), esto no tiene porque ser así siempre.
Por ejemplo, imaginemos un codigo asi:
add sp,sp,#32
ldr r0,[sp]
sub sp,sp,#32
¿que pasa si despues del add sp,sp... ocurre una interrupcion? Pues que cuando entremos en nuestra funcion de handler, nuestras variables locales macharan los datos que hemos dejado desprotegidos al variar el puntero de pila (de ahi que haya un puntero de pila diferente para cada modo en el arm) .
Aunque parezca increible, eso sucede (o algo similar) con las instrucciones en modo thumb , o si no, explicadme porque el pete desaparece, si desplazo la pila hacia abajo un determinado numero de bytes antes de entrar en el handler y luego, por supuesto, hago la correccion oportuna al salir.
En el codigo utilizado en ARM7, no hay problema, pues el main() acaba en un bucle infinito, que no debe variar mucho la pila y las cosas 'complicadas' cuelgan de las interrupciones
En ARM9, se tiene que dar la circustancia de que una interrupcion coincida con una instruccion equivalente a la que pongo arriba y eso es bastante mas dificil cuando la interrupción VBLANK es la unica que puede dar por saco y menos con un swiWaitForVBlank(); que es muy probable que atrape la interrupcion (aun así, yo creo que un problema que tenia con mi juego Asteroids and Gems, al salvar partida, que hacia que el juego se colgara de forma aleatoria al salvar, podría deberse a ese problema)
Con el tema multithread, la cosa se complica porque a la conmutacion de hilos hay que añadir un timer que realiza esos cambios a la velocidad de 1000 ciclos/segundo y claro, no es una cosa que ocurra a cada instante, si no que dependiendo de como se sincronice, puede tardar 1 minuto, 5, 20 o varias horas, hasta que aparece ese problema
En fin, que ya está todo solucionado y todo funciona perfectamente, aunque he preferido optar por usar una pila independiente de 1024 bytes, para los handlers y evitar futuros problemas.
Tambien he añadido un test para comprobar el puntero de pila de todas las funciones y llamar a una funcion en caso de rebase de pila (o sea, una funcion debug que se llamaría en el momento de conmutar una tarea)
Mañana trataré de adelantar todo el trabajo que pueda, ya que este problema me ha retrasado mucho (aunque lo bueno es que eso repercute en una libreria mas robusta)
EDITADO:
Bueno, parece que el nucleo multihread va perfectamente y mi implementacion (BETA) de semaforos, tambien rula como debiera.
No se si leereis esto o no (ya se que escribo tochos, pero si encima no intercalais ningun post, la cosa se agrava

)
He añadido cosas nuevas... soporte RPC para poder llamar funciones remotas en cada uno de los procesadores, hasta 32 servidores para cada uno de los procesadores.
Bueno, uno menos porque el server 0, se utiliza internamente para detalles como poder activar un hilo en cualquiera de los procesadores, o asignar memoria del monticulo con arm9_malloc() (
o una funcion, print_log, que nos permite escribir un mensaje de texto desde el ARM7 en un buffer que luego podemos recuperar desde el ARM9.
En fin, que solo queda preparar la documentacion y algunos ejemplos