Index: tests/array-container/.expect/array-sbscr-types.txt
===================================================================
--- tests/array-container/.expect/array-sbscr-types.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/array-container/.expect/array-sbscr-types.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,162 @@
+Simple array
+
+100.3
+100.3
+
+100.0
+100.1
+100.2
+100.3
+100.4
+
+100.0
+100.1
+100.2
+100.3
+
+Via trait
+
+100.3
+100.3
+
+100.0
+100.1
+100.2
+100.3
+100.4
+
+100.0
+100.1
+100.2
+100.3
+
+Simple array, multidim
+
+3.3
+3.3
+3.3
+3.3
+
+0.3
+1.3
+2.3
+3.3
+4.3
+
+0.3
+1.3
+2.3
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+Via trait, multidim
+
+3.3
+3.3
+3.3
+3.3
+
+0.3
+1.3
+2.3
+3.3
+4.3
+
+0.3
+1.3
+2.3
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+Transposed, Via trait, multidim
+
+3.3
+3.3
+3.3
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+0.3
+1.3
+2.3
+3.3
+4.3
+
+0.3
+1.3
+2.3
+3.3
+
+Slice giving Simple array
+
+2.3
+2.3
+
+2.0
+2.1
+2.2
+2.3
+
+2.0
+2.1
+2.2
+2.3
+
+Same slice Via trait
+
+2.3
+2.3
+
+2.0
+2.1
+2.2
+2.3
+
+2.0
+2.1
+2.2
+2.3
+
+Strided slice Via trait
+
+3.2
+3.2
+
+0.2
+1.2
+2.2
+3.2
+4.2
+
+0.2
+1.2
+2.2
+3.2
+
Index: tests/array-container/array-basic.cfa
===================================================================
--- tests/array-container/array-basic.cfa	(revision e874605d8b0f66ad6050e4d03825b57912afe8ac)
+++ tests/array-container/array-basic.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -78,8 +78,8 @@
 }
 
