1/*
2 *  testthreadcall.cpp
3 *  testkext
4 *
5 */
6
7#include "testthreadcall.h"
8
9#include <kern/thread_call.h>
10
11#define super IOService
12OSDefineMetaClassAndStructors(testthreadcall, super);
13
14extern "C" {
15
16static void thread_call_test_func(thread_call_param_t param0,
17								  thread_call_param_t param1);
18
19static void thread_call_test_func2(thread_call_param_t param0,
20								  thread_call_param_t param1);
21
22}
23
24bool
25testthreadcall::start( IOService * provider )
26{
27	boolean_t ret;
28	uint64_t deadline;
29	int sleepret;
30
31    IOLog("%s\n", __PRETTY_FUNCTION__);
32
33    if (!super::start(provider)) {
34        return false;
35    }
36
37    IOLog("Attempting thread_call_allocate\n");
38	tcall = thread_call_allocate(thread_call_test_func, this);
39    IOLog("thread_call_t %p\n", tcall);
40
41	tlock = IOSimpleLockAlloc();
42	IOLog("tlock %p\n", tlock);
43
44	clock_interval_to_deadline(5, NSEC_PER_SEC, &deadline);
45	IOLog("%d sec deadline is %llu\n", 5, deadline);
46
47	ret = thread_call_enter_delayed(tcall, deadline);
48
49    IOLog("Attempting thread_call_allocate\n");
50    tcall2 = thread_call_allocate(thread_call_test_func2, this);
51    IOLog("thread_call_t %p\n", tcall);
52
53    tlock2 = IOLockAlloc();
54    IOLog("tlock2 %p\n", tlock2);
55
56    clock_interval_to_deadline(2, NSEC_PER_SEC, &deadline);
57    IOLog("%d sec deadline is %llu\n", 2, deadline);
58
59    ret = thread_call_enter_delayed(tcall2, deadline);
60
61    IOLockLock(tlock2);
62
63    clock_interval_to_deadline(3, NSEC_PER_SEC, &deadline);
64    IOLog("%d sec deadline is %llu\n", 3, deadline);
65    sleepret = IOLockSleepDeadline(tlock2, NULL, deadline, THREAD_INTERRUPTIBLE);
66    IOLog("IOLockSleepDeadline(NULL, %llu) returned %d, expected 0\n", deadline, sleepret);
67
68    IOLockUnlock(tlock2);
69
70    clock_interval_to_deadline(4, NSEC_PER_SEC, &deadline);
71    IOLog("%d sec deadline is %llu\n", 4, deadline);
72
73    ret = thread_call_enter_delayed(tcall2, deadline);
74
75    IOLockLock(tlock2);
76
77    clock_interval_to_deadline(3, NSEC_PER_SEC, &deadline);
78    IOLog("%d sec deadline is %llu\n", 3, deadline);
79    sleepret = IOLockSleepDeadline(tlock2, NULL, deadline, THREAD_INTERRUPTIBLE);
80    IOLog("IOLockSleepDeadline(NULL, %llu) returned %d, expected 1\n", deadline, sleepret);
81
82    IOLockUnlock(tlock2);
83
84    return true;
85}
86
87static void thread_call_test_func(thread_call_param_t param0,
88								  thread_call_param_t param1)
89{
90	testthreadcall *self = (testthreadcall *)param0;
91
92	IOLog("thread_call_test_func %p %p\n", param0, param1);
93
94	IOSimpleLockLock(self->tlock);
95	IOSimpleLockUnlock(self->tlock);
96}
97
98static void thread_call_test_func2(thread_call_param_t param0,
99								  thread_call_param_t param1)
100{
101	testthreadcall *self = (testthreadcall *)param0;
102
103	IOLog("thread_call_test_func2 %p %p\n", param0, param1);
104
105	IOLockWakeup(self->tlock2, NULL, false);
106}
107