Skip to content

Commit ab06100

Browse files
xerenhernan-poncedeleon
authored andcommitted
Add Intrinsics pthread_detach (#905)
1 parent f5f562f commit ab06100

File tree

11 files changed

+2960
-2018
lines changed

11 files changed

+2960
-2018
lines changed

benchmarks/miscellaneous/pthread.c

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ void* thread_join(pthread_t id)
3838
//define PTHREAD_PRIO_NONE 0
3939
//define PTHREAD_PRIO_INHERIT 1
4040
//define PTHREAD_PRIO_PROTECT 2
41-
//define PTHREAD_MUTEX_POLICY_FAIRSHARE_NP 1
42-
//define PTHREAD_MUTEX_POLICY_FIRSTFIT_NP 3
43-
void mutex_init(pthread_mutex_t* lock, int type, int protocol, int policy, int prioceiling)
41+
void mutex_init(pthread_mutex_t* lock, int type, int protocol, int prioceiling)
4442
{
4543
int status;
4644
int value;
@@ -58,11 +56,6 @@ void mutex_init(pthread_mutex_t* lock, int type, int protocol, int policy, int p
5856
status = pthread_mutexattr_getprotocol(&attributes, &value);
5957
assert(status == 0);// && value == protocol);
6058

61-
status = pthread_mutexattr_setpolicy_np(&attributes, policy);
62-
assert(status == 0);
63-
status = pthread_mutexattr_getpolicy_np(&attributes, &value);
64-
assert(status == 0);// && value == policy);
65-
6659
status = pthread_mutexattr_setprioceiling(&attributes, prioceiling);
6760
assert(status == 0);
6861
status = pthread_mutexattr_getprioceiling(&attributes, &value);
@@ -104,8 +97,8 @@ void mutex_test()
10497
pthread_mutex_t mutex0;
10598
pthread_mutex_t mutex1;
10699
//TODO Add different behavior based on attributes.
107-
mutex_init(&mutex0, PTHREAD_MUTEX_ERRORCHECK, PTHREAD_PRIO_INHERIT, PTHREAD_MUTEX_POLICY_FAIRSHARE_NP, 1);
108-
mutex_init(&mutex1, PTHREAD_MUTEX_RECURSIVE, PTHREAD_PRIO_PROTECT, PTHREAD_MUTEX_POLICY_FIRSTFIT_NP, 2);
100+
mutex_init(&mutex0, PTHREAD_MUTEX_ERRORCHECK, PTHREAD_PRIO_INHERIT, 1);
101+
mutex_init(&mutex1, PTHREAD_MUTEX_RECURSIVE, PTHREAD_PRIO_PROTECT, 2);
109102

110103
{
111104
mutex_lock(&mutex0);
@@ -229,7 +222,7 @@ void* cond_worker(void* message)
229222
void cond_test()
230223
{
231224
void* message = (void*) 42;
232-
mutex_init(&cond_mutex, PTHREAD_MUTEX_NORMAL, PTHREAD_PRIO_NONE, PTHREAD_MUTEX_POLICY_FIRSTFIT_NP, 0);
225+
mutex_init(&cond_mutex, PTHREAD_MUTEX_NORMAL, PTHREAD_PRIO_NONE, 0);
233226
cond_init(&cond);
234227

235228
pthread_t worker = thread_create(cond_worker, message);
@@ -412,10 +405,59 @@ void key_test()
412405
//assert(pthread_equal(latest_thread, worker));//TODO add support for destructors
413406
}
414407

408+
// -------- detaching threads
409+
410+
void* detach_test_worker0(void* ignore)
411+
{
412+
return NULL;
413+
}
414+
415+
void* detach_test_detach(void* ignore)
416+
{
417+
int status;
418+
pthread_t w0 = thread_create(detach_test_worker0, NULL);
419+
status = pthread_detach(w0);
420+
assert(status == 0);
421+
422+
status = pthread_join(w0, NULL);
423+
assert(status != 0);
424+
return NULL;
425+
}
426+
427+
void* detach_test_attr(void* ignore)
428+
{
429+
int status;
430+
int detachstate;
431+
pthread_t w0;
432+
pthread_attr_t w0_attr;
433+
status = pthread_attr_init(&w0_attr);
434+
assert(status == 0);
435+
status = pthread_attr_getdetachstate(&w0_attr, &detachstate);
436+
assert(status == 0 && detachstate == PTHREAD_CREATE_JOINABLE);
437+
status = pthread_attr_setdetachstate(&w0_attr, PTHREAD_CREATE_DETACHED);
438+
assert(status == 0);
439+
status = pthread_attr_getdetachstate(&w0_attr, &detachstate);
440+
assert(status == 0 && detachstate == PTHREAD_CREATE_DETACHED);
441+
status = pthread_create(&w0, &w0_attr, detach_test_worker0, NULL);
442+
assert(status == 0);
443+
pthread_attr_destroy(&w0_attr);
444+
445+
status = pthread_join(w0, NULL);
446+
assert(status != 0);
447+
return NULL;
448+
}
449+
450+
void detach_test()
451+
{
452+
thread_create(detach_test_detach, NULL);
453+
thread_create(detach_test_attr, NULL);
454+
}
455+
415456
int main()
416457
{
417458
mutex_test();
418459
cond_test();
419460
rwlock_test();
420461
key_test();
462+
detach_test();
421463
}

dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.dat3m.dartagnan.program.event.functions.VoidFunctionCall;
3838
import com.dat3m.dartagnan.program.event.lang.catomic.*;
3939
import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadCreate;
40+
import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadDetach;
4041
import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadJoin;
4142
import com.dat3m.dartagnan.program.event.lang.linux.*;
4243
import com.dat3m.dartagnan.program.event.lang.llvm.*;
@@ -333,6 +334,10 @@ public static DynamicThreadJoin newDynamicThreadJoin(Register resultRegister, Ex
333334
return new DynamicThreadJoin(resultRegister, tidExpr);
334335
}
335336

337+
public static DynamicThreadDetach newDynamicThreadDetach(Register statusReg, Expression tidExpr) {
338+
return new DynamicThreadDetach(statusReg, tidExpr);
339+
}
340+
336341
public static ThreadCreate newThreadCreate(List<Expression> arguments) {
337342
return new ThreadCreate(arguments);
338343
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.dat3m.dartagnan.program.event.lang.dat3m;
2+
3+
import com.dat3m.dartagnan.expression.Expression;
4+
import com.dat3m.dartagnan.expression.ExpressionVisitor;
5+
import com.dat3m.dartagnan.program.Register;
6+
import com.dat3m.dartagnan.program.event.AbstractEvent;
7+
import com.dat3m.dartagnan.program.event.Event;
8+
import com.dat3m.dartagnan.program.event.RegReader;
9+
import com.dat3m.dartagnan.program.event.RegWriter;
10+
11+
import java.util.HashSet;
12+
import java.util.Set;
13+
14+
public final class DynamicThreadDetach extends AbstractEvent implements RegWriter, RegReader {
15+
16+
private Register status;
17+
private Expression tid;
18+
19+
public DynamicThreadDetach(Register statusRegister, Expression tidExpression) {
20+
this.status = statusRegister;
21+
this.tid = tidExpression;
22+
}
23+
24+
private DynamicThreadDetach(DynamicThreadDetach copy) {
25+
super(copy);
26+
this.status = copy.status;
27+
this.tid = copy.tid;
28+
}
29+
30+
public Expression getTid() {
31+
return tid;
32+
}
33+
34+
@Override
35+
protected String defaultString() {
36+
return String.format("%s <- DynamicThreadDetach(%s)", status, tid);
37+
}
38+
39+
@Override
40+
public Event getCopy() {
41+
return new DynamicThreadDetach(this);
42+
}
43+
44+
@Override
45+
public Register getResultRegister() {
46+
return status;
47+
}
48+
49+
@Override
50+
public void setResultRegister(Register reg) {
51+
status = reg;
52+
}
53+
54+
@Override
55+
public Set<Register.Read> getRegisterReads() {
56+
return Register.collectRegisterReads(tid, Register.UsageType.OTHER, new HashSet<>());
57+
}
58+
59+
@Override
60+
public void transformExpressions(ExpressionVisitor<? extends Expression> exprTransformer) {
61+
tid = tid.accept(exprTransformer);
62+
}
63+
}

dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/dat3m/DynamicThreadJoin.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ The status register shall be large enough to accommodate all error values (bv8 s
2929
public class DynamicThreadJoin extends AbstractEvent implements RegWriter, RegReader, BlockingEvent {
3030

3131
public enum Status {
32-
SUCCESS(0), // The join was successful
33-
INVALID_TID(1), // The provided tid does not match with a joinable thread
34-
INVALID_RETURN_TYPE(2); // The provided tid is valid, but the return type of that thread does not match
32+
SUCCESS(0), // The join was successful.
33+
INVALID_TID(1), // The provided tid does not match with any of the spawned threads.
34+
INVALID_RETURN_TYPE(2), // The provided tid is valid, but the return type of that thread does not match
3535
// with the expected return type.
36+
DETACHED_THREAD(3); // The provided tid belongs to a non-joinable thread.
3637

3738
final int errorCode;
3839
public int getErrorCode() { return errorCode; }

dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/AssignmentInlining.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public Expression visitRegister(Register reg) {
7878
// A usage counter may be missing for assignments of the form "r = f(r)"
7979
// which do not allow for substituting r for f(r) in later usages.
8080
usageCounter.containsKey(lastAssignment)
81+
&& preDominatorTree.contains(curEvent)
8182
&& preDominatorTree.isDominatedBy(curEvent, lastAssignment)
8283
&& !curEvent.hasTag(Tag.NOOPT)
8384
// Inline if the expression is only used once or if it leads to simplifications.

0 commit comments

Comments
 (0)