source: libcfa/src/concurrency/thread.cfa@ 6f36dde

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 6f36dde was fcd0b9d7, checked in by Michael Brooks <mlbrooks@…>, 5 years ago

PolyCost calculation result becomes 0 or 1 per type, avoiding double-couting. Fixes #235

PolyCost calculation is documented as "Count of parameters and return values bound to some poly type." Before this fix, the cost calculation, looking inside one parameter or return, counted each occurrence of a poly type that it found there. This caused an incorrect increase in PolyCost on cases like #235 where several type variables are used in the declaration of one parameter.

libcfa/src/concurrency/thread.cfa: Changing a decl-use pattern to keep resolution consistent (no behaviour is changed). The management of defaultResumptionHandler in the thread constructor was benefitting from bug #235 to disambiguate assignment to local variable vs assignment to declared function (due to #234). After this change, the code works around that false ambiguity by using a different name for the local variable.

tests/avl*: Adding a missing assertion on the custom destructor definition. Previously, the destructor definition was benefiting from bug #235 to avoid the missing-assertion-on-custom-dtor problem described in #227.

  • Property mode set to 100644
File size: 4.8 KB
RevLine 
[78b3f52]1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[75a17f1]7// thread.c --
[78b3f52]8//
9// Author : Thierry Delisle
[f07e037]10// Created On : Tue Jan 17 12:27:26 2017
[6b0b624]11// Last Modified By : Peter A. Buhr
[121be3e]12// Last Modified On : Wed Dec 4 09:17:49 2019
13// Update Count : 9
[78b3f52]14//
15
[2026bb6]16#define __cforall_thread__
17
[58b6d1b]18#include "thread.hfa"
[78b3f52]19
[73abe95]20#include "kernel_private.hfa"
[ab8c6a6]21#include "exception.hfa"
[8118303]22
23#define __CFA_INVOKE_PRIVATE__
24#include "invoke.h"
25
26//-----------------------------------------------------------------------------
27// Thread ctors and dtors
[ac2b598]28void ?{}($thread & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
[121be3e]29 context{ 0p, 0p };
[de6319f]30 self_cor{ name, storage, storageSize };
[6a77224]31 ticket = TICKET_RUNNING;
[e8e457e]32 state = Start;
[3381ed7]33 preempted = __NO_PREEMPTION;
[82c948c]34 curr_cor = &self_cor;
[65deb18]35 self_mon.owner = &this;
36 self_mon.recursion = 1;
37 self_mon_p = &self_mon;
[de6319f]38 curr_cluster = &cl;
[b798713]39 link.next = 0p;
40 link.prev = 0p;
[d72c074]41 link.preferred = -1;
[b4b63e8]42 #if defined( __CFA_WITH_VERIFY__ )
[ac12f1f]43 canary = 0x0D15EA5E0D15EA5Ep;
[b4b63e8]44 #endif
[de94a60]45
[c131a02]46 seqable.next = 0p;
47 seqable.back = 0p;
48
[121be3e]49 node.next = 0p;
50 node.prev = 0p;
[a1a17a74]51 doregister(curr_cluster, this);
[5ea06d6]52
[65deb18]53 monitors{ &self_mon_p, 1, (fptr_t)0 };
[8118303]54}
55
[ac2b598]56void ^?{}($thread& this) with( this ) {
[b4b63e8]57 #if defined( __CFA_WITH_VERIFY__ )
[ac12f1f]58 canary = 0xDEADDEADDEADDEADp;
[b4b63e8]59 #endif
[a1a17a74]60 unregister(curr_cluster, this);
[65deb18]61 ^self_cor{};
[8118303]62}
63
[ab8c6a6]64FORALL_DATA_INSTANCE(ThreadCancelled, (dtype thread_t), (thread_t))
65
66forall(dtype T)
67void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src) {
68 dst->virtual_table = src->virtual_table;
69 dst->the_thread = src->the_thread;
70 dst->the_exception = src->the_exception;
71}
72
73forall(dtype T)
74const char * msg(ThreadCancelled(T) *) {
75 return "ThreadCancelled";
76}
77
78forall(dtype T)
79static void default_thread_cancel_handler(ThreadCancelled(T) & ) {
80 abort( "Unhandled thread cancellation.\n" );
81}
82
83forall(dtype T | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)))
84void ?{}( thread_dtor_guard_t & this,
[fcd0b9d7]85 T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) {
86 $monitor * m = get_monitor(thrd);
[3ea8ad1]87 $thread * desc = get_thread(thrd);
88
89 // Setup the monitor guard
[ab8c6a6]90 void (*dtor)(T& mutex this) = ^?{};
[fcd0b9d7]91 bool join = cancelHandler != (void(*)(ThreadCancelled(T)&))0;
[ab8c6a6]92 (this.mg){&m, (void(*)())dtor, join};
[342be43]93
[3ea8ad1]94
95 /* paranoid */ verifyf( Halted == desc->state || Cancelled == desc->state, "Expected thread to be Halted or Cancelled, was %d\n", (int)desc->state );
96
[342be43]97 // After the guard set-up and any wait, check for cancellation.
98 struct _Unwind_Exception * cancellation = desc->self_cor.cancellation;
99 if ( likely( 0p == cancellation ) ) {
100 return;
101 } else if ( Cancelled == desc->state ) {
102 return;
103 }
104 desc->state = Cancelled;
[fcd0b9d7]105 void(*defaultResumptionHandler)(ThreadCancelled(T) &) =
106 join ? cancelHandler : default_thread_cancel_handler;
[342be43]107
108 ThreadCancelled(T) except;
109 // TODO: Remove explitate vtable set once trac#186 is fixed.
110 except.virtual_table = &get_exception_vtable(&except);
111 except.the_thread = &thrd;
112 except.the_exception = __cfaehm_cancellation_exception( cancellation );
113 throwResume except;
114
115 except.the_exception->virtual_table->free( except.the_exception );
116 free( cancellation );
117 desc->self_cor.cancellation = 0p;
[ab8c6a6]118}
119
120void ^?{}( thread_dtor_guard_t & this ) {
121 ^(this.mg){};
122}
123
[8118303]124//-----------------------------------------------------------------------------
125// Starting and stopping threads
[0c92c9f]126forall( dtype T | is_thread(T) )
[09f357ec]127void __thrd_start( T & this, void (*main_p)(T &) ) {
[ac2b598]128 $thread * this_thrd = get_thread(this);
[8118303]129
[1c273d0]130 disable_interrupts();
[c7a900a]131 __cfactx_start(main_p, get_coroutine(this), this, __cfactx_invoke_thread);
[09f357ec]132
[e8e457e]133 this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
[ac5816d]134 /* paranoid */ verify( this_thrd->context.SP );
[8118303]135
[e873838]136 __schedule_thread( this_thrd );
[36982fc]137 enable_interrupts( __cfaabi_dbg_ctx );
[8118303]138}
139
[8c50aed]140//-----------------------------------------------------------------------------
141// Support for threads that don't ues the thread keyword
[242a902]142forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } )
[65deb18]143void ?{}( scoped(T)& this ) with( this ) {
144 handle{};
[09f357ec]145 __thrd_start(handle, main);
[bd98b58]146}
147
[242a902]148forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T&, P); } )
[65deb18]149void ?{}( scoped(T)& this, P params ) with( this ) {
150 handle{ params };
[09f357ec]151 __thrd_start(handle, main);
[8118303]152}
153
[9f1695b]154forall( dtype T | sized(T) | is_thread(T) )
[65deb18]155void ^?{}( scoped(T)& this ) with( this ) {
156 ^handle{};
[44264c5]157}
158
[ab8c6a6]159//-----------------------------------------------------------------------------
160forall(dtype T | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)))
161T & join( T & this ) {
162 thread_dtor_guard_t guard = { this, defaultResumptionHandler };
163 return this;
164}
165
[fe9468e2]166uint64_t thread_rand() {
167 disable_interrupts();
168 uint64_t ret = __tls_rand();
169 enable_interrupts( __cfaabi_dbg_ctx );
170 return ret;
171}
172
[78b3f52]173// Local Variables: //
174// mode: c //
175// tab-width: 4 //
[6a3d2e7]176// End: //
Note: See TracBrowser for help on using the repository browser.