- A Concurrent Affair - https://www.concurrentaffair.org -

Object Arrays for Argument Passing

Ok, during the last day and a bit, I changed my completely working implementation of passing method arguments. Before, there was one argument in the predicate method for each argument in the method that was annotated. That limited the applicability of the annotations. Now I pass an Object[] array that can be empty, contain one element, or however many. The coolest thing is that it automatically takes care of the subtyping problem.

Here are rewritten predicates and annotations from the last post:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
public class TCSample14 {
    public static class CheckSynchronized {
        public static boolean check(
          Object [1] thisObject, Object [1] args[], int value) {
            if (value>=args.length) return false;
            return ThreadCheckPredicates.checkMonitorOwned(args[value]);
        }
        public static boolean checkNot(
          Object [1] thisObject, Object [1] args[], int value) {
            if (value>=args.length) return false;
            return !ThreadCheckPredicates.checkMonitorOwned(args[value]);
        }
    }

    @PredicateLink(
      value=CheckSynchronized.class,
      arguments=true)
    public static interface OnlySynchronized {
        int value() default 0;
    }

    @PredicateLink(
      value=CheckSynchronized.class,
      method="checkNot",
      arguments=true)
    public static interface NotSynchronized {
        int value() default 0;
    }

    public static void main(String [2][] args) {
        TCSample14 o = new TCSample14();
        System [3].out.println("main!");
        o.succeeds();
        o.fails();
        System [3].out.println("end main!");
    }

    // these invariants all succeed
    void succeeds() {
        String [2] o1 = "foo";
        String [2] o2 = "bar";
        notUnary(o1);
        synchronized(o1) {
            unary(o1);
            binary1st(o1,o2);
            notBinary2nd(o1,o2);
        }
        synchronized(o2) {
            notBinary1st(o1,o2);
            binary2nd(o1,o2);
        }
    }

    @OnlySynchronized(0)
    void unary(Object [1] o1) {
        System [3].out.println("unary!");
    }

    @OnlySynchronized(0)
    void binary1st(Object [1] o1, Object [1] o2) {
        System [3].out.println("binary1st");
    }

    @OnlySynchronized(1)
    void binary2nd(Object [1] o1, Object [1] o2) {
        System [3].out.println("binary2nd");
    }

    // these invariants all fail
    private void fails() {
        String [2] o1 = "foo";
        String [2] o2 = "bar";
        unary(o1);
        synchronized(o1) {
            notUnary(o1);
            notBinary1st(o1,o2);
            binary2nd(o1,o2);
        }
        synchronized(o2) {
            binary1st(o1,o2);
            notBinary2nd(o1,o2);
        }
    }

    @NotSynchronized(0)
    void notUnary(Object [1] o1) {
        System [3].out.println("notUnary!");
    }

    @NotSynchronized(0)
    void notBinary1st(Object [1] o1, Object [1] o2) {
        System [3].out.println("notBinary1st");
    }

    @NotSynchronized(1)
    void notBinary2nd(Object [1] o1, Object [1] o2) {
        System [3].out.println("notBinary2nd");
    }
}

Now I think this is pretty cool. It even auto-boxes primitive types to their boxed types. Now I’m just running some more tests, and then it’s time to sleep.

PS: Whatever happened to Beer Bike today?

[4] [5]Share [6]