xref: /xnu-12377.41.6/tools/tests/perf_index/PerfIndex_COPS_Module/PITest.m (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1*bbb1b6f9SApple OSS Distributions//
2*bbb1b6f9SApple OSS Distributions//  PITest.m
3*bbb1b6f9SApple OSS Distributions//  PerfIndex
4*bbb1b6f9SApple OSS Distributions//
5*bbb1b6f9SApple OSS Distributions//  Created by Mark Hamilton on 8/21/13.
6*bbb1b6f9SApple OSS Distributions//
7*bbb1b6f9SApple OSS Distributions//
8*bbb1b6f9SApple OSS Distributions
9*bbb1b6f9SApple OSS Distributions#import "PITest.h"
10*bbb1b6f9SApple OSS Distributions#include <dlfcn.h>
11*bbb1b6f9SApple OSS Distributions#include <pthread.h>
12*bbb1b6f9SApple OSS Distributions
13*bbb1b6f9SApple OSS Distributions@implementation PITest
14*bbb1b6f9SApple OSS Distributions
15*bbb1b6f9SApple OSS Distributions+ (id)testWithOptions:(NSDictionary *)options
16*bbb1b6f9SApple OSS Distributions{
17*bbb1b6f9SApple OSS Distributions    PITest *instance = nil;
18*bbb1b6f9SApple OSS Distributions    if(instance == nil)
19*bbb1b6f9SApple OSS Distributions        instance = [[PITest alloc] init];
20*bbb1b6f9SApple OSS Distributions    [instance setTestName:[options objectForKey:@"name"]];
21*bbb1b6f9SApple OSS Distributions    return instance;
22*bbb1b6f9SApple OSS Distributions}
23*bbb1b6f9SApple OSS Distributions
24*bbb1b6f9SApple OSS Distributions- (BOOL)loadPITestAtPath:(NSString*) path
25*bbb1b6f9SApple OSS Distributions{
26*bbb1b6f9SApple OSS Distributions    void* handle;
27*bbb1b6f9SApple OSS Distributions    void* f;
28*bbb1b6f9SApple OSS Distributions
29*bbb1b6f9SApple OSS Distributions    handle = dlopen([path UTF8String], RTLD_NOW | RTLD_LOCAL);
30*bbb1b6f9SApple OSS Distributions    if(!handle) {
31*bbb1b6f9SApple OSS Distributions        return NO;
32*bbb1b6f9SApple OSS Distributions    }
33*bbb1b6f9SApple OSS Distributions
34*bbb1b6f9SApple OSS Distributions
35*bbb1b6f9SApple OSS Distributions    f = dlsym(handle, "setup");
36*bbb1b6f9SApple OSS Distributions    self->setup_func = (int (*)(int, long long, int, void **))f;
37*bbb1b6f9SApple OSS Distributions
38*bbb1b6f9SApple OSS Distributions    f = dlsym(handle, "execute");
39*bbb1b6f9SApple OSS Distributions    self->execute_func = (int (*)(int, int, long long, int, void **))f;
40*bbb1b6f9SApple OSS Distributions    if(!self->execute_func)
41*bbb1b6f9SApple OSS Distributions        return NO;
42*bbb1b6f9SApple OSS Distributions
43*bbb1b6f9SApple OSS Distributions    f = dlsym(handle, "cleanup");
44*bbb1b6f9SApple OSS Distributions    self->cleanup_func = (void (*)(int, long long))f;
45*bbb1b6f9SApple OSS Distributions    return YES;
46*bbb1b6f9SApple OSS Distributions}
47*bbb1b6f9SApple OSS Distributions
48*bbb1b6f9SApple OSS Distributions- (long long)lengthForTest:(NSString*) testName
49*bbb1b6f9SApple OSS Distributions{
50*bbb1b6f9SApple OSS Distributions    NSNumber* number;
51*bbb1b6f9SApple OSS Distributions    long long myLength;
52*bbb1b6f9SApple OSS Distributions    NSDictionary* lengths = [NSDictionary dictionaryWithObjectsAndKeys:
53*bbb1b6f9SApple OSS Distributions        @"cpu", [NSNumber numberWithLongLong:2000],
54*bbb1b6f9SApple OSS Distributions        @"syscall", [NSNumber numberWithLongLong:2500],
55*bbb1b6f9SApple OSS Distributions        @"memory", [NSNumber numberWithLongLong:1000000],
56*bbb1b6f9SApple OSS Distributions        @"fault", [NSNumber numberWithLongLong:500],
57*bbb1b6f9SApple OSS Distributions        @"zfod", [NSNumber numberWithLongLong:500],
58*bbb1b6f9SApple OSS Distributions        @"file_create", [NSNumber numberWithLongLong:10],
59*bbb1b6f9SApple OSS Distributions        @"file_read", [NSNumber numberWithLongLong:1000000],
60*bbb1b6f9SApple OSS Distributions        @"file_write", [NSNumber numberWithLongLong:1000000],
61*bbb1b6f9SApple OSS Distributions    nil];
62*bbb1b6f9SApple OSS Distributions
63*bbb1b6f9SApple OSS Distributions    number = (NSNumber*)[lengths objectForKey:testName];
64*bbb1b6f9SApple OSS Distributions    if(!number) {
65*bbb1b6f9SApple OSS Distributions        myLength = 10;
66*bbb1b6f9SApple OSS Distributions    } else {
67*bbb1b6f9SApple OSS Distributions        myLength = [number longLongValue];
68*bbb1b6f9SApple OSS Distributions    }
69*bbb1b6f9SApple OSS Distributions
70*bbb1b6f9SApple OSS Distributions    return myLength;
71*bbb1b6f9SApple OSS Distributions}
72*bbb1b6f9SApple OSS Distributions
73*bbb1b6f9SApple OSS Distributions- (BOOL)setup
74*bbb1b6f9SApple OSS Distributions{
75*bbb1b6f9SApple OSS Distributions    BOOL success = NO;
76*bbb1b6f9SApple OSS Distributions    int retval;
77*bbb1b6f9SApple OSS Distributions
78*bbb1b6f9SApple OSS Distributions    NSString* testPath = [NSString stringWithFormat:@"/AppleInternal/CoreOS/perf_index/%@.dylib", [self testName]];
79*bbb1b6f9SApple OSS Distributions    success = [self loadPITestAtPath:testPath];
80*bbb1b6f9SApple OSS Distributions    if(!success) {
81*bbb1b6f9SApple OSS Distributions        NSLog(@"Failed to load test %@", [self testName]);
82*bbb1b6f9SApple OSS Distributions        return NO;
83*bbb1b6f9SApple OSS Distributions    }
84*bbb1b6f9SApple OSS Distributions
85*bbb1b6f9SApple OSS Distributions    self->length = [self lengthForTest:[self testName]];
86*bbb1b6f9SApple OSS Distributions    self->numThreads = 1;
87*bbb1b6f9SApple OSS Distributions    self->testArgc = 0;
88*bbb1b6f9SApple OSS Distributions    self->testArgv = NULL;
89*bbb1b6f9SApple OSS Distributions
90*bbb1b6f9SApple OSS Distributions    pthread_cond_init(&self->threadsReadyCvar, NULL);
91*bbb1b6f9SApple OSS Distributions    pthread_cond_init(&self->startCvar, NULL);
92*bbb1b6f9SApple OSS Distributions    pthread_mutex_init(&self->readyThreadCountLock, NULL);
93*bbb1b6f9SApple OSS Distributions    self->readyThreadCount = 0;
94*bbb1b6f9SApple OSS Distributions
95*bbb1b6f9SApple OSS Distributions    if(self->setup_func) {
96*bbb1b6f9SApple OSS Distributions        retval = self->setup_func(1, self->length, 0, NULL);
97*bbb1b6f9SApple OSS Distributions        if(retval != 0) {
98*bbb1b6f9SApple OSS Distributions            NSLog(@"setup_func failed");
99*bbb1b6f9SApple OSS Distributions            return NO;
100*bbb1b6f9SApple OSS Distributions        }
101*bbb1b6f9SApple OSS Distributions    }
102*bbb1b6f9SApple OSS Distributions
103*bbb1b6f9SApple OSS Distributions    self->threads = (pthread_t*)malloc(sizeof(pthread_t)*self->numThreads);
104*bbb1b6f9SApple OSS Distributions
105*bbb1b6f9SApple OSS Distributions    for(int thread_index = 0; thread_index < self->numThreads; thread_index++) {
106*bbb1b6f9SApple OSS Distributions        NSNumber* my_thread_index = [NSNumber numberWithInt:thread_index];
107*bbb1b6f9SApple OSS Distributions        NSArray *arg = [NSArray arrayWithObjects:my_thread_index, self, nil];
108*bbb1b6f9SApple OSS Distributions        retval = pthread_create(&threads[thread_index], NULL, thread_setup, (__bridge void*)arg);
109*bbb1b6f9SApple OSS Distributions        if(retval != 0) {
110*bbb1b6f9SApple OSS Distributions            NSLog(@"pthread_create failed");
111*bbb1b6f9SApple OSS Distributions            free(self->threads);
112*bbb1b6f9SApple OSS Distributions            return NO;
113*bbb1b6f9SApple OSS Distributions        }
114*bbb1b6f9SApple OSS Distributions    }
115*bbb1b6f9SApple OSS Distributions
116*bbb1b6f9SApple OSS Distributions    pthread_mutex_lock(&self->readyThreadCountLock);
117*bbb1b6f9SApple OSS Distributions    if(self->readyThreadCount != self->numThreads) {
118*bbb1b6f9SApple OSS Distributions        pthread_cond_wait(&self->threadsReadyCvar, &self->readyThreadCountLock);
119*bbb1b6f9SApple OSS Distributions    }
120*bbb1b6f9SApple OSS Distributions    pthread_mutex_unlock(&self->readyThreadCountLock);
121*bbb1b6f9SApple OSS Distributions    return YES;
122*bbb1b6f9SApple OSS Distributions}
123*bbb1b6f9SApple OSS Distributions
124*bbb1b6f9SApple OSS Distributions- (BOOL)execute
125*bbb1b6f9SApple OSS Distributions{
126*bbb1b6f9SApple OSS Distributions    pthread_cond_broadcast(&self->startCvar);
127*bbb1b6f9SApple OSS Distributions    for(int thread_index = 0; thread_index < self->numThreads; thread_index++) {
128*bbb1b6f9SApple OSS Distributions        pthread_join(self->threads[thread_index], NULL);
129*bbb1b6f9SApple OSS Distributions    }
130*bbb1b6f9SApple OSS Distributions    return YES;
131*bbb1b6f9SApple OSS Distributions}
132*bbb1b6f9SApple OSS Distributions
133*bbb1b6f9SApple OSS Distributions- (void)cleanup
134*bbb1b6f9SApple OSS Distributions{
135*bbb1b6f9SApple OSS Distributions    free(self->threads);
136*bbb1b6f9SApple OSS Distributions    if(self->cleanup_func)
137*bbb1b6f9SApple OSS Distributions        self->cleanup_func(0, self->length);
138*bbb1b6f9SApple OSS Distributions}
139*bbb1b6f9SApple OSS Distributions
140*bbb1b6f9SApple OSS Distributionsvoid* thread_setup(void* arg)
141*bbb1b6f9SApple OSS Distributions{
142*bbb1b6f9SApple OSS Distributions    int my_index = (int)[(NSNumber*)[(__bridge NSArray*)arg objectAtIndex:0] integerValue];
143*bbb1b6f9SApple OSS Distributions    PITest* test = (PITest*)[(__bridge NSArray*)arg objectAtIndex:1];
144*bbb1b6f9SApple OSS Distributions
145*bbb1b6f9SApple OSS Distributions    long long work_size = test->length / test->numThreads;
146*bbb1b6f9SApple OSS Distributions    int work_remainder = test->length % test->numThreads;
147*bbb1b6f9SApple OSS Distributions
148*bbb1b6f9SApple OSS Distributions    if(work_remainder > my_index) {
149*bbb1b6f9SApple OSS Distributions        work_size++;
150*bbb1b6f9SApple OSS Distributions    }
151*bbb1b6f9SApple OSS Distributions
152*bbb1b6f9SApple OSS Distributions    pthread_mutex_lock(&test->readyThreadCountLock);
153*bbb1b6f9SApple OSS Distributions    test->readyThreadCount++;
154*bbb1b6f9SApple OSS Distributions
155*bbb1b6f9SApple OSS Distributions    if(test->readyThreadCount == test->numThreads)
156*bbb1b6f9SApple OSS Distributions        pthread_cond_signal(&test->threadsReadyCvar);
157*bbb1b6f9SApple OSS Distributions    pthread_cond_wait(&test->startCvar, &test->readyThreadCountLock);
158*bbb1b6f9SApple OSS Distributions    pthread_mutex_unlock(&test->readyThreadCountLock);
159*bbb1b6f9SApple OSS Distributions    test->execute_func(my_index, test->numThreads, work_size, test->testArgc, test->testArgv);
160*bbb1b6f9SApple OSS Distributions
161*bbb1b6f9SApple OSS Distributions    return NULL;
162*bbb1b6f9SApple OSS Distributions}
163*bbb1b6f9SApple OSS Distributions
164*bbb1b6f9SApple OSS Distributions@end
165