SmartBatteryUserClient.c [plain text]
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <XILog/XILog.h>
#include <stdio.h>
#include <unistd.h>
#define kBatteryManagerName "AppleSmartBatteryManager"
#define kMaxSecondsUCOperation 3.15
#define kUCExclusiveIterationsCount 10
#define kUCIterationsCount 25
enum {
kBatteryExclusiveAccessType = 1
};
io_connect_t connectSmartBatteryManager(uint32_t options, IOReturn *outret);
int main(int argc, char *argv[]) {
io_connect_t manager_connect = IO_OBJECT_NULL;
uint32_t openfailure = 0;
uint32_t closefailure = 0;
uint32_t ucOpenedCount = 0;
uint32_t ucExclusiveOpenedCount = 0;
IOReturn connectreturn = 0;
kern_return_t kernreturn = 0;
CFAbsoluteTime start_time = 0.0;
CFAbsoluteTime end_time = 0.0;
CFTimeInterval elapsed_time = 0.0;
char *XIconfig = NULL;
int XIecho = true;
int XIxml = false;
char *XILogPath = NULL;
XILogRef logRef = XILogOpenLog(XILogPath, "SmartBatteryUserClient", "com.apple.iokit.ethan", XIconfig, XIxml, XIecho);
XILogBeginTestCase(logRef, "SmartBatteryUserClientTest", "Create and destroy many user clients in series.");
while ( (ucOpenedCount < kUCIterationsCount) && (ucExclusiveOpenedCount < kUCExclusiveIterationsCount))
{
if (ucOpenedCount < kUCIterationsCount)
{
start_time = CFAbsoluteTimeGetCurrent();
manager_connect = connectSmartBatteryManager(0, &connectreturn);
if (MACH_PORT_NULL == manager_connect)
{
XILogErr("IOServiceOpen error 0x%08x opening %s\n", connectreturn, kBatteryManagerName);
openfailure++;
} else {
end_time = CFAbsoluteTimeGetCurrent();
elapsed_time = end_time - start_time;
XILogMsg("User client opened successfully in %d.%02d seconds", (int)elapsed_time, (int)(100.0 * elapsed_time)%100);
if (elapsed_time > kMaxSecondsUCOperation) {
XILogErr("Error - opening user client took %d.%02d, exceeding %d.%02d",
(int)elapsed_time, (int)(100.0 * elapsed_time)%100,
(int)kMaxSecondsUCOperation, (int)(100.0*kMaxSecondsUCOperation)%100);
}
start_time = CFAbsoluteTimeGetCurrent();
kernreturn = IOServiceClose(manager_connect);
if (KERN_SUCCESS != kernreturn) {
XILogErr("IOServiceClose error %d closing user client.", kernreturn);
closefailure++;
} else {
end_time = CFAbsoluteTimeGetCurrent();
elapsed_time = end_time - start_time;
XILogMsg("User client closed successfully in %d.%02d seconds", (int)elapsed_time, (int)(100.0 * elapsed_time)%100);
if (elapsed_time > kMaxSecondsUCOperation) {
XILogErr("Error - closing user client took %d.%02d, exceeding %d.%02d",
(int)elapsed_time, (int)(100.0 * elapsed_time)%100,
(int)kMaxSecondsUCOperation, (int)(100.0*kMaxSecondsUCOperation)%100);
}
}
}
ucOpenedCount++;
}
if (ucExclusiveOpenedCount < kUCExclusiveIterationsCount)
{
start_time = CFAbsoluteTimeGetCurrent();
manager_connect = connectSmartBatteryManager(kBatteryExclusiveAccessType, &connectreturn);
if (MACH_PORT_NULL == manager_connect)
{
XILogErr("IOServiceOpen error 0x%08x opening exclusive %s", connectreturn, kBatteryManagerName);
openfailure++;
} else {
end_time = CFAbsoluteTimeGetCurrent();
elapsed_time = end_time - start_time;
XILogMsg("User client EXCLUSIVE opened successfully in %d.%02d seconds", (int)elapsed_time, (int)(100.0 * elapsed_time)%100);
if (elapsed_time > kMaxSecondsUCOperation) {
XILogErr("Error - opening EXCLUSIVE user client took %d.%02d, exceeding %d.%02d",
(int)elapsed_time, (int)(100.0 * elapsed_time)%100,
(int)kMaxSecondsUCOperation, (int)(100.0*kMaxSecondsUCOperation)%100);
}
start_time = CFAbsoluteTimeGetCurrent();
kernreturn = IOServiceClose(manager_connect);
if (KERN_SUCCESS != kernreturn) {
XILogErr("IOServiceClose error %d closing user client.", kernreturn);
closefailure++;
} else {
end_time = CFAbsoluteTimeGetCurrent();
elapsed_time = end_time - start_time;
XILogMsg("User client EXCLUSIVE closed successfully in %d.%02d seconds", (int)elapsed_time, (int)(100.0 * elapsed_time)%100);
if (elapsed_time > kMaxSecondsUCOperation) {
XILogErr("Error - closing EXCLUSIVE user client took %d.%02d, exceeding %d.%02d",
(int)elapsed_time, (int)(100.0 * elapsed_time)%100,
(int)kMaxSecondsUCOperation, (int)(100.0*kMaxSecondsUCOperation)%100);
}
}
}
ucExclusiveOpenedCount++;
}
}
XILogMsg("SmartBatteryUserClient test completed: opened %d clients and %d exclusive clients",
ucOpenedCount, ucExclusiveOpenedCount);
if (openfailure == 0 && closefailure == 0)
{
XILogMsg("Success.");
} else {
if (openfailure) {
XILogMsg("Test completed with %d failures opening the user client.", openfailure);
}
if (closefailure) {
XILogMsg("Test completed with %d failures closing the user client.", closefailure);
}
}
XILogEndTestCase(logRef, kXILogTestPassOnErrorLevel);
return 0;
}
io_connect_t connectSmartBatteryManager(uint32_t options, IOReturn *outret)
{
io_service_t smartbattman_entry = MACH_PORT_NULL;
io_connect_t manager_connect = MACH_PORT_NULL;
IOReturn ret;
smartbattman_entry = IOServiceGetMatchingService( MACH_PORT_NULL,
IOServiceNameMatching(kBatteryManagerName) );
if (MACH_PORT_NULL == smartbattman_entry) {
return MACH_PORT_NULL;
}
ret = IOServiceOpen( smartbattman_entry,
mach_task_self(),
options,
&manager_connect);
if (outret) *outret = ret;
if(kIOReturnSuccess != ret) {
return MACH_PORT_NULL;
}
IOObjectRelease(smartbattman_entry);
return manager_connect;
}