1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LLVM_LICENSE_HEADER@
5 */
6
7//
8//  tlctester.m
9//  tests
10//
11//  Created by Blaine Garst on 5/7/08.
12//  Copyright 2008-2009 Apple. All rights reserved.
13//
14
15// TEST_DISABLED
16// TEST_CFLAGS -framework Foundation
17
18#import <Foundation/Foundation.h>
19#import <pthread.h>
20#import <objc/objc-auto.h>
21#include <libkern/OSAtomic.h>
22#include <sys/time.h>
23#include <Block.h>
24#include "test.h"
25
26// This is not a Block test at all; rather a property list test
27
28typedef struct {
29    float a, b;
30    //int c[10];  makes problem go away
31} twofloats;
32
33@interface TestObject : NSObject {
34    twofloats tf;
35}
36@property twofloats tf;
37@end
38
39@implementation TestObject
40@synthesize tf;
41@end
42
43double timeofday() {
44    struct timeval raw;
45    gettimeofday(&raw, NULL);
46    return (double)raw.tv_sec + (double)raw.tv_usec/10e6;
47}
48
49
50
51
52void *callBlock(void *block) {
53    void (^realBlock)(void) = (void (^)(void))block;
54    while(1) {
55        realBlock();
56    }
57    return (void *)0;
58}
59
60int main(int argc, char *argv[]) {
61    int nthreads = 8;
62    int sleeptime = 1;
63    int verbose = 0;
64    const char *whoami = argv[0];
65    --argc;
66    ++argv;
67    if (argc > 0 && !strncmp("-v", argv[0], 2)) {
68        verbose = 1;
69        --argc;
70        ++argv;
71    }
72    if (argc > 0) {
73        nthreads = atoi(argv[0]);
74        --argc;
75        ++argv;
76    }
77    if (argc > 0) {
78        sleeptime = atoi(argv[0]);
79        --argc;
80        ++argv;
81    }
82    if (nthreads == 0 || sleeptime == 0) {
83        printf("Usage: %s [nthreads [sleeptime]]\n", whoami);
84        return 0;
85    }
86    if (nthreads > 100) nthreads = 100;
87    if (verbose) printf("running %d threads for %d seconds\n", nthreads, sleeptime);
88    pthread_t threads[nthreads];
89    //double start = timeofday();
90    TestObject *to = [[TestObject alloc] init];
91    for (int i = 0; i < nthreads/2; ++i) {
92        void (^setter)(void) = ^{
93                twofloats tf = { (float)i, (float)i };
94                to.tf = tf; // set to a pair of values
95        };
96        pthread_create(&threads[i], NULL, callBlock, (void *)Block_copy(setter));
97    }
98    for (int i = 0; i < nthreads/2; ++i) {
99        void (^getter)(void) = ^{
100                twofloats tf = to.tf;
101                if (tf.a != tf.b) {
102                    printf("got inconsistent values %f and %f\n", tf.a, tf.b);
103                    exit(1);
104                }
105        };
106        pthread_create(&threads[i], NULL, callBlock, (void *)Block_copy(getter));
107    }
108#if 0
109    for (int i = 0; i < nthreads; ++i)
110        pthread_join(threads[i], NULL);
111#endif
112    sleep(sleeptime);
113    return 0;
114}
115