+ IOReturn err;
+ uint32_t idx;
+ IOWorkLoop * wl;
+ IOTimerEventSource * tes;
+ IOInterruptEventSource * ies;
+
+ wl = IOWorkLoop::workLoop();
+ assert(wl);
+ tes = IOTimerEventSource::timerEventSource(kIOTimerEventSourceOptionsPriorityWorkLoop, wl, &TESAction);
+ assert(tes);
+ err = wl->addEventSource(tes);
+ assert(kIOReturnSuccess == err);
+ clock_interval_to_deadline(100, kMillisecondScale, &gIOWorkLoopTestDeadline);
+ for (idx = 0; mach_absolute_time() < gIOWorkLoopTestDeadline; idx++) {
+ tes->setTimeout(idx & 1023, kNanosecondScale);
+ }
+ tes->cancelTimeout();
+ wl->removeEventSource(tes);
+ tes->release();
+
+ int value = 3;
+
+ tes = IOTimerEventSource::timerEventSource(kIOTimerEventSourceOptionsDefault, wl, ^(IOTimerEventSource * tes){
+ kprintf("wl %p, value %d\n", wl, value);
+ });
+ err = wl->addEventSource(tes);
+ assert(kIOReturnSuccess == err);
+
+ value = 2;
+ tes->setTimeout(1, kNanosecondScale);
+ IOSleep(1);
+ wl->removeEventSource(tes);
+ tes->release();
+
+ ies = IOInterruptEventSource::interruptEventSource(wl, NULL, 0, ^void (IOInterruptEventSource *sender, int count){
+ kprintf("ies block %p, %d\n", sender, count);
+ });
+
+ assert(ies);
+ kprintf("ies %p\n", ies);
+ err = wl->addEventSource(ies);
+ assert(kIOReturnSuccess == err);
+ ies->interruptOccurred(NULL, NULL, 0);
+ IOSleep(1);
+ ies->interruptOccurred(NULL, NULL, 0);
+ IOSleep(1);
+ wl->removeEventSource(ies);
+ ies->release();
+
+ wl->release();
+
+ return 0;
+}
+
+static int
+OSCollectionTest(int newValue)
+{
+ OSArray * array = OSArray::withCapacity(8);
+ array->setObject(kOSBooleanTrue);
+ array->setObject(kOSBooleanFalse);
+ array->setObject(kOSBooleanFalse);
+ array->setObject(kOSBooleanTrue);
+ array->setObject(kOSBooleanFalse);
+ array->setObject(kOSBooleanTrue);
+
+ __block unsigned int index;
+ index = 0;
+ array->iterateObjects(^bool (OSObject * obj) {
+ kprintf("%d:%d ", index, (obj == kOSBooleanTrue) ? 1 : (obj == kOSBooleanFalse) ? 0 : 2);
+ index++;
+ return false;
+ });
+ kprintf("\n");
+ array->release();
+
+ OSDictionary * dict = IOService::resourceMatching("hello");
+ assert(dict);
+ index = 0;
+ dict->iterateObjects(^bool (const OSSymbol * sym, OSObject * obj) {
+ OSString * str = OSDynamicCast(OSString, obj);
+ assert(str);
+ kprintf("%d:%s=%s\n", index, sym->getCStringNoCopy(), str->getCStringNoCopy());
+ index++;
+ return false;
+ });
+ dict->release();
+
+ OSSerializer * serializer = OSSerializer::withBlock(^bool (OSSerialize * s){
+ return gIOBSDUnitKey->serialize(s);
+ });
+ assert(serializer);
+ IOService::getPlatform()->setProperty("OSSerializer_withBlock", serializer);
+ serializer->release();
+
+ return 0;
+}
+
+static int
+OSAllocationTests(int)
+{
+ OSAllocation<int> ints(100, OSAllocateMemory);
+ assert(ints);
+
+ {
+ int counter = 0;
+ for (int& i : ints) {
+ i = counter++;
+ }
+ }
+
+ {
+ int counter = 0;
+ for (int& i : ints) {
+ assert(i == counter);
+ ++counter;
+ }
+ }
+
+ // Make sure we can have two-level OSAllocations
+ {
+ OSAllocation<OSAllocation<int> > testArray(10, OSAllocateMemory);
+ for (int i = 0; i < 10; i++) {
+ testArray[i] = OSAllocation<int>(10, OSAllocateMemory);
+ for (int j = 0; j < 10; ++j) {
+ testArray[i][j] = i + j;
+ }
+ }
+
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; ++j) {
+ assert(testArray[i][j] == i + j);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+OSBoundedArrayTests(int)
+{
+ OSBoundedArray<int, 5> ints = {0, 1, 2, 3, 4};
+ assert(ints.size() == 5);
+
+ {
+ int counter = 0;
+ for (int& i : ints) {
+ i = counter++;
+ }
+ }
+
+ {
+ int counter = 0;
+ for (int& i : ints) {
+ assert(i == counter);
+ ++counter;
+ }
+ }
+
+ return 0;
+}
+
+static int
+OSBoundedArrayRefTests(int)
+{
+ OSBoundedArray<int, 5> storage = {0, 1, 2, 3, 4};
+ OSBoundedArrayRef<int> ints(storage);
+ assert(ints);
+
+ {
+ int counter = 0;
+ for (int& i : ints) {
+ i = counter++;
+ }
+ }
+
+ {
+ int counter = 0;
+ for (int& i : ints) {
+ assert(i == counter);
+ ++counter;
+ }
+ }
+
+ return 0;
+}
+
+static int
+OSBoundedPtrTests(int)
+{
+ int array[5] = {55, 66, 77, 88, 99};
+ OSBoundedPtr<int> begin(&array[0], &array[0], &array[5]);
+ OSBoundedPtr<int> end(&array[5], &array[0], &array[5]);
+
+ {
+ int counter = 0;
+ for (OSBoundedPtr<int> b = begin; b != end; ++b) {
+ *b = counter++;
+ }
+ }
+
+ {
+ int counter = 0;
+ for (OSBoundedPtr<int> b = begin; b != end; ++b) {
+ assert(*b == counter);
+ ++counter;
+ }
+ }
+
+ return 0;
+}
+
+static int
+IOSharedDataQueue_44636964(__unused int newValue)
+{
+ IOSharedDataQueue* sd = IOSharedDataQueue::withCapacity(DATA_QUEUE_ENTRY_HEADER_SIZE + sizeof(UInt64));
+ UInt64 data = 0x11223344aa55aa55;
+ UInt32 data2 = 0x44332211;
+ UInt32 size = sizeof(UInt32);
+ /* enqueue moves tail to end */
+ sd->enqueue(&data, sizeof(UInt64));
+ /* dequeue moves head to end */
+ sd->dequeue(&data, &size);
+ /* Tail wraps around, head is still at end */
+ sd->enqueue(&data2, sizeof(UInt32));
+ /* something in the queue so peek() should return non-null */
+ assert(sd->peek() != NULL);
+ return KERN_SUCCESS;
+}
+
+#if 0
+#include <IOKit/IOUserClient.h>
+class TestUserClient : public IOUserClient
+{
+ OSDeclareDefaultStructors(TestUserClient);
+ virtual void stop( IOService *provider) APPLE_KEXT_OVERRIDE;
+ virtual bool finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE;
+ virtual IOReturn externalMethod( uint32_t selector,
+ IOExternalMethodArguments * arguments,
+ IOExternalMethodDispatch * dispatch,
+ OSObject * target,
+ void * reference ) APPLE_KEXT_OVERRIDE;
+};
+
+void
+TestUserClient::stop( IOService *provider)
+{
+ kprintf("TestUserClient::stop\n");
+}
+bool
+TestUserClient::finalize(IOOptionBits options)
+{
+ kprintf("TestUserClient::finalize\n");
+ return true;
+}
+IOReturn
+TestUserClient::externalMethod( uint32_t selector,
+ IOExternalMethodArguments * arguments,
+ IOExternalMethodDispatch * dispatch,
+ OSObject * target,
+ void * reference )
+{
+ getProvider()->terminate();
+ IOSleep(500);
+ return 0;
+}
+OSDefineMetaClassAndStructors(TestUserClient, IOUserClient);
+#endif
+
+static int
+IOServiceTest(int newValue)
+{
+ OSDictionary * matching;
+ IONotifier * note;
+ __block IOService * found;
+
+#if 0
+ found = new IOService;
+ found->init();
+ found->setName("IOTestUserClientProvider");
+ found->attach(IOService::getPlatform());
+ found->setProperty("IOUserClientClass", "TestUserClient");
+ found->registerService();
+#endif
+
+ matching = IOService::serviceMatching("IOPlatformExpert");
+ assert(matching);
+ found = nullptr;
+ note = IOService::addMatchingNotification(gIOMatchedNotification, matching, 0,
+ ^bool (IOService * newService, IONotifier * notifier) {
+ kprintf("found %s, %d\n", newService->getName(), newService->getRetainCount());
+ found = newService;
+ found->retain();
+ return true;
+ }
+ );
+ assert(note);
+ assert(found);
+ matching->release();
+ note->remove();
+
+ note = found->registerInterest(gIOBusyInterest,
+ ^IOReturn (uint32_t messageType, IOService * provider,
+ void * messageArgument, size_t argSize) {
+ kprintf("%p messageType 0x%08x %p\n", provider, messageType, messageArgument);
+ return kIOReturnSuccess;
+ });
+ assert(note);
+ IOSleep(1 * 1000);
+ note->remove();
+ found->release();
+
+ return 0;
+}
+
+static void
+OSStaticPtrCastTests()
+{
+ // const& overload
+ {
+ OSSharedPtr<OSDictionary> const dict = OSMakeShared<OSDictionary>();
+ OSSharedPtr<OSCollection> collection = OSStaticPtrCast<OSCollection>(dict);
+ assert(collection == dict);
+ }
+ {
+ OSSharedPtr<OSDictionary> const dict = nullptr;
+ OSSharedPtr<OSCollection> collection = OSStaticPtrCast<OSCollection>(dict);
+ assert(collection == nullptr);
+ }
+ // && overload
+ {
+ OSSharedPtr<OSDictionary> dict = OSMakeShared<OSDictionary>();
+ OSDictionary* oldDict = dict.get();
+ OSSharedPtr<OSCollection> collection = OSStaticPtrCast<OSCollection>(os::move(dict));
+ assert(collection.get() == oldDict);
+ assert(dict == nullptr);
+ }
+ {
+ OSSharedPtr<OSDictionary> dict = nullptr;
+ OSSharedPtr<OSCollection> collection = OSStaticPtrCast<OSCollection>(os::move(dict));
+ assert(collection == nullptr);
+ assert(dict == nullptr);
+ }
+}
+
+static void
+OSConstPtrCastTests()
+{
+ // const& overload
+ {
+ OSSharedPtr<OSDictionary const> const dict = OSMakeShared<OSDictionary>();
+ OSSharedPtr<OSDictionary> dict2 = OSConstPtrCast<OSDictionary>(dict);
+ assert(dict2 == dict);
+ }
+ {
+ OSSharedPtr<OSDictionary const> const dict = OSMakeShared<OSDictionary>();
+ OSSharedPtr<OSDictionary const> dict2 = OSConstPtrCast<OSDictionary const>(dict);
+ assert(dict2 == dict);
+ }
+ {
+ OSSharedPtr<OSDictionary const> const dict = nullptr;
+ OSSharedPtr<OSDictionary> dict2 = OSConstPtrCast<OSDictionary>(dict);
+ assert(dict2 == nullptr);
+ }
+ {
+ OSSharedPtr<OSDictionary const> const dict = nullptr;
+ OSSharedPtr<OSDictionary const> dict2 = OSConstPtrCast<OSDictionary const>(dict);
+ assert(dict2 == nullptr);
+ }
+
+ // && overload
+ {
+ OSSharedPtr<OSDictionary const> dict = OSMakeShared<OSDictionary>();
+ OSDictionary const* oldDict = dict.get();
+ OSSharedPtr<OSDictionary> dict2 = OSConstPtrCast<OSDictionary>(os::move(dict));
+ assert(dict == nullptr);
+ assert(dict2 == oldDict);
+ }
+ {
+ OSSharedPtr<OSDictionary const> dict = nullptr;
+ OSSharedPtr<OSDictionary> dict2 = OSConstPtrCast<OSDictionary>(os::move(dict));
+ assert(dict == nullptr);
+ assert(dict2 == nullptr);
+ }
+}
+
+static void
+OSDynamicPtrCastTests()
+{
+ OSSharedPtr<OSDictionary> const dict = OSMakeShared<OSDictionary>();
+ {
+ OSSharedPtr<OSCollection> collection = OSDynamicPtrCast<OSCollection>(dict);
+ assert(collection != nullptr);
+ }
+ {
+ OSSharedPtr<OSArray> array = OSDynamicPtrCast<OSArray>(dict);
+ assert(array == nullptr);
+ assert(dict != nullptr);
+ }
+ {
+ OSTaggedSharedPtr<OSCollection, OSCollection> taggedDict(dict.get(), OSRetain);
+ OSTaggedSharedPtr<OSCollection, OSCollection> collection = OSDynamicPtrCast<OSCollection>(taggedDict);
+ assert(collection != nullptr);
+ }
+ {
+ OSTaggedSharedPtr<OSCollection, OSCollection> taggedDict(dict.get(), OSRetain);
+ OSTaggedSharedPtr<OSArray, OSCollection> array = OSDynamicPtrCast<OSArray>(taggedDict);
+ assert(array == nullptr);
+ assert(dict != nullptr);
+ }
+ {
+ OSSharedPtr<OSCollection> collection = OSDynamicPtrCast<OSCollection>(dict);
+ assert(collection.get() == OSDynamicCast(OSDictionary, dict.get()));
+ OSSharedPtr<OSDictionary> newDict = OSDynamicPtrCast<OSDictionary>(os::move(collection));
+ assert(collection == nullptr);
+ assert(newDict != nullptr);
+ assert(newDict.get() == dict.get());
+ }
+}
+
+static int
+OSSharedPtrTests(int)
+{
+ OSDynamicPtrCastTests();
+ OSConstPtrCastTests();
+ OSStaticPtrCastTests();
+ return 0;