source: libcfa/src/concurrency/thread.cfa @ fcd0b9d7

arm-ehjacob/cs343-translationnew-ast-unique-expr
Last change on this file since fcd0b9d7 was fcd0b9d7, checked in by Michael Brooks <mlbrooks@…>, 12 months 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
Line 
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//
7// thread.c --
8//
9// Author           : Thierry Delisle
10// Created On       : Tue Jan 17 12:27:26 2017
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Dec  4 09:17:49 2019
13// Update Count     : 9
14//
15
16#define __cforall_thread__
17
18#include "thread.hfa"
19
20#include "kernel_private.hfa"
21#include "exception.hfa"
22
23#define __CFA_INVOKE_PRIVATE__
24#include "invoke.h"
25
26//-----------------------------------------------------------------------------
27// Thread ctors and dtors
28void ?{}($thread & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
29        context{ 0p, 0p };
30        self_cor{ name, storage, storageSize };
31        ticket = TICKET_RUNNING;
32        state = Start;
33        preempted = __NO_PREEMPTION;
34        curr_cor = &self_cor;
35        self_mon.owner = &this;
36        self_mon.recursion = 1;
37        self_mon_p = &self_mon;
38        curr_cluster = &cl;
39        link.next = 0p;
40        link.prev = 0p;
41        link.preferred = -1;
42        #if defined( __CFA_WITH_VERIFY__ )
43                canary = 0x0D15EA5E0D15EA5Ep;
44        #endif
45
46        seqable.next = 0p;
47        seqable.back = 0p;
48
49        node.next = 0p;
50        node.prev = 0p;
51        doregister(curr_cluster, this);
52
53        monitors{ &self_mon_p, 1, (fptr_t)0 };
54}
55
56void ^?{}($thread& this) with( this ) {
57        #if defined( __CFA_WITH_VERIFY__ )
58                canary = 0xDEADDEADDEADDEADp;
59        #endif
60        unregister(curr_cluster, this);
61        ^self_cor{};
62}
63
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,
85                T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) {
86        $monitor * m = get_monitor(thrd);
87        $thread * desc = get_thread(thrd);
88
89        // Setup the monitor guard
90        void (*dtor)(T& mutex this) = ^?{};
91        bool join = cancelHandler != (void(*)(ThreadCancelled(T)&))0;
92        (this.mg){&m, (void(*)())dtor, join};
93
94
95        /* paranoid */ verifyf( Halted == desc->state || Cancelled == desc->state, "Expected thread to be Halted or Cancelled, was %d\n", (int)desc->state );
96
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;
105        void(*defaultResumptionHandler)(ThreadCancelled(T) &) =
106                join ? cancelHandler : default_thread_cancel_handler;
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;
118}
119
120void ^?{}( thread_dtor_guard_t & this ) {
121        ^(this.mg){};
122}
123
124//-----------------------------------------------------------------------------
125// Starting and stopping threads
126forall( dtype T | is_thread(T) )
127void __thrd_start( T & this, void (*main_p)(T &) ) {
128        $thread * this_thrd = get_thread(this);
129
130        disable_interrupts();
131        __cfactx_start(main_p, get_coroutine(this), this, __cfactx_invoke_thread);
132
133        this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
134        /* paranoid */ verify( this_thrd->context.SP );
135
136        __schedule_thread( this_thrd );
137        enable_interrupts( __cfaabi_dbg_ctx );
138}
139
140//-----------------------------------------------------------------------------
141// Support for threads that don't ues the thread keyword
142forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } )
143void ?{}( scoped(T)& this ) with( this ) {
144        handle{};
145        __thrd_start(handle, main);
146}
147
148forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T&, P); } )
149void ?{}( scoped(T)& this, P params ) with( this ) {
150        handle{ params };
151        __thrd_start(handle, main);
152}
153
154forall( dtype T | sized(T) | is_thread(T) )
155void ^?{}( scoped(T)& this ) with( this ) {
156        ^handle{};
157}
158
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
166uint64_t thread_rand() {
167        disable_interrupts();
168        uint64_t ret = __tls_rand();
169        enable_interrupts( __cfaabi_dbg_ctx );
170        return ret;
171}
172
173// Local Variables: //
174// mode: c //
175// tab-width: 4 //
176// End: //
Note: See TracBrowser for help on using the repository browser.