build/ccw_gen: stat the file in C instead of shelling out
[hvf.git] / cp / nucleus / ldep.c
blobdf2197adcbde16051f076268ca76ae2fd1207252
1 /*
2 * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * This file is released under the GPLv2. See the COPYING file for more
5 * details.
6 */
8 #include <sclp.h>
9 #include <sched.h>
10 #include <list.h>
11 #include <spinlock.h>
12 #include <ldep.h>
14 static spinlock_t __lock = SPIN_LOCK_UNLOCKED;
15 static int ldep_enabled;
17 void ldep_on()
19 unsigned long mask;
21 spin_lock_intsave(&__lock, &mask);
22 ldep_enabled = 1;
23 spin_unlock_intrestore(&__lock, mask);
26 static int __get_stack_slot()
28 current->nr_locks++;
30 if (current->nr_locks == LDEP_STACK_SIZE) {
31 sclp_msg("task '%s' exceeded the number of tracked "
32 "locks (%d)! disabling ldep!\n", current->name,
33 LDEP_STACK_SIZE);
34 return 1;
37 return 0;
40 static void ldep_warn_head(char *lockname, void *addr)
42 sclp_msg("task '%s' is trying to acquire lock:\n", current->name);
43 sclp_msg(" (%s), at: %p\n\n", lockname, addr);
46 static void ldep_warn_recursive(char *lockname, void *addr, struct held_lock *held)
48 sclp_msg("[INFO: possible recursive locking detected]\n");
50 ldep_warn_head(lockname, addr);
52 sclp_msg("but task is already holding lock:\n\n");
53 sclp_msg(" (%s), at: %p\n\n", held->lockname, held->ra);
56 static void print_held_locks()
58 struct held_lock *cur;
59 int i;
61 sclp_msg("\nlocks currently held:\n");
62 for(i=0; i<current->nr_locks; i++) {
63 cur = &current->lock_stack[i];
64 sclp_msg(" #%d: (%s), at %p\n", i, cur->lockname, cur->ra);
68 void ldep_lock(void *lock, struct lock_class *c, char *lockname)
70 void *ra = __builtin_return_address(0);
71 struct held_lock *cur;
72 unsigned long mask;
73 // int ret;
74 int i;
76 // LOCK
77 spin_lock_intsave(&__lock, &mask);
79 if (!ldep_enabled)
80 goto out;
82 if (current->nr_locks) {
83 /* check for recursive locking */
84 for(i=0; i<current->nr_locks; i++) {
85 cur = &current->lock_stack[i];
86 if (cur->lclass != c)
87 continue;
89 ldep_warn_recursive(lockname, ra, cur);
90 ldep_enabled = 0;
91 goto out;
95 /* ok, no issues, add the lock we're trying to get to the stack */
96 if (__get_stack_slot())
97 goto out;
99 cur = &current->lock_stack[current->nr_locks-1];
100 cur->ra = ra;
101 cur->lock = lock;
102 cur->lockname = lockname;
103 cur->lclass = c;
105 out:
106 // UNLOCK
107 spin_unlock_intrestore(&__lock, mask);
110 void ldep_unlock(void *lock, char *lockname)
112 void *ra = __builtin_return_address(0);
113 struct held_lock *cur;
114 unsigned long mask;
115 int i;
117 // LOCK
118 spin_lock_intsave(&__lock, &mask);
120 if (!ldep_enabled)
121 goto out;
123 for(i=0; i<current->nr_locks; i++) {
124 cur = &current->lock_stack[i];
125 if (cur->lock == lock)
126 goto found;
129 sclp_msg("task '%s' is trying to release lock it doesn't have:\n",
130 current->name);
131 sclp_msg(" (%s), at %p\n", lockname, ra);
132 print_held_locks();
134 ldep_enabled = 0;
136 goto out;
138 found:
139 if (i != current->nr_locks-1)
140 memcpy(&current->lock_stack[i],
141 &current->lock_stack[i+1],
142 current->nr_locks - i - 1);
144 current->nr_locks--;
146 out:
147 // UNLOCK
148 spin_unlock_intrestore(&__lock, mask);
151 void ldep_no_locks()
153 void *ra = __builtin_return_address(0);
154 unsigned long mask;
156 // LOCK
157 spin_lock_intsave(&__lock, &mask);
159 if (!ldep_enabled)
160 goto out;
162 if (!current->nr_locks)
163 goto out;
165 sclp_msg("task '%s' is holding a lock when it shouldn't have:\n",
166 current->name);
167 sclp_msg(" at %p\n", ra);
168 print_held_locks();
170 ldep_enabled = 0;
172 out:
173 // UNLOCK
174 spin_unlock_intrestore(&__lock, mask);