this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement down_timeout_interruptible() because Linux kernel doesn't have that API

+50 -1
+50 -1
src/lkm/primitives/semaphore.c
··· 26 26 #include <linux/slab.h> 27 27 #include <linux/atomic.h> 28 28 #include <linux/version.h> 29 + #include <linux/sched.h> 30 + #include <linux/list.h> 29 31 30 32 static atomic_t sem_count = ATOMIC_INIT(0); 31 33 ··· 153 155 return ret; 154 156 } 155 157 158 + // Copied from kernel/locking/semaphore.c (explanation below) 159 + // This MUST MATCH the private definition in kernel! 160 + struct semaphore_waiter { 161 + struct list_head list; 162 + struct task_struct *task; 163 + bool up; 164 + }; 165 + 166 + // Copied from kernel/locking/semaphore.c because down_timeout_interruptible() 167 + // doesn't exist. 168 + // Otherwise, Darwin sleep() would not be interruptible by signals. 169 + static inline int __down_common(struct semaphore *sem, long state, 170 + long timeout) { 171 + struct task_struct *task = current; 172 + struct semaphore_waiter waiter; 173 + 174 + list_add_tail(&waiter.list, &sem->wait_list); 175 + waiter.task = task; 176 + waiter.up = false; 177 + 178 + for (;;) { 179 + if (signal_pending_state(state, task)) 180 + goto interrupted; 181 + if (unlikely(timeout <= 0)) 182 + goto timed_out; 183 + __set_task_state(task, state); 184 + raw_spin_unlock_irq(&sem->lock); 185 + timeout = schedule_timeout(timeout); 186 + raw_spin_lock_irq(&sem->lock); 187 + if (waiter.up) 188 + return 0; 189 + } 190 + 191 + timed_out: 192 + list_del(&waiter.list); 193 + return -ETIME; 194 + 195 + interrupted: 196 + list_del(&waiter.list); 197 + return -EINTR; 198 + } 199 + 200 + static int down_timeout_interruptible(struct semaphore *sem, long timeout) 201 + { 202 + return __down_common(sem, TASK_INTERRUPTIBLE, timeout); 203 + } 204 + 156 205 kern_return_t 157 206 mach_semaphore_timedwait(darling_mach_port_t* port, unsigned int sec, 158 207 unsigned int nsec) ··· 182 231 jiffies = nsecs_to_jiffies(((u64) sec) * NSEC_PER_SEC + nsec); 183 232 #endif 184 233 185 - err = down_timeout(&ms->sem, jiffies); 234 + err = down_timeout_interruptible(&ms->sem, jiffies); 186 235 if (err == -ETIME) 187 236 ret = KERN_OPERATION_TIMED_OUT; 188 237 else if (err == -EINTR)