Changeset 90c8b8d in mainline
- Timestamp:
- 2009-08-21T14:08:20Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a71c158
- Parents:
- af8e565
- Location:
- kernel/generic
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/print.h
raf8e565 r90c8b8d 37 37 38 38 #include <arch/types.h> 39 #include <synch/spinlock.h>40 39 #include <arch/arg.h> 41 42 /* We need this address in spinlock to avoid deadlock in deadlock detection */43 SPINLOCK_EXTERN(printf_lock);44 40 45 41 #define EOF (-1) -
kernel/generic/include/synch/spinlock.h
raf8e565 r90c8b8d 43 43 44 44 #ifdef CONFIG_SMP 45 45 46 typedef struct { 47 atomic_t val; 48 46 49 #ifdef CONFIG_DEBUG_SPINLOCK 47 50 char *name; 48 51 #endif 49 atomic_t val;50 52 } spinlock_t; 51 53 … … 54 56 * where the lock gets initialized in run time. 55 57 */ 56 #define SPINLOCK_DECLARE( slname) spinlock_t slname57 #define SPINLOCK_EXTERN( slname) extern spinlock_t slname58 #define SPINLOCK_DECLARE(lock_name) spinlock_t lock_name 59 #define SPINLOCK_EXTERN(lock_name) extern spinlock_t lock_name 58 60 59 61 /* … … 62 64 */ 63 65 #ifdef CONFIG_DEBUG_SPINLOCK 64 #define SPINLOCK_INITIALIZE(slname) \ 65 spinlock_t slname = { \ 66 .name = #slname, \ 67 .val = { 0 } \ 66 67 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \ 68 spinlock_t lock_name = { \ 69 .name = desc_name, \ 70 .val = { 0 } \ 68 71 } 72 73 #define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 74 static spinlock_t lock_name = { \ 75 .name = desc_name, \ 76 .val = { 0 } \ 77 } 78 79 #define spinlock_lock(lock) spinlock_lock_debug(lock) 80 69 81 #else 70 #define SPINLOCK_INITIALIZE(slname) \ 71 spinlock_t slname = { \ 72 .val = { 0 } \ 82 83 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \ 84 spinlock_t lock_name = { \ 85 .val = { 0 } \ 73 86 } 87 88 #define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 89 static spinlock_t lock_name = { \ 90 .val = { 0 } \ 91 } 92 93 #define spinlock_lock(lock) atomic_lock_arch(&(lock)->val) 94 74 95 #endif 75 96 76 extern void spinlock_initialize(spinlock_t *sl, char *name); 77 extern int spinlock_trylock(spinlock_t *sl); 78 extern void spinlock_lock_debug(spinlock_t *sl); 97 #define SPINLOCK_INITIALIZE(lock_name) \ 98 SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name) 79 99 80 #ifdef CONFIG_DEBUG_SPINLOCK 81 # define spinlock_lock(x) spinlock_lock_debug(x) 82 #else 83 # define spinlock_lock(x) atomic_lock_arch(&(x)->val) 84 #endif 100 #define SPINLOCK_STATIC_INITIALIZE(lock_name) \ 101 SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name) 102 103 extern void spinlock_initialize(spinlock_t *lock, char *name); 104 extern int spinlock_trylock(spinlock_t *lock); 105 extern void spinlock_lock_debug(spinlock_t *lock); 85 106 86 107 /** Unlock spinlock … … 90 111 * @param sl Pointer to spinlock_t structure. 91 112 */ 92 static inline void spinlock_unlock(spinlock_t * sl)113 static inline void spinlock_unlock(spinlock_t *lock) 93 114 { 94 ASSERT(atomic_get(& sl->val) != 0);95 115 ASSERT(atomic_get(&lock->val) != 0); 116 96 117 /* 97 118 * Prevent critical section code from bleeding out this way down. … … 99 120 CS_LEAVE_BARRIER(); 100 121 101 atomic_set(& sl->val, 0);122 atomic_set(&lock->val, 0); 102 123 preemption_enable(); 103 124 } … … 105 126 #ifdef CONFIG_DEBUG_SPINLOCK 106 127 107 extern int printf(const char *, ...); 128 #include <print.h> 108 129 109 #define DEADLOCK_THRESHOLD 100000000 110 #define DEADLOCK_PROBE_INIT(pname) size_t pname = 0 111 #define DEADLOCK_PROBE(pname, value) \ 112 if ((pname)++ > (value)) { \ 113 (pname) = 0; \ 114 printf("Deadlock probe %s: exceeded threshold %u\n", \ 115 "cpu%u: function=%s, line=%u\n", \ 116 #pname, (value), CPU->id, __func__, __LINE__); \ 130 #define DEADLOCK_THRESHOLD 100000000 131 132 #define DEADLOCK_PROBE_INIT(pname) size_t pname = 0 133 134 #define DEADLOCK_PROBE(pname, value) \ 135 if ((pname)++ > (value)) { \ 136 (pname) = 0; \ 137 printf("Deadlock probe %s: exceeded threshold %u\n", \ 138 "cpu%u: function=%s, line=%u\n", \ 139 #pname, (value), CPU->id, __func__, __LINE__); \ 117 140 } 118 #else119 #define DEADLOCK_PROBE_INIT(pname)120 #define DEADLOCK_PROBE(pname, value)121 #endif122 141 123 142 #else 124 143 144 #define DEADLOCK_PROBE_INIT(pname) 145 #define DEADLOCK_PROBE(pname, value) 146 147 #endif 148 149 #else /* CONFIG_SMP */ 150 125 151 /* On UP systems, spinlocks are effectively left out. */ 152 126 153 #define SPINLOCK_DECLARE(name) 127 154 #define SPINLOCK_EXTERN(name) 155 128 156 #define SPINLOCK_INITIALIZE(name) 157 #define SPINLOCK_STATIC_INITIALIZE(name) 129 158 130 #define spinlock_initialize(x, name) 131 #define spinlock_lock(x) preemption_disable() 132 #define spinlock_trylock(x) (preemption_disable(), 1) 133 #define spinlock_unlock(x) preemption_enable() 159 #define SPINLOCK_INITIALIZE_NAME(name, desc_name) 160 #define SPINLOCK_STATIC_INITIALIZE_NAME(name, desc_name) 161 162 #define spinlock_initialize(lock, name) 163 164 #define spinlock_lock(lock) preemption_disable() 165 #define spinlock_trylock(lock) (preemption_disable(), 1) 166 #define spinlock_unlock(lock) preemption_enable() 134 167 135 168 #define DEADLOCK_PROBE_INIT(pname) -
kernel/generic/src/printf/vprintf.c
raf8e565 r90c8b8d 42 42 #include <string.h> 43 43 44 SPINLOCK_ INITIALIZE(printf_lock); /**< vprintf spinlock */44 SPINLOCK_STATIC_INITIALIZE_NAME(printf_lock, "*printf_lock"); 45 45 46 46 static int vprintf_str_write(const char *str, size_t size, void *data) -
kernel/generic/src/synch/spinlock.c
raf8e565 r90c8b8d 45 45 #include <symtab.h> 46 46 47 #ifdef CONFIG_FB48 #include <genarch/fb/fb.h>49 #endif50 51 47 #ifdef CONFIG_SMP 52 48 53 49 /** Initialize spinlock 54 50 * 55 * Initialize spinlock.51 * @param sl Pointer to spinlock_t structure. 56 52 * 57 * @param sl Pointer to spinlock_t structure.58 53 */ 59 void spinlock_initialize(spinlock_t * sl, char *name)54 void spinlock_initialize(spinlock_t *lock, char *name) 60 55 { 61 atomic_set(& sl->val, 0);56 atomic_set(&lock->val, 0); 62 57 #ifdef CONFIG_DEBUG_SPINLOCK 63 sl->name = name;64 #endif 58 lock->name = name; 59 #endif 65 60 } 61 62 #ifdef CONFIG_DEBUG_SPINLOCK 66 63 67 64 /** Lock spinlock … … 71 68 * possible occurence of deadlock. 72 69 * 73 * @param sl Pointer to spinlock_t structure. 70 * @param lock Pointer to spinlock_t structure. 71 * 74 72 */ 75 #ifdef CONFIG_DEBUG_SPINLOCK 76 void spinlock_lock_debug(spinlock_t *sl) 73 void spinlock_lock_debug(spinlock_t *lock) 77 74 { 78 75 size_t i = 0; 79 76 bool deadlock_reported = false; 80 77 81 78 preemption_disable(); 82 while (test_and_set(&sl->val)) { 83 79 while (test_and_set(&lock->val)) { 84 80 /* 85 * We need to be careful about printf_lock and fb_lock. 86 * Both of them are used to report deadlocks via 87 * printf() and fb_putchar(). 81 * We need to be careful about particular locks 82 * which are directly used to report deadlocks 83 * via printf() (and recursively other functions). 84 * This conserns especially printf_lock and the 85 * framebuffer lock. 88 86 * 87 * Any lock whose name is prefixed by "*" will be 88 * ignored by this deadlock detection routine 89 * as this might cause an infinite recursion. 89 90 * We trust our code that there is no possible deadlock 90 * caused by these two locks (except when an exception 91 * is triggered for instance by printf() or fb_putchar()). 92 * However, we encountered false positives caused by very 93 * slow VESA framebuffer interaction (especially when 91 * caused by these locks (except when an exception 92 * is triggered for instance by printf()). 93 * 94 * We encountered false positives caused by very 95 * slow framebuffer interaction (especially when 94 96 * run in a simulator) that caused problems with both 95 * printf_lock and fb_lock.97 * printf_lock and the framebuffer lock. 96 98 * 97 * Possible deadlocks on both printf_lock and fb_lock98 * are therefore not reported as they would cause an99 * infinite recursion.100 99 */ 101 if ( sl == &printf_lock)100 if (lock->name[0] == '*') 102 101 continue; 103 #ifdef CONFIG_FB 104 if (sl == &fb_lock) 105 continue; 106 #endif 102 107 103 if (i++ > DEADLOCK_THRESHOLD) { 108 104 printf("cpu%u: looping on spinlock %" PRIp ":%s, " 109 "caller=%" PRIp "(%s)\n", CPU->id, sl, sl->name,105 "caller=%" PRIp "(%s)\n", CPU->id, lock, lock->name, 110 106 CALLER, symtab_fmt_name_lookup(CALLER)); 111 107 … … 114 110 } 115 111 } 116 112 117 113 if (deadlock_reported) 118 114 printf("cpu%u: not deadlocked\n", CPU->id); 119 115 120 116 /* 121 117 * Prevent critical section code from bleeding out this way up. … … 123 119 CS_ENTER_BARRIER(); 124 120 } 121 125 122 #endif 126 123 … … 131 128 * signal failure. 132 129 * 133 * @param slPointer to spinlock_t structure.130 * @param lock Pointer to spinlock_t structure. 134 131 * 135 132 * @return Zero on failure, non-zero otherwise. 133 * 136 134 */ 137 int spinlock_trylock(spinlock_t * sl)135 int spinlock_trylock(spinlock_t *lock) 138 136 { 139 int rc; 137 preemption_disable(); 138 int rc = !test_and_set(&lock->val); 140 139 141 preemption_disable();142 rc = !test_and_set(&sl->val);143 144 140 /* 145 141 * Prevent critical section code from bleeding out this way up. 146 142 */ 147 143 CS_ENTER_BARRIER(); 148 144 149 145 if (!rc) 150 146 preemption_enable();
Note:
See TracChangeset
for help on using the changeset viewer.