Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/include/smp/spinlock.h need to be fixed.

0001 /*                    The Quest Operating System
0002  *  Copyright (C) 2005-2010  Richard West, Boston University
0003  *
0004  *  This program is free software: you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation, either version 3 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 #ifndef _SPINLOCK_H_
0019 #define _SPINLOCK_H_
0020 #include"smp/atomic.h"
0021 
0022 //#define DEBUG_SPINLOCK
0023 #define DEBUG_MAX_SPIN 1000000
0024 
0025 struct _spinlock
0026 {
0027   uint32 lock;
0028 };
0029 typedef struct _spinlock spinlock;
0030 
0031 extern volatile bool mp_enabled;
0032 
0033 static inline void
0034 spinlock_lock (spinlock * lock)
0035 {
0036   extern void com1_putc (char);
0037   extern void com1_puts (char *);
0038   extern void com1_putx (uint32);
0039   uint8 LAPIC_get_physical_ID (void);
0040 
0041   if (mp_enabled) {
0042 #ifdef DEBUG_SPINLOCK
0043     int count = 0;
0044     extern void panic (char *);
0045     extern void com1_printf (const char *, ...);
0046 #endif
0047     int x = 1;
0048     uint32 *addr = &lock->lock;
0049     for (;;) {
0050       asm volatile ("lock xchgl %1,(%0)":"=r" (addr),
0051                     "=ir" (x):"0" (addr), "1" (x));
0052       if (x == 0)
0053         break;
0054       asm volatile ("pause");
0055 #ifdef DEBUG_SPINLOCK
0056       count++;
0057       if (count > DEBUG_MAX_SPIN) {
0058         com1_printf ("DEADLOCK (CPU %d)\n", LAPIC_get_physical_ID ());
0059         panic ("DEADLOCK\n");
0060       }
0061 #endif
0062     }
0063   }
0064 }
0065 
0066 static inline void
0067 spinlock_unlock (spinlock * lock)
0068 {
0069   uint32 x = 0;
0070   uint32 *addr = &lock->lock;
0071   extern void com1_putc (char);
0072   extern void com1_puts (char *);
0073   extern void com1_putx (uint32);
0074   uint8 LAPIC_get_physical_ID (void);
0075   void stacktrace (void);
0076 
0077   asm volatile ("lock xchgl %1,(%0)":"=r" (addr), "=ir" (x):"0" (addr),
0078                 "1" (x));
0079 }
0080 
0081 static inline void
0082 spinlock_init (spinlock * lock)
0083 {
0084   atomic_store_dword (&lock->lock, 0);
0085 }
0086 
0087 #define SPINLOCK_INIT {0}
0088 
0089 #endif
0090 
0091 /* 
0092  * Local Variables:
0093  * indent-tabs-mode: nil
0094  * mode: C
0095  * c-file-style: "gnu"
0096  * c-basic-offset: 2
0097  * End: 
0098  */
0099 
0100 /* vi: set et sw=2 sts=2: */