1#include <config.h>
2
3#include "preempt.h"
4
5#include "assume.h"
6#include "locks.h"
7
8
9#define CPU_PREEMPTION_LOCKS_INIT0 LOCK_IMPL_INITIALIZER
10#define CPU_PREEMPTION_LOCKS_INIT1 \
11 CPU_PREEMPTION_LOCKS_INIT0, CPU_PREEMPTION_LOCKS_INIT0
12#define CPU_PREEMPTION_LOCKS_INIT2 \
13 CPU_PREEMPTION_LOCKS_INIT1, CPU_PREEMPTION_LOCKS_INIT1
14#define CPU_PREEMPTION_LOCKS_INIT3 \
15 CPU_PREEMPTION_LOCKS_INIT2, CPU_PREEMPTION_LOCKS_INIT2
16#define CPU_PREEMPTION_LOCKS_INIT4 \
17 CPU_PREEMPTION_LOCKS_INIT3, CPU_PREEMPTION_LOCKS_INIT3
18#define CPU_PREEMPTION_LOCKS_INIT5 \
19 CPU_PREEMPTION_LOCKS_INIT4, CPU_PREEMPTION_LOCKS_INIT4
20
21
22
23
24
25struct lock_impl cpu_preemption_locks[NR_CPUS] = {
26 CPU_PREEMPTION_LOCKS_INIT0
27#if (NR_CPUS - 1) & 1
28 , CPU_PREEMPTION_LOCKS_INIT0
29#endif
30#if (NR_CPUS - 1) & 2
31 , CPU_PREEMPTION_LOCKS_INIT1
32#endif
33#if (NR_CPUS - 1) & 4
34 , CPU_PREEMPTION_LOCKS_INIT2
35#endif
36#if (NR_CPUS - 1) & 8
37 , CPU_PREEMPTION_LOCKS_INIT3
38#endif
39#if (NR_CPUS - 1) & 16
40 , CPU_PREEMPTION_LOCKS_INIT4
41#endif
42#if (NR_CPUS - 1) & 32
43 , CPU_PREEMPTION_LOCKS_INIT5
44#endif
45};
46
47#undef CPU_PREEMPTION_LOCKS_INIT0
48#undef CPU_PREEMPTION_LOCKS_INIT1
49#undef CPU_PREEMPTION_LOCKS_INIT2
50#undef CPU_PREEMPTION_LOCKS_INIT3
51#undef CPU_PREEMPTION_LOCKS_INIT4
52#undef CPU_PREEMPTION_LOCKS_INIT5
53
54__thread int thread_cpu_id;
55__thread int preempt_disable_count;
56
57void preempt_disable(void)
58{
59 BUG_ON(preempt_disable_count < 0 || preempt_disable_count == INT_MAX);
60
61 if (preempt_disable_count++)
62 return;
63
64 thread_cpu_id = nondet_int();
65 assume(thread_cpu_id >= 0);
66 assume(thread_cpu_id < NR_CPUS);
67 lock_impl_lock(&cpu_preemption_locks[thread_cpu_id]);
68}
69
70void preempt_enable(void)
71{
72 BUG_ON(preempt_disable_count < 1);
73
74 if (--preempt_disable_count)
75 return;
76
77 lock_impl_unlock(&cpu_preemption_locks[thread_cpu_id]);
78}
79