atomic.c

Go to the documentation of this file.
00001 /* spinlock.c */
00002 
00003 #include "routix/system.h"
00004 #include "routix/atomic.h"
00005 #include "routix/debug.h"
00006 
00007 // Funciones que aseguran la atomicidad de operaciones basicas
00008 
00009 inline int atomic_inc (int *p)
00010 {
00011         cli();
00012         (*p)++;
00013         sti();
00014         return *p;
00015 }
00016 
00017 inline int atomic_dec (int *p)
00018 {
00019         cli();
00020         (*p)--;
00021         sti();
00022         return *p;
00023 }
00024 
00025 inline int atomic_asign (int *p, int x)
00026 {
00027         cli();
00028         *p = x;
00029         sti();
00030         return *p;
00031 }
00032 
00033 inline int atomic_add (int *p, int x)
00034 {
00035         cli();
00036         *p += x;
00037         sti();
00038         return *p;
00039 }
00040 
00041 inline int atomic_sub (int *p, int x)
00042 {
00043         cli();
00044         *p -= x;
00045         sti();
00046         return *p;
00047 }
00048 
00049 // Retorna el valor que posee la variable candado, y luego la setea a 1
00050 inline int TestAndSet(spinlock_t *candado)
00051 {
00052     int retorno;
00053         
00054     __asm__ __volatile__ ("pushf\n\t"
00055                                                   "cli\n\t"
00056                                                   "movl %2, %0\n\t"
00057                                                   "movl $1, %1\n\t"
00058                                                   "popf"
00059                                                   : "=m" (retorno), "=m" (*candado)
00060                                                   : "r" (*candado));
00061 
00062 /*      cli();
00063         
00064         __asm__ __volatile__ ("movl %0, %%ebx ; movl $1, %%eax ; xchg %%eax, (%%ebx)" : : "m" (candado) : "ebx");
00065         sti();
00066 */      
00067         return retorno;    
00068 }
00069 
00070 /* Momentaneamente solo usadas por funciones de kernel */
00071 
00072 // Candado, utilizado para verificar si algun proceso está evaluando el contenido de "valor"
00073 spinlock_t kernel_lock = 0;
00074 
00075 
00076 //Funcion de bloqueo del semaforo (equivalente a down o wait)
00077 void spin_lock (spinlock_t *valor)
00078 {
00079     while(1) {
00080                 // Esperar mientras algún proceso este dentro de spin_lock/spin_unlock
00081                 while (TestAndSet(&kernel_lock));
00082 
00083                 if (*valor > 0) {
00084                     (*valor)--;
00085                     break;
00086                 }
00087                 kernel_lock = 0;    
00088     }
00089     kernel_lock = 0;
00090 }
00091 
00092 
00093 //Funcion de desbloqueo del semaforo (equivalente a up o signal)
00094 void spin_unlock (spinlock_t *valor)
00095 {
00096         // Esperar mientras algún proceso este dentro de spin_lock/spin_unlock
00097     while (TestAndSet(&kernel_lock));
00098     (*valor)++;
00099     kernel_lock = 0;   
00100 }
00101 
00102 

Generated on Sun May 30 18:38:34 2004 for Routix OS by doxygen 1.3.6