-forall( A & | ar(A, float) )
+forall( [N], A & | ar(A, float, N) )
 float total1d_hi( A & a ) {
     float total = 0.0f;
-    for (i; a`len)
+    for (i; N)
         total += a[i];
     return total;
Index: tests/array-container/array-sbscr-types.cfa
===================================================================
--- tests/array-container/array-sbscr-types.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/array-container/array-sbscr-types.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,135 @@
+#include <containers/array.hfa>
+
+// Shows support for many required ways a user can index into a new array.
+//
+// A successful run of this test on 32 bit is necessary, before concluding
+// that a relevant change has good quality.  Even though the test has no 
+// differentiated 64/32-bit versions.
+//
+// Repetition, within this test, beween indexing directly into an `array(...)`
+// and indexing into a `A`, as in `forall(A...|ar(A...))`, represents indexing
+// into a (statically programmer-known) contiguous view, and a (potentially)
+// noncontiguous view, respectively.  Users obtain noncontiguous views by
+// slicing or transposing higher-dimensional arrays.  The limited uses of
+// `a[..., all, ...]` within this test create such situations.  Working via
+// the `ar` trait is the first of two ways that users depend on the array
+// implementation tunneling subscript operators through the CFA assertion
+// system.
+//
+// This test uses the `a[i,j]` form for subscriping higher-dimensional arrays,
+// which is the "new" form, compared with the C-style `a[i][j]` form.  The
+// "new" subscripting form is the second of two ways that users depend on the
+// array implementation tunneling subscript operators through the CFA
+// assertion system.
+//
+// This test covers types and syntactic forms that can convey a numeric value
+// to `a[-]` or `a[-,-,-]`.  The array-md-sbscr-cases test covers combinations
+// of `a[i][j,k]` vs `a[i,j,k]` and `a[all,3][42]` vs `a[42,3]`, though
+// generally using ptrdiff_t-typed variables to convey numeric values.
+
+
+#define show( expr ) printf( "%.1f\n", expr )
+
+#define singleDimTestBody(testName) {                      \
+                                                           \
+    printf(testName "\n\n");                               \
+                                                           \
+    assert( 3 < N );                                       \
+                                                           \
+    show( a[i1] );                                         \
+    show( a[i2] );                                         \
+    printf("\n");                                          \
+                                                           \
+    for( i_dynbounded; N ) show( a[i_dynbounded] );        \
+    printf("\n");                                          \
+                                                           \
+    for( i_stabounded; 4 ) show( a[i_stabounded] );        \
+    printf("\n");                                          \
+}
+
+forall( [N] )
+void test_common_arg_types(array(float, N) & a, ptrdiff_t i1, size_t i2)
+    singleDimTestBody("Simple array")
+
+forall( [N], A& | ar(A, float, N) )
+void test_common_arg_types__via_trait(A & a, ptrdiff_t i1, size_t i2)
+    singleDimTestBody("Via trait")
+
+void do1dimTest() {
+    array(float, 5) a;
+    a[0] = 100.0;
+    a[1] = 100.1;
+    a[2] = 100.2;
+    a[3] = 100.3;
+    a[4] = 100.4;
+
+    test_common_arg_types(a, 3, 3);
+    test_common_arg_types__via_trait(a, 3, 3);
+}
+
+#define multiDimTestBody(testName) {                         \
+                                                             \
+    printf(testName "\n\n");                                 \
+                                                             \
+    assert( 3 < M );                                         \
+    assert( 3 < N );                                         \
+                                                             \
+    show(( a[x1,x1] ));                                      \
+    show(( a[x1,x2] ));                                      \
+    show(( a[x2,x1] ));                                      \
+    show(( a[x2,x2] ));                                      \
+    printf("\n");                                            \
+                                                             \
+    for( i_dynbounded; M ) show(( a[i_dynbounded, 3] ));     \
+    printf("\n");                                            \
+                                                             \
+    for( i_stabounded; 4 ) show(( a[i_stabounded, 3] ));     \
+    printf("\n");                                            \
+                                                             \
+    for( j_dynbounded; N ) show(( a[3, j_dynbounded] ));     \
+    printf("\n");                                            \
+                                                             \
+    for( j_stabounded; 4 ) show(( a[3, j_stabounded] ));     \
+    printf("\n");                                            \
+}
+
+forall( [M], [N] )
+void test_common_arg_types__md(array(float, M, N) & a, ptrdiff_t x1, size_t x2)
+    multiDimTestBody("Simple array, multidim")
+
+
+forall( [M], [N], A_outer &, A_inner & | ar(A_outer, A_inner, M) | ar(A_inner, float, N) )
+void test_common_arg_types__md__via_trait(A_outer & a, ptrdiff_t x1, size_t x2)
+    multiDimTestBody("Via trait, multidim")
+
+
+void doMdimTest() {
+
+    array(float, 5, 4) b;
+    b[ix0,ix0] = 0.0; b[ix0,1] = 0.1; b[ix0,2] = 0.2; b[ix0,3] = 0.3;
+    b[  1,ix0] = 1.0; b[  1,1] = 1.1; b[  1,2] = 1.2; b[  1,3] = 1.3;
+    b[  2,ix0] = 2.0; b[  2,1] = 2.1; b[  2,2] = 2.2; b[  2,3] = 2.3;
+    b[  3,ix0] = 3.0; b[  3,1] = 3.1; b[  3,2] = 3.2; b[  3,3] = 3.3;
+    b[  4,ix0] = 4.0; b[  4,1] = 4.1; b[  4,2] = 4.2; b[  4,3] = 4.3;
+
+    test_common_arg_types__md(b, 3, 3);
+    test_common_arg_types__md__via_trait(b, 3, 3);
+    printf("Transposed, ");
+    test_common_arg_types__md__via_trait(b[all], 3, 3);
+
+    printf("Slice giving ");
+    test_common_arg_types(b[2], 3, 3);
+
+    printf("Same slice ");
+    test_common_arg_types__via_trait(b[2], 3, 3);
+
+    printf("Strided slice ");
+    test_common_arg_types__via_trait(b[all,2], 3, 3);
+}
+
+int main() {
+
+    // can't be inlined in same func due to Trac #175.
+    do1dimTest();
+    doMdimTest();
+}
Index: tests/collections/atomic_mpsc.cfa
===================================================================
--- tests/collections/atomic_mpsc.cfa	(revision e874605d8b0f66ad6050e4d03825b57912afe8ac)
+++ tests/collections/atomic_mpsc.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -1,4 +1,4 @@
 #include <fstream.hfa>
-#include <queueLockFree.hfa>
+#include <containers/lockfree.hfa>
 #include <thread.hfa>
 
Index: tests/concurrent/.expect/migrate.txt
===================================================================
--- tests/concurrent/.expect/migrate.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/.expect/migrate.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,1 @@
+done
Index: tests/concurrent/migrate.cfa
===================================================================
--- tests/concurrent/migrate.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/migrate.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,85 @@
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <thread.hfa>
+
+#include <stdatomic.h>
+#include <assert.h>
+
+struct cluster_wrapper {
+	cluster self;
+	const uint64_t canary;
+	struct {
+		volatile uint64_t want;
+		volatile uint64_t have;
+	} checksum;
+};
+
+void ?{}( cluster_wrapper & this ) {
+	(this.self){};
+	(*(uint64_t *)&this.canary) = 0xDEAD2BADDEAD2BAD;
+	this.checksum.want = 0;
+	this.checksum.have = 0;
+}
+
+void ^?{}( cluster_wrapper & this ) {
+	assert(this.canary == 0xDEAD2BADDEAD2BAD);
+}
+
+static cluster_wrapper * the_clusters;
+static unsigned cluster_cnt;
+
+thread MyThread {
+
+};
+
+void ?{}( MyThread & this ) {}
+
+void checkcl( MyThread & this, cluster * cl) {
+	if(((thread&)this).curr_cluster != cl) {
+		abort | "Thread has unexpected cluster";
+	}
+}
+
+void main( MyThread & this ) {
+	waitfor( migrate : this ) {
+		assert( ((thread&)this).curr_cluster == active_cluster() );
+		assert( ((thread&)this).curr_cluster == active_processor()->cltr );
+	}
+
+	struct cluster_wrapper * curr = (struct cluster_wrapper *)&the_clusters[0];
+
+	for(100) {
+		unsigned idx = prng( this, cluster_cnt );
+
+		struct cluster_wrapper * next = &the_clusters[ idx ];
+		assert(next->canary == 0xDEAD2BADDEAD2BAD);
+
+		// next->
+
+		migrate( this, next->self );
+
+		assert( active_cluster() == &next->self );
+		assert( ((thread&)this).curr_cluster == active_cluster() );
+		assert( ((thread&)this).curr_cluster == active_processor()->cltr );
+	}
+}
+
+int main() {
+	cluster_cnt = 3;
+	cluster_wrapper cl[cluster_cnt];
+	the_clusters = cl;
+
+	{
+		set_concurrency( cl[0].self, 2 );
+		set_concurrency( cl[1].self, 2 );
+		set_concurrency( cl[2].self, 1 );
+
+		MyThread threads[17];
+		for(i;17) {
+			migrate( threads[i], cl[0].self );
+		}
+
+	}
+	// non-empty .expect file
+	printf( "done\n" );
+}
Index: tests/concurrent/pthread/.expect/bounded_buffer.txt
===================================================================
--- tests/concurrent/pthread/.expect/bounded_buffer.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/.expect/bounded_buffer.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,2 @@
+producer total value is 23426
+consumer total value is 23426
Index: tests/concurrent/pthread/.expect/pthread_attr_test.txt
===================================================================
--- tests/concurrent/pthread/.expect/pthread_attr_test.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/.expect/pthread_attr_test.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,1 @@
+stack size is 123456789
Index: tests/concurrent/pthread/.expect/pthread_cond_test.txt
===================================================================
--- tests/concurrent/pthread/.expect/pthread_cond_test.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/.expect/pthread_cond_test.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,1001 @@
+S1 done 0
+S1 done 1
+S1 done 2
+S1 done 3
+S1 done 4
+S1 done 5
+S1 done 6
+S1 done 7
+S1 done 8
+S1 done 9
+S1 done 10
+S1 done 11
+S1 done 12
+S1 done 13
+S1 done 14
+S1 done 15
+S1 done 16
+S1 done 17
+S1 done 18
+S1 done 19
+S1 done 20
+S1 done 21
+S1 done 22
+S1 done 23
+S1 done 24
+S1 done 25
+S1 done 26
+S1 done 27
+S1 done 28
+S1 done 29
+S1 done 30
+S1 done 31
+S1 done 32
+S1 done 33
+S1 done 34
+S1 done 35
+S1 done 36
+S1 done 37
+S1 done 38
+S1 done 39
+S1 done 40
+S1 done 41
+S1 done 42
+S1 done 43
+S1 done 44
+S1 done 45
+S1 done 46
+S1 done 47
+S1 done 48
+S1 done 49
+S1 done 50
+S1 done 51
+S1 done 52
+S1 done 53
+S1 done 54
+S1 done 55
+S1 done 56
+S1 done 57
+S1 done 58
+S1 done 59
+S1 done 60
+S1 done 61
+S1 done 62
+S1 done 63
+S1 done 64
+S1 done 65
+S1 done 66
+S1 done 67
+S1 done 68
+S1 done 69
+S1 done 70
+S1 done 71
+S1 done 72
+S1 done 73
+S1 done 74
+S1 done 75
+S1 done 76
+S1 done 77
+S1 done 78
+S1 done 79
+S1 done 80
+S1 done 81
+S1 done 82
+S1 done 83
+S1 done 84
+S1 done 85
+S1 done 86
+S1 done 87
+S1 done 88
+S1 done 89
+S1 done 90
+S1 done 91
+S1 done 92
+S1 done 93
+S1 done 94
+S1 done 95
+S1 done 96
+S1 done 97
+S1 done 98
+S1 done 99
+S1 done 100
+S1 done 101
+S1 done 102
+S1 done 103
+S1 done 104
+S1 done 105
+S1 done 106
+S1 done 107
+S1 done 108
+S1 done 109
+S1 done 110
+S1 done 111
+S1 done 112
+S1 done 113
+S1 done 114
+S1 done 115
+S1 done 116
+S1 done 117
+S1 done 118
+S1 done 119
+S1 done 120
+S1 done 121
+S1 done 122
+S1 done 123
+S1 done 124
+S1 done 125
+S1 done 126
+S1 done 127
+S1 done 128
+S1 done 129
+S1 done 130
+S1 done 131
+S1 done 132
+S1 done 133
+S1 done 134
+S1 done 135
+S1 done 136
+S1 done 137
+S1 done 138
+S1 done 139
+S1 done 140
+S1 done 141
+S1 done 142
+S1 done 143
+S1 done 144
+S1 done 145
+S1 done 146
+S1 done 147
+S1 done 148
+S1 done 149
+S1 done 150
+S1 done 151
+S1 done 152
+S1 done 153
+S1 done 154
+S1 done 155
+S1 done 156
+S1 done 157
+S1 done 158
+S1 done 159
+S1 done 160
+S1 done 161
+S1 done 162
+S1 done 163
+S1 done 164
+S1 done 165
+S1 done 166
+S1 done 167
+S1 done 168
+S1 done 169
+S1 done 170
+S1 done 171
+S1 done 172
+S1 done 173
+S1 done 174
+S1 done 175
+S1 done 176
+S1 done 177
+S1 done 178
+S1 done 179
+S1 done 180
+S1 done 181
+S1 done 182
+S1 done 183
+S1 done 184
+S1 done 185
+S1 done 186
+S1 done 187
+S1 done 188
+S1 done 189
+S1 done 190
+S1 done 191
+S1 done 192
+S1 done 193
+S1 done 194
+S1 done 195
+S1 done 196
+S1 done 197
+S1 done 198
+S1 done 199
+S1 done 200
+S1 done 201
+S1 done 202
+S1 done 203
+S1 done 204
+S1 done 205
+S1 done 206
+S1 done 207
+S1 done 208
+S1 done 209
+S1 done 210
+S1 done 211
+S1 done 212
+S1 done 213
+S1 done 214
+S1 done 215
+S1 done 216
+S1 done 217
+S1 done 218
+S1 done 219
+S1 done 220
+S1 done 221
+S1 done 222
+S1 done 223
+S1 done 224
+S1 done 225
+S1 done 226
+S1 done 227
+S1 done 228
+S1 done 229
+S1 done 230
+S1 done 231
+S1 done 232
+S1 done 233
+S1 done 234
+S1 done 235
+S1 done 236
+S1 done 237
+S1 done 238
+S1 done 239
+S1 done 240
+S1 done 241
+S1 done 242
+S1 done 243
+S1 done 244
+S1 done 245
+S1 done 246
+S1 done 247
+S1 done 248
+S1 done 249
+S1 done 250
+S1 done 251
+S1 done 252
+S1 done 253
+S1 done 254
+S1 done 255
+S1 done 256
+S1 done 257
+S1 done 258
+S1 done 259
+S1 done 260
+S1 done 261
+S1 done 262
+S1 done 263
+S1 done 264
+S1 done 265
+S1 done 266
+S1 done 267
+S1 done 268
+S1 done 269
+S1 done 270
+S1 done 271
+S1 done 272
+S1 done 273
+S1 done 274
+S1 done 275
+S1 done 276
+S1 done 277
+S1 done 278
+S1 done 279
+S1 done 280
+S1 done 281
+S1 done 282
+S1 done 283
+S1 done 284
+S1 done 285
+S1 done 286
+S1 done 287
+S1 done 288
+S1 done 289
+S1 done 290
+S1 done 291
+S1 done 292
+S1 done 293
+S1 done 294
+S1 done 295
+S1 done 296
+S1 done 297
+S1 done 298
+S1 done 299
+S1 done 300
+S1 done 301
+S1 done 302
+S1 done 303
+S1 done 304
+S1 done 305
+S1 done 306
+S1 done 307
+S1 done 308
+S1 done 309
+S1 done 310
+S1 done 311
+S1 done 312
+S1 done 313
+S1 done 314
+S1 done 315
+S1 done 316
+S1 done 317
+S1 done 318
+S1 done 319
+S1 done 320
+S1 done 321
+S1 done 322
+S1 done 323
+S1 done 324
+S1 done 325
+S1 done 326
+S1 done 327
+S1 done 328
+S1 done 329
+S1 done 330
+S1 done 331
+S1 done 332
+S1 done 333
+S1 done 334
+S1 done 335
+S1 done 336
+S1 done 337
+S1 done 338
+S1 done 339
+S1 done 340
+S1 done 341
+S1 done 342
+S1 done 343
+S1 done 344
+S1 done 345
+S1 done 346
+S1 done 347
+S1 done 348
+S1 done 349
+S1 done 350
+S1 done 351
+S1 done 352
+S1 done 353
+S1 done 354
+S1 done 355
+S1 done 356
+S1 done 357
+S1 done 358
+S1 done 359
+S1 done 360
+S1 done 361
+S1 done 362
+S1 done 363
+S1 done 364
+S1 done 365
+S1 done 366
+S1 done 367
+S1 done 368
+S1 done 369
+S1 done 370
+S1 done 371
+S1 done 372
+S1 done 373
+S1 done 374
+S1 done 375
+S1 done 376
+S1 done 377
+S1 done 378
+S1 done 379
+S1 done 380
+S1 done 381
+S1 done 382
+S1 done 383
+S1 done 384
+S1 done 385
+S1 done 386
+S1 done 387
+S1 done 388
+S1 done 389
+S1 done 390
+S1 done 391
+S1 done 392
+S1 done 393
+S1 done 394
+S1 done 395
+S1 done 396
+S1 done 397
+S1 done 398
+S1 done 399
+S1 done 400
+S1 done 401
+S1 done 402
+S1 done 403
+S1 done 404
+S1 done 405
+S1 done 406
+S1 done 407
+S1 done 408
+S1 done 409
+S1 done 410
+S1 done 411
+S1 done 412
+S1 done 413
+S1 done 414
+S1 done 415
+S1 done 416
+S1 done 417
+S1 done 418
+S1 done 419
+S1 done 420
+S1 done 421
+S1 done 422
+S1 done 423
+S1 done 424
+S1 done 425
+S1 done 426
+S1 done 427
+S1 done 428
+S1 done 429
+S1 done 430
+S1 done 431
+S1 done 432
+S1 done 433
+S1 done 434
+S1 done 435
+S1 done 436
+S1 done 437
+S1 done 438
+S1 done 439
+S1 done 440
+S1 done 441
+S1 done 442
+S1 done 443
+S1 done 444
+S1 done 445
+S1 done 446
+S1 done 447
+S1 done 448
+S1 done 449
+S1 done 450
+S1 done 451
+S1 done 452
+S1 done 453
+S1 done 454
+S1 done 455
+S1 done 456
+S1 done 457
+S1 done 458
+S1 done 459
+S1 done 460
+S1 done 461
+S1 done 462
+S1 done 463
+S1 done 464
+S1 done 465
+S1 done 466
+S1 done 467
+S1 done 468
+S1 done 469
+S1 done 470
+S1 done 471
+S1 done 472
+S1 done 473
+S1 done 474
+S1 done 475
+S1 done 476
+S1 done 477
+S1 done 478
+S1 done 479
+S1 done 480
+S1 done 481
+S1 done 482
+S1 done 483
+S1 done 484
+S1 done 485
+S1 done 486
+S1 done 487
+S1 done 488
+S1 done 489
+S1 done 490
+S1 done 491
+S1 done 492
+S1 done 493
+S1 done 494
+S1 done 495
+S1 done 496
+S1 done 497
+S1 done 498
+S1 done 499
+S1 done 500
+S1 done 501
+S1 done 502
+S1 done 503
+S1 done 504
+S1 done 505
+S1 done 506
+S1 done 507
+S1 done 508
+S1 done 509
+S1 done 510
+S1 done 511
+S1 done 512
+S1 done 513
+S1 done 514
+S1 done 515
+S1 done 516
+S1 done 517
+S1 done 518
+S1 done 519
+S1 done 520
+S1 done 521
+S1 done 522
+S1 done 523
+S1 done 524
+S1 done 525
+S1 done 526
+S1 done 527
+S1 done 528
+S1 done 529
+S1 done 530
+S1 done 531
+S1 done 532
+S1 done 533
+S1 done 534
+S1 done 535
+S1 done 536
+S1 done 537
+S1 done 538
+S1 done 539
+S1 done 540
+S1 done 541
+S1 done 542
+S1 done 543
+S1 done 544
+S1 done 545
+S1 done 546
+S1 done 547
+S1 done 548
+S1 done 549
+S1 done 550
+S1 done 551
+S1 done 552
+S1 done 553
+S1 done 554
+S1 done 555
+S1 done 556
+S1 done 557
+S1 done 558
+S1 done 559
+S1 done 560
+S1 done 561
+S1 done 562
+S1 done 563
+S1 done 564
+S1 done 565
+S1 done 566
+S1 done 567
+S1 done 568
+S1 done 569
+S1 done 570
+S1 done 571
+S1 done 572
+S1 done 573
+S1 done 574
+S1 done 575
+S1 done 576
+S1 done 577
+S1 done 578
+S1 done 579
+S1 done 580
+S1 done 581
+S1 done 582
+S1 done 583
+S1 done 584
+S1 done 585
+S1 done 586
+S1 done 587
+S1 done 588
+S1 done 589
+S1 done 590
+S1 done 591
+S1 done 592
+S1 done 593
+S1 done 594
+S1 done 595
+S1 done 596
+S1 done 597
+S1 done 598
+S1 done 599
+S1 done 600
+S1 done 601
+S1 done 602
+S1 done 603
+S1 done 604
+S1 done 605
+S1 done 606
+S1 done 607
+S1 done 608
+S1 done 609
+S1 done 610
+S1 done 611
+S1 done 612
+S1 done 613
+S1 done 614
+S1 done 615
+S1 done 616
+S1 done 617
+S1 done 618
+S1 done 619
+S1 done 620
+S1 done 621
+S1 done 622
+S1 done 623
+S1 done 624
+S1 done 625
+S1 done 626
+S1 done 627
+S1 done 628
+S1 done 629
+S1 done 630
+S1 done 631
+S1 done 632
+S1 done 633
+S1 done 634
+S1 done 635
+S1 done 636
+S1 done 637
+S1 done 638
+S1 done 639
+S1 done 640
+S1 done 641
+S1 done 642
+S1 done 643
+S1 done 644
+S1 done 645
+S1 done 646
+S1 done 647
+S1 done 648
+S1 done 649
+S1 done 650
+S1 done 651
+S1 done 652
+S1 done 653
+S1 done 654
+S1 done 655
+S1 done 656
+S1 done 657
+S1 done 658
+S1 done 659
+S1 done 660
+S1 done 661
+S1 done 662
+S1 done 663
+S1 done 664
+S1 done 665
+S1 done 666
+S1 done 667
+S1 done 668
+S1 done 669
+S1 done 670
+S1 done 671
+S1 done 672
+S1 done 673
+S1 done 674
+S1 done 675
+S1 done 676
+S1 done 677
+S1 done 678
+S1 done 679
+S1 done 680
+S1 done 681
+S1 done 682
+S1 done 683
+S1 done 684
+S1 done 685
+S1 done 686
+S1 done 687
+S1 done 688
+S1 done 689
+S1 done 690
+S1 done 691
+S1 done 692
+S1 done 693
+S1 done 694
+S1 done 695
+S1 done 696
+S1 done 697
+S1 done 698
+S1 done 699
+S1 done 700
+S1 done 701
+S1 done 702
+S1 done 703
+S1 done 704
+S1 done 705
+S1 done 706
+S1 done 707
+S1 done 708
+S1 done 709
+S1 done 710
+S1 done 711
+S1 done 712
+S1 done 713
+S1 done 714
+S1 done 715
+S1 done 716
+S1 done 717
+S1 done 718
+S1 done 719
+S1 done 720
+S1 done 721
+S1 done 722
+S1 done 723
+S1 done 724
+S1 done 725
+S1 done 726
+S1 done 727
+S1 done 728
+S1 done 729
+S1 done 730
+S1 done 731
+S1 done 732
+S1 done 733
+S1 done 734
+S1 done 735
+S1 done 736
+S1 done 737
+S1 done 738
+S1 done 739
+S1 done 740
+S1 done 741
+S1 done 742
+S1 done 743
+S1 done 744
+S1 done 745
+S1 done 746
+S1 done 747
+S1 done 748
+S1 done 749
+S1 done 750
+S1 done 751
+S1 done 752
+S1 done 753
+S1 done 754
+S1 done 755
+S1 done 756
+S1 done 757
+S1 done 758
+S1 done 759
+S1 done 760
+S1 done 761
+S1 done 762
+S1 done 763
+S1 done 764
+S1 done 765
+S1 done 766
+S1 done 767
+S1 done 768
+S1 done 769
+S1 done 770
+S1 done 771
+S1 done 772
+S1 done 773
+S1 done 774
+S1 done 775
+S1 done 776
+S1 done 777
+S1 done 778
+S1 done 779
+S1 done 780
+S1 done 781
+S1 done 782
+S1 done 783
+S1 done 784
+S1 done 785
+S1 done 786
+S1 done 787
+S1 done 788
+S1 done 789
+S1 done 790
+S1 done 791
+S1 done 792
+S1 done 793
+S1 done 794
+S1 done 795
+S1 done 796
+S1 done 797
+S1 done 798
+S1 done 799
+S1 done 800
+S1 done 801
+S1 done 802
+S1 done 803
+S1 done 804
+S1 done 805
+S1 done 806
+S1 done 807
+S1 done 808
+S1 done 809
+S1 done 810
+S1 done 811
+S1 done 812
+S1 done 813
+S1 done 814
+S1 done 815
+S1 done 816
+S1 done 817
+S1 done 818
+S1 done 819
+S1 done 820
+S1 done 821
+S1 done 822
+S1 done 823
+S1 done 824
+S1 done 825
+S1 done 826
+S1 done 827
+S1 done 828
+S1 done 829
+S1 done 830
+S1 done 831
+S1 done 832
+S1 done 833
+S1 done 834
+S1 done 835
+S1 done 836
+S1 done 837
+S1 done 838
+S1 done 839
+S1 done 840
+S1 done 841
+S1 done 842
+S1 done 843
+S1 done 844
+S1 done 845
+S1 done 846
+S1 done 847
+S1 done 848
+S1 done 849
+S1 done 850
+S1 done 851
+S1 done 852
+S1 done 853
+S1 done 854
+S1 done 855
+S1 done 856
+S1 done 857
+S1 done 858
+S1 done 859
+S1 done 860
+S1 done 861
+S1 done 862
+S1 done 863
+S1 done 864
+S1 done 865
+S1 done 866
+S1 done 867
+S1 done 868
+S1 done 869
+S1 done 870
+S1 done 871
+S1 done 872
+S1 done 873
+S1 done 874
+S1 done 875
+S1 done 876
+S1 done 877
+S1 done 878
+S1 done 879
+S1 done 880
+S1 done 881
+S1 done 882
+S1 done 883
+S1 done 884
+S1 done 885
+S1 done 886
+S1 done 887
+S1 done 888
+S1 done 889
+S1 done 890
+S1 done 891
+S1 done 892
+S1 done 893
+S1 done 894
+S1 done 895
+S1 done 896
+S1 done 897
+S1 done 898
+S1 done 899
+S1 done 900
+S1 done 901
+S1 done 902
+S1 done 903
+S1 done 904
+S1 done 905
+S1 done 906
+S1 done 907
+S1 done 908
+S1 done 909
+S1 done 910
+S1 done 911
+S1 done 912
+S1 done 913
+S1 done 914
+S1 done 915
+S1 done 916
+S1 done 917
+S1 done 918
+S1 done 919
+S1 done 920
+S1 done 921
+S1 done 922
+S1 done 923
+S1 done 924
+S1 done 925
+S1 done 926
+S1 done 927
+S1 done 928
+S1 done 929
+S1 done 930
+S1 done 931
+S1 done 932
+S1 done 933
+S1 done 934
+S1 done 935
+S1 done 936
+S1 done 937
+S1 done 938
+S1 done 939
+S1 done 940
+S1 done 941
+S1 done 942
+S1 done 943
+S1 done 944
+S1 done 945
+S1 done 946
+S1 done 947
+S1 done 948
+S1 done 949
+S1 done 950
+S1 done 951
+S1 done 952
+S1 done 953
+S1 done 954
+S1 done 955
+S1 done 956
+S1 done 957
+S1 done 958
+S1 done 959
+S1 done 960
+S1 done 961
+S1 done 962
+S1 done 963
+S1 done 964
+S1 done 965
+S1 done 966
+S1 done 967
+S1 done 968
+S1 done 969
+S1 done 970
+S1 done 971
+S1 done 972
+S1 done 973
+S1 done 974
+S1 done 975
+S1 done 976
+S1 done 977
+S1 done 978
+S1 done 979
+S1 done 980
+S1 done 981
+S1 done 982
+S1 done 983
+S1 done 984
+S1 done 985
+S1 done 986
+S1 done 987
+S1 done 988
+S1 done 989
+S1 done 990
+S1 done 991
+S1 done 992
+S1 done 993
+S1 done 994
+S1 done 995
+S1 done 996
+S1 done 997
+S1 done 998
+S1 done 999
+S2 statement done!
Index: tests/concurrent/pthread/.expect/pthread_demo_create_join.txt
===================================================================
--- tests/concurrent/pthread/.expect/pthread_demo_create_join.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/.expect/pthread_demo_create_join.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,1 @@
+final res is 190
Index: tests/concurrent/pthread/.expect/pthread_demo_lock.txt
===================================================================
--- tests/concurrent/pthread/.expect/pthread_demo_lock.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/.expect/pthread_demo_lock.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,6 @@
+lock res is 2000000000
+in trylocktest1 res1 is 0
+in trylocktest1 res2 is 0
+in trylocktest2 res1 is 16
+in trylocktest2 res2 is 16
+cnt_trylock is 200000000
Index: tests/concurrent/pthread/.expect/pthread_key_test.txt
===================================================================
--- tests/concurrent/pthread/.expect/pthread_key_test.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/.expect/pthread_key_test.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,6 @@
+Destructor function invoked
+Destructor function invoked
+Destructor function invoked
+Destructor function invoked
+Destructor function invoked
+total value is 207, total value by pthread_getspecific is 207
Index: tests/concurrent/pthread/.expect/pthread_once_test.txt
===================================================================
--- tests/concurrent/pthread/.expect/pthread_once_test.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/.expect/pthread_once_test.txt	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,1 @@
+in once_fn
Index: tests/concurrent/pthread/bounded_buffer.cfa
===================================================================
--- tests/concurrent/pthread/bounded_buffer.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/bounded_buffer.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,156 @@
+#include <stdlib.h>										// prototype: rand
+#include <fstream.hfa>
+#include <thread.hfa>
+#include <pthread.h>
+#include <errno.h>
+// tested pthread mutex related routines, pthread cond related routines
+// tested pthread_create/join
+
+enum { BufferSize = 50 };
+
+volatile int producer_val_total;
+volatile int consumer_val_total;
+
+pthread_mutex_t producer_cnt_lock, consumer_cnt_lock;
+
+
+forall( T ){
+    struct Buffer
+    {
+        int front, back, count;
+		T elements[BufferSize];
+        pthread_mutex_t _mutex;
+	    pthread_cond_t Full, Empty;							// waiting consumers & producers
+    };
+
+    void ?{}( Buffer(T) & buffer ) with( buffer ) {
+         [front, back, count] = 0; 
+         pthread_mutex_init(&_mutex, NULL);
+         pthread_cond_init(&Full, NULL);
+         pthread_cond_init(&Empty, NULL);
+    }
+
+    void ^?{}( Buffer(T) & buffer ) with( buffer ){
+        pthread_mutex_destroy(&_mutex);
+        pthread_cond_destroy(&Full);
+        pthread_cond_destroy(&Empty);
+    }
+
+    int query( Buffer(T) & buffer ) { return buffer.count; } // read-only, no mutual exclusion
+    
+    void insert( Buffer(T) & buffer, T elem ) with(buffer) {
+		pthread_mutex_lock(&_mutex);
+		while ( count == 20 ) pthread_cond_wait( &Empty, &_mutex ); // block producer
+		elements[back] = elem;
+		back = ( back + 1 ) % 20;
+		count += 1;
+		pthread_cond_signal( &Full );					// unblock consumer
+        pthread_mutex_unlock(&_mutex);
+	}
+
+    T remove(Buffer(T) & buffer) with(buffer) {
+		pthread_mutex_lock(&_mutex);
+		while ( count == 0 ) pthread_cond_wait( &Full, &_mutex ); // block consumer
+		T elem = elements[front];
+		front = ( front + 1 ) % 20;
+		count -= 1;
+		pthread_cond_signal( &Empty );					// unblock producer
+        pthread_mutex_unlock(&_mutex);
+		return elem;
+	}
+
+}
+
+void *producer( void *arg ) {
+	Buffer(int) &buf = *(Buffer(int)*)arg;
+	const int NoOfItems = rand() % 40;
+	int item;
+	for ( int i = 1; i <= NoOfItems; i += 1 ) {			// produce a bunch of items
+		item = rand() % 100 + 1;						// produce a random number
+		//sout | "Producer:" | pthread_self() | " value:" | item;
+		insert( buf,item );								// insert element into queue
+        pthread_mutex_lock(&producer_cnt_lock);
+        producer_val_total += item;
+        pthread_mutex_unlock(&producer_cnt_lock);
+	} // for
+	//sout | "Producer:" | pthread_self() | " is finished";
+	return NULL;
+} // producer
+
+void *consumer( void *arg ) {
+	Buffer(int) &buf = *(Buffer(int) *)arg;
+	int item;
+	for ( ;; ) {										// consume until a negative element appears
+		item = remove(buf);							// remove from front of queue
+		//sout | "Consumer:" | pthread_self() | " value:" | item;
+	  if ( item == -1 ) break;
+        pthread_mutex_lock(&consumer_cnt_lock);
+        consumer_val_total += item;
+        pthread_mutex_unlock(&consumer_cnt_lock);
+	} // for
+	//sout | "Consumer:" | pthread_self() | " is finished";
+	return NULL;
+} // consumer
+
+int main() {
+	const int NoOfCons = 20, NoOfProds = 30;
+	Buffer(int) buf;								// create a buffer monitor
+	pthread_t cons[NoOfCons];							// pointer to an array of consumers
+	pthread_t prods[NoOfProds];							// pointer to an array of producers
+    pthread_mutex_init(&producer_cnt_lock, NULL);
+    pthread_mutex_init(&consumer_cnt_lock, NULL);
+	// parallelism
+    srandom( 1003 );
+
+	processor p[5];
+    {
+        // create/join and mutex/condition test
+        //sout | "create/join and mutex/condition test";
+        for ( int i = 0; i < NoOfCons; i += 1 ) {			// create consumers
+            if ( pthread_create( &cons[i], NULL, consumer, (void*)&buf ) != 0 ) {
+                sout | "create thread failure, errno:" | errno;
+                exit( EXIT_FAILURE );
+            } // if
+        } // for
+        for ( int i = 0; i < NoOfProds; i += 1 ) {			// 	create producers
+            if ( pthread_create( &prods[i], NULL, producer, (void*)&buf ) != 0 ) {
+                sout | "create thread failure";
+                exit( EXIT_FAILURE );
+            } // if
+        } // for
+
+        void *result;
+        for ( int i = 0; i < NoOfProds; i += 1 ) {			// wait for producers to end
+            if ( pthread_join( prods[i], &result ) != 0 ) {
+                sout | " producers join thread failure";
+                exit( EXIT_FAILURE );
+            } // if
+            if ( (uint64_t)result != 0 ) {
+                sout | "producers" | prods[i] |" bad return value " | result;
+                exit( EXIT_FAILURE );
+            } // if
+            //sout | "join prods[" | i | "]:" | prods[i] | " result:" | result;
+        } // for
+
+        for ( int i = 0; i < NoOfCons; i += 1 ) {			// terminate each consumer
+            insert(buf, -1 );
+        } // for
+
+        for ( int i = 0; i < NoOfCons; i += 1 ) {			// wait for consumer to end
+            if ( pthread_join( cons[i], &result ) != 0 ) {
+                sout| "consumers join thread failure" ;
+                exit( EXIT_FAILURE );
+            } // if
+            if ( (uint64_t)result != 0 ) {
+                sout| "consumers bad return value" | result;
+                exit( EXIT_FAILURE );
+            } // if
+        } // for
+        sout | "producer total value is " | producer_val_total;
+        sout | "consumer total value is " | consumer_val_total;
+    }
+
+	
+
+	
+}
Index: tests/concurrent/pthread/pthread_attr_test.cfa
===================================================================
--- tests/concurrent/pthread/pthread_attr_test.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/pthread_attr_test.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,29 @@
+/* test attr init; set stack; get stack */
+
+#include <fstream.hfa>
+#include <thread.hfa>
+
+void* foo(void* _attr){
+    size_t size;
+    pthread_attr_t* attr = (pthread_attr_t*)_attr;
+    int status = pthread_attr_getstacksize(attr, &size);
+    if (status != 0){
+        sout | "error return code";
+        exit(1);
+    }
+    sout | "stack size is " | size;
+    return NULL;
+}
+
+int main(int argc, char const *argv[])
+{
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setstacksize(&attr, 123456789);
+    pthread_t thr;
+    void* res;
+    pthread_create(&thr, &attr, foo, (void*)&attr);
+    pthread_join(thr, &res);
+    pthread_attr_destroy(&attr);
+    return 0;
+}
Index: tests/concurrent/pthread/pthread_cond_test.cfa
===================================================================
--- tests/concurrent/pthread/pthread_cond_test.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/pthread_cond_test.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,46 @@
+/* small test of pthread cond */
+
+#include <fstream.hfa>
+#include <thread.hfa>
+#include <pthread.h>
+
+int done_flag = 0;
+pthread_mutex_t _mutex;
+pthread_cond_t cond;
+
+extern "C"{
+    void* S1(void* arg){
+        pthread_mutex_lock(&_mutex);
+        for (int i = 0; i < 1000; i++) sout | "S1 done " | i;
+        done_flag = 1;
+        pthread_mutex_unlock(&_mutex);
+        pthread_cond_signal(&cond);
+        return NULL;
+    }
+
+    void* S2(void* arg){
+        pthread_mutex_lock(&_mutex);
+        if (!done_flag) pthread_cond_wait(&cond, &_mutex);
+        sout | "S2 statement done!";
+        pthread_mutex_unlock(&_mutex);
+        return NULL;
+    }
+}
+
+
+
+int main(int argc, char const *argv[])
+{
+    /* code */
+    pthread_mutex_init(&_mutex, NULL);
+    pthread_cond_init(&cond, NULL);
+    pthread_t s1,s2;
+    pthread_create(&s1, NULL, S1, NULL);
+    pthread_create(&s2, NULL, S2, NULL);
+    void* res = NULL;
+    pthread_join(s1, &res);
+    pthread_join(s2, &res);
+    pthread_mutex_destroy(&_mutex);
+    pthread_cond_destroy(&cond);
+    return 0;
+}
Index: tests/concurrent/pthread/pthread_demo_create_join.cfa
===================================================================
--- tests/concurrent/pthread/pthread_demo_create_join.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/pthread_demo_create_join.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,41 @@
+#include <fstream.hfa>
+#include <thread.hfa>
+/* test pthread create/join/exit */
+
+int arr[20];
+
+void* fetch(void* idx){
+    int res = arr[(uint64_t)idx];
+    pthread_exit((void*)res);
+    sout | "it should not be here";
+    exit(1);
+    //return (void*)res;
+}
+
+void arr_init(){
+    for (int i = 0; i < 20; i++){
+        arr[i] = i;
+    }
+}
+
+int main(int argc, char const *argv[])
+{
+    pthread_t threads[20];
+    arr_init();
+    int status;
+    for (int i = 0; i < 20; i++){
+        status = pthread_create(&threads[i], NULL, fetch, (void*)i);
+        if (status != 0) exit(1);
+    }
+    int res = 0;
+    for (int i = 0; i < 20; i++){
+        void* _res = NULL;
+        status = pthread_join(threads[i], &_res);
+        if (status != 0) exit(2);
+        if (((uint64_t)_res) != i) exit(3);
+        res += (uint64_t)_res;
+    }
+    sout | "final res is" | res;
+
+    return 0;
+}
Index: tests/concurrent/pthread/pthread_demo_lock.cfa
===================================================================
--- tests/concurrent/pthread/pthread_demo_lock.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/pthread_demo_lock.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,124 @@
+#include <fstream.hfa>
+#include <thread.hfa>
+/* 
+    test pthread_mutex to provide mutual exclusion
+    test pthread_mutex_trylock not block when lock is acquired by others; test pthread_mutex_trylock can acquire the lock
+*/
+volatile int cnt_nolock = 0;
+volatile int cnt_lock = 0;
+volatile int cnt_trylock = 0;
+extern "C"{
+    static pthread_mutex_t _mutex;
+}
+
+/* mutex pthread routine  */
+// unlocked increnment
+void* inc_unlock(void* cnt){
+    for (int i = 0; i < (uint64_t)cnt; i++){
+        cnt_nolock++;
+    }   // for
+    return NULL;
+}   
+// locked increment
+void* inc_lock(void* cnt){
+    pthread_mutex_lock(&_mutex);
+    for (int i = 0; i < (uint64_t)cnt; i++){
+        cnt_lock++;
+    }   // for
+    pthread_mutex_unlock(&_mutex);
+    return NULL;
+}
+
+/* test lock vs unlock */
+void test_unlock(){
+    pthread_t threads[20];
+    for (int i = 0; i < 20; i++){
+        pthread_create(&threads[i], NULL, inc_unlock, (void*)100000000);
+    }
+    for (int i = 0; i < 20; i++){
+        void * res = NULL;
+        pthread_join(threads[i], &res);
+    }
+    sout | "unlock res is" | cnt_nolock;
+    cnt_nolock = 0;
+}
+extern "C"{
+    void test_lock(){
+        pthread_mutex_init(&_mutex, NULL);
+        pthread_t threads[20];
+        for (int i = 0; i < 20; i++){
+            
+            pthread_create(&threads[i], NULL, inc_lock, (void*)100000000);
+        }
+        for (int i = 0; i < 20; i++){
+            void * res = NULL;
+            pthread_join(threads[i], &res);
+        }
+        sout | "lock res is" | cnt_lock;
+        pthread_mutex_destroy(&_mutex);
+        if (cnt_lock != 100000000 * 20) {
+            sout | "pthread mutex not working";
+            exit(1);
+        }
+        cnt_lock = 0;
+    }
+}
+
+
+/* mutex trylock pthread routine  */
+void* trylock_test2(void* arg){
+    int res = pthread_mutex_trylock(&_mutex);
+    sout | "in trylocktest2 res1 is" | res;
+    res = pthread_mutex_trylock(&_mutex);
+    sout | "in trylocktest2 res2 is" | res;
+    pthread_mutex_lock(&_mutex);
+    for (int i = 0; i < (uint64_t)arg; i++) cnt_trylock++;
+    pthread_mutex_unlock(&_mutex);
+    return NULL;
+}
+
+void* trylock_test1(void* arg){
+    int res = pthread_mutex_trylock(&_mutex);
+    sout | "in trylocktest1 res1 is" | res;
+    res = pthread_mutex_trylock(&_mutex);
+    sout | "in trylocktest1 res2 is" | res;
+    pthread_t task2;
+    pthread_create(&task2, NULL, trylock_test2, (void*)100000000);
+
+    // inc cnt then release the lock
+    for (int i = 0; i < (uint64_t)arg; i++) cnt_trylock++;
+    pthread_mutex_unlock(&_mutex);
+    pthread_mutex_unlock(&_mutex);
+    void * dummy = NULL;
+    pthread_join(task2, &dummy);
+    sout | "cnt_trylock is " | cnt_trylock;
+    return NULL;
+}
+
+// trylock test
+void test_trylock(){
+    pthread_mutex_init(&_mutex, NULL);
+    pthread_t task1;
+    pthread_create(&task1, NULL, trylock_test1, (void*)100000000);
+    void * dummy = NULL;
+    pthread_join(task1,&dummy);
+    pthread_mutex_destroy(&_mutex);
+    if (cnt_trylock != 100000000 * 2) {
+        sout | "pthread try mutex not working";
+        exit(1);
+    }
+    cnt_trylock = 0;
+}
+
+
+
+int main(int argc, char const *argv[])
+{
+    
+    // compare unlock vs lock
+    test_lock();
+    // test trylock
+    test_trylock();
+    
+    return 0;
+}
Index: tests/concurrent/pthread/pthread_key_test.cfa
===================================================================
--- tests/concurrent/pthread/pthread_key_test.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/pthread_key_test.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,126 @@
+
+/* test pthread_key_create/set_specific/get_specific
+    get specific == set specific
+    dtor is invoked (no mem leak)
+*/
+
+
+extern "C"{
+
+    #include <stdio.h>
+    #include <stdlib.h>
+    #include <errno.h>
+    #include <pthread.h>
+
+    #define THREADS 5
+    #define BUFFSZ  48
+    pthread_key_t   key;
+    volatile int total_value,total_value_getspec;
+    pthread_mutex_t value_mutex;
+
+    void            *threadfunc(void *parm)
+    {
+        int        status;
+        void      *value;
+        int        threadnum;
+        int       *tnum;
+        void      *getvalue;
+        char       Buffer[BUFFSZ];
+
+        tnum = (int*)parm;
+        threadnum = *tnum;
+
+        //printf("Thread %d executing\n", threadnum);
+        value = (void *)(rand()%100);
+        status = pthread_setspecific(key, (void *) value);
+        if ( status !=  0) {
+            printf("pthread_setspecific failed, thread %d, errno %d",
+                                                        threadnum, errno);
+            return (void*)12;
+        }
+        pthread_mutex_lock(&value_mutex);
+        total_value_getspec += (int)value;
+        total_value += (int)pthread_getspecific(key);
+        pthread_mutex_unlock(&value_mutex);
+
+
+        if (!(value = malloc(sizeof(Buffer))))
+            printf("Thread %d could not allocate storage, errno = %d\n",
+                                                        threadnum, errno);
+        status = pthread_setspecific(key, (void *) value);
+        if ( status !=  0) {
+            printf("pthread_setspecific failed, thread %d, errno %d",
+                                                        threadnum, errno);
+            return (void*)12;
+        }
+        //printf("Thread %d setspecific value: %d\n", threadnum, value);
+
+        getvalue = 0;
+        getvalue = pthread_getspecific(key);
+
+        if (getvalue != value) {
+        printf("getvalue not valid, getvalue=%d", (u_int64_t)getvalue);
+            return (void*)68;
+        }
+
+        pthread_exit((void *)0);
+    }
+
+    void  destr_fn(void *parm)
+    {
+
+        printf("Destructor function invoked\n");
+        free(parm);
+    }
+
+
+    int main() {
+        int          getvalue;
+        int          status;
+        int          i;
+        int          threadparm[THREADS];
+        pthread_t    threadid[THREADS];
+        void*          thread_stat[THREADS];
+
+        // rand seed for testing
+        srand(1003);
+        pthread_mutex_init(&value_mutex, NULL);
+
+        // testing getspec and setspec
+        total_value = 0;
+        total_value_getspec = 0;
+
+        if ((status = pthread_key_create(&key, destr_fn )) < 0) {
+            printf("pthread_key_create failed, errno=%d", errno);
+            exit(1);
+        }
+
+        // create 3 THREADS, pass each its number
+        for (i=0; i<THREADS; i++) {
+            threadparm[i] = i+1;
+            status = pthread_create( &threadid[i],
+                                    NULL,
+                                    threadfunc,
+                                    (void *)&threadparm[i]);
+            if ( status <  0) {
+            printf("pthread_create failed, errno=%d", errno);
+            exit(2);
+            }
+        }
+
+        for ( i=0; i<THREADS; i++) {
+            status = pthread_join( threadid[i], (void **)&thread_stat[i]);
+            if ( status <  0) {
+            printf("pthread_join failed, thread %d, errno=%d\n", i+1, errno);
+            }
+
+            if (thread_stat[i] != 0)   {
+                printf("bad thread status, thread %d, status=%d\n", i+1,
+                                                        (u_int64_t)thread_stat[i]);
+            }
+        }
+        printf("total value is %d, total value by pthread_getspecific is %d\n", total_value, total_value_getspec);
+        exit(0);
+    }   // main
+}
+
Index: tests/concurrent/pthread/pthread_once_test.cfa
===================================================================
--- tests/concurrent/pthread/pthread_once_test.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
+++ tests/concurrent/pthread/pthread_once_test.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -0,0 +1,96 @@
+// tested pthread once,create,join
+
+                                                          
+                                                                                
+                                                            
+#include <fstream.hfa>
+#include <thread.hfa>                                                                    
+#define THREADS 20                                                                                                                                                    
+
+extern "C"{
+    #include <pthread.h>
+    #include <stdio.h>
+    #include <errno.h> 
+    int             once_counter=0;                                                 
+    pthread_once_t  once_control = PTHREAD_ONCE_INIT;                               
+                                                                                    
+    void  once_fn(void)                                                             
+    {                                                                               
+    puts("in once_fn");                                                            
+    once_counter++;                                                                
+    }                                                                               
+                                                                                    
+    void            *threadfunc(void *parm)                                         
+    {                                                                               
+    int        status;                                                             
+    int        threadnum;                                                          
+    int        *tnum;                                                              
+                                                                                    
+    tnum = (int *)parm;                                                                   
+    threadnum = *tnum;                                                             
+                                                                                    
+    //printf("Thread %d executing\n", threadnum);                                    
+                                                                                    
+    status = pthread_once(&once_control, once_fn);                                 
+    if ( status <  0)                                                              
+        printf("pthread_once failed, thread %d, errno=%d\n", threadnum,             
+                                                                errno);             
+                                                                                    
+    //pthread_exit((void *)0);  
+    return NULL;                                                     
+    }  
+
+
+    void once_rtn(){
+        printf("in once init\n");
+    }
+    void test(){
+
+        processor p[10];
+        
+
+        int          status;                                                           
+        int          i;                                                                
+        int          threadparm[THREADS];                                              
+        pthread_t    threadid[THREADS];                                                
+        void*          thread_stat[THREADS];                                             
+                                                                                        
+        for (i=0; i<THREADS; i++) {                                                    
+            threadparm[i] = i+1;                                                        
+            status = pthread_create( &threadid[i],                                      
+                                    NULL,                                              
+                                    threadfunc,                                        
+                                    (void *)&threadparm[i]);                           
+            if ( status <  0) {                                                         
+            printf("pthread_create failed, errno=%d", errno);                        
+            exit(2);                                                                 
+            }                                                                           
+        }                                                                             
+                                                                                        
+        for ( i=0; i<THREADS; i++) {                                                   
+            status = pthread_join( threadid[i], (void **)&thread_stat[i]);               
+            if ( status <  0)                                                           
+            printf("pthread_join failed, thread %d, errno=%d\n", i+1, errno);        
+                                                                                        
+            if (thread_stat[i] != 0)                                                    
+                printf("bad thread status, thread %d, status=%d\n", i+1,                
+                                                        (int)thread_stat[i]);             
+        }                                                                             
+                                                                                        
+        if (once_counter != 1) {
+            printf("once_fn did not get control once, counter=%d",once_counter);         
+            exit(1);
+        }                                                        
+        
+        exit(0);
+        
+    }
+}
+
+
+
+int main(int argc, char const *argv[])
+{
+    test();
+    return 0;
+}
Index: tests/configs/parsebools.cfa
===================================================================
--- tests/configs/parsebools.cfa	(revision e874605d8b0f66ad6050e4d03825b57912afe8ac)
+++ tests/configs/parsebools.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -15,8 +15,10 @@
 //
 
-#include <parseargs.hfa>
 #include <fstream.hfa>
 
 #include "../meta/fork+exec.hfa"
+
+// last as a work around to a parse bug
+#include <parseargs.hfa>
 
 int main(int argc, char * argv[]) {
@@ -30,16 +32,14 @@
 	bool sf = true;
 
-	cfa_option options[] = {
-		{'e', "yesno",     "test yes/no",     YN, parse_yesno},
-		{'y', "YN",        "test yes/no",     Yn, parse_yesno},
-		{'n', "yn",        "test yes/no",     yn, parse_yesno},
-		{'t', "truefalse", "test true/false", tf, parse_truefalse},
-		{'s', "settrue",   "test set true",   st, parse_settrue},
-		{'u', "setfalse",  "test set false",  sf, parse_setfalse},
-	};
-	int options_cnt = sizeof(options) / sizeof(cfa_option);
+	array( cfa_option, 6 ) options;
+	options[0] = (cfa_option){'e', "yesno",     "test yes/no",     YN, parse_yesno};
+	options[1] = (cfa_option){'y', "YN",        "test yes/no",     Yn, parse_yesno};
+	options[2] = (cfa_option){'n', "yn",        "test yes/no",     yn, parse_yesno};
+	options[3] = (cfa_option){'t', "truefalse", "test true/false", tf, parse_truefalse};
+	options[4] = (cfa_option){'s', "settrue",   "test set true",   st, parse_settrue};
+	options[5] = (cfa_option){'u', "setfalse",  "test set false",  sf, parse_setfalse};
 
 	char **left;
-	parse_args( options, options_cnt, "[OPTIONS]...\ntesting bool parameters", left);
+	parse_args( options, "[OPTIONS]...\ntesting bool parameters", left);
 
 	sout | "yes/no     :" | YN;
Index: tests/configs/parsenums.cfa
===================================================================
--- tests/configs/parsenums.cfa	(revision e874605d8b0f66ad6050e4d03825b57912afe8ac)
+++ tests/configs/parsenums.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -15,8 +15,10 @@
 //
 
+#include <fstream.hfa>
+
+#include "../meta/fork+exec.hfa"
+
+// last as workaround to parser bug
 #include <parseargs.hfa>
-#include <fstream.hfa>
-
-#include "../meta/fork+exec.hfa"
 
 #if __SIZEOF_LONG__ == 4
@@ -42,15 +44,13 @@
 
 
-	cfa_option options[] = {
-		{ 'i', "int",              "test int",                i   },
-		{ 'u', "unsigned",         "test unsigned",           u   },
-		{ 'l', "unsignedlong",     "test unsigned long",      ul  },
-		{ 'L', "unsignedlonglong", "test unsigned long long", ull },
-		{ 'd', "double",           "test double",             d   },
-	};
-	int options_cnt = sizeof(options) / sizeof(cfa_option);
+	array( cfa_option, 5 ) options;
+	options[0] = (cfa_option){ 'i', "int",              "test int",                i   };
+	options[1] = (cfa_option){ 'u', "unsigned",         "test unsigned",           u   };
+	options[2] = (cfa_option){ 'l', "unsignedlong",     "test unsigned long",      ul  };
+	options[3] = (cfa_option){ 'L', "unsignedlonglong", "test unsigned long long", ull };
+	options[4] = (cfa_option){ 'd', "double",           "test double",             d   };
 
 	char **left;
-	parse_args( options, options_cnt, "[OPTIONS]...\ntesting bool parameters", left);
+	parse_args( options, "[OPTIONS]...\ntesting bool parameters", left);
 
 	sout | "int                :" | i;
Index: tests/configs/usage.cfa
===================================================================
--- tests/configs/usage.cfa	(revision e874605d8b0f66ad6050e4d03825b57912afe8ac)
+++ tests/configs/usage.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -15,8 +15,8 @@
 //
 
+#include <fstream.hfa>
+#include "../meta/fork+exec.hfa"
 #include <parseargs.hfa>
-#include <fstream.hfa>
 
-#include "../meta/fork+exec.hfa"
 
 int main() {
@@ -25,6 +25,6 @@
 	sout | "No args, no errors";
 	if(pid_t child = strict_fork(); child == 0) {
-		cfa_option opts[0];
-		print_args_usage(1, fake_argv, opts, 0, "Test usage", false);
+		array( cfa_option, 0 ) opts;
+		print_args_usage(1, fake_argv, opts, "Test usage", false);
 	}
 	else {
@@ -35,6 +35,6 @@
 	sout | "No args, with errors";
 	if(pid_t child = strict_fork(); child == 0) {
-		cfa_option opts[0];
-		print_args_usage(1, fake_argv, opts, 0, "Test usage", true);
+		array( cfa_option, 0 ) opts;
+		print_args_usage(1, fake_argv, opts, "Test usage", true);
 	}
 	else {
@@ -46,10 +46,9 @@
 	if(pid_t child = strict_fork(); child == 0) {
 		int a, b, c;
-		cfa_option opts[] = {
-			{'a', "", "First arg", a },
-			{'b', "", "Second arg", b },
-			{'c', "", "Third arg", c },
-		};
-		print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
+		array( cfa_option, 3 ) opts;
+		opts[0] = (cfa_option){'a', "", "First arg", a };
+		opts[1] = (cfa_option){'b', "", "Second arg", b };
+		opts[2] = (cfa_option){'c', "", "Third arg", c };
+		print_args_usage(1, fake_argv, opts, "Test usage", false);
 	}
 	else {
@@ -61,10 +60,9 @@
 	if(pid_t child = strict_fork(); child == 0) {
 		int a, b, c;
-		cfa_option opts[] = {
-			{'\0', "AA", "First arg", a },
-			{'\0', "BB", "Second arg", b },
-			{'\0', "CC", "Third arg", c },
-		};
-		print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
+		array( cfa_option, 3 ) opts;
+		opts[0] = (cfa_option){'\0', "AA", "First arg", a };
+		opts[1] = (cfa_option){'\0', "BB", "Second arg", b };
+		opts[2] = (cfa_option){'\0', "CC", "Third arg", c };
+		print_args_usage(1, fake_argv, opts, "Test usage", false);
 	}
 	else {
@@ -76,10 +74,9 @@
 	if(pid_t child = strict_fork(); child == 0) {
 		int a, b, c;
-		cfa_option opts[] = {
-			{'a', "", "First arg", a },
-			{'b', "BBBB", "Second arg", b },
-			{'\0', "CC", "Third arg", c },
-		};
-		print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
+		array( cfa_option, 3 ) opts;
+		opts[0] = (cfa_option){'a', "", "First arg", a };
+		opts[1] = (cfa_option){'b', "BBBB", "Second arg", b };
+		opts[2] = (cfa_option){'\0', "CC", "Third arg", c };
+		print_args_usage(1, fake_argv, opts, "Test usage", false);
 	}
 	else {
@@ -91,10 +88,9 @@
 	if(pid_t child = strict_fork(); child == 0) {
 		int a, b, c;
-		cfa_option opts[] = {
-			{'a', "", "First arg", a },
-			{'b', "BBBB", "", b },
-			{'\0', "CC", "Third arg", c },
-		};
-		print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
+		array( cfa_option, 3 ) opts;
+		opts[0] = (cfa_option){'a', "", "First arg", a };
+		opts[1] = (cfa_option){'b', "BBBB", "", b };
+		opts[2] = (cfa_option){'\0', "CC", "Third arg", c };
+		print_args_usage(1, fake_argv, opts, "Test usage", false);
 	}
 	else {
@@ -106,10 +102,9 @@
 	if(pid_t child = strict_fork(); child == 0) {
 		int a, b, c;
-		cfa_option opts[] = {
-			{'a', "", "First arg\nThe description has multiple lines,\n...for some reason", a },
-			{'b', "BBBB", "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", b },
-			{'\0', "CC", "Third arg", c },
-		};
-		print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
+		array( cfa_option, 3 ) opts;
+		opts[0] = (cfa_option){'a', "", "First arg\nThe description has multiple lines,\n...for some reason", a };
+		opts[1] = (cfa_option){'b', "BBBB", "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", b };
+		opts[2] = (cfa_option){'\0', "CC", "Third arg", c };
+		print_args_usage(1, fake_argv, opts, "Test usage", false);
 	}
 	else {
Index: tests/device/cpu.cfa
===================================================================
--- tests/device/cpu.cfa	(revision e874605d8b0f66ad6050e4d03825b57912afe8ac)
+++ tests/device/cpu.cfa	(revision c7f12a486e42e8b7e1569779966df2681cc1ed38)
@@ -117,4 +117,5 @@
 unsigned find_idx() {
 	int idxs = count_cache_indexes();
+	if( 0 == idxs ) return 0;
 
 	unsigned found_level = 0;
@@ -179,5 +180,5 @@
 	unsigned idx = find_idx();
 	// For all procs check mapping is consistent
-	for(cpu_me; cpu_info.hthrd_count) {
+	if( idx > 0 ) for(cpu_me; cpu_info.hthrd_count) {
 		char buf_me[32];
 		size_t len_me = read_cpuidxinfo_into(cpu_me, idx, "shared_cpu_list", buf_me, 32);
