source: libcfa/src/concurrency/thread.hfa @ 5d3d281

Last change on this file since 5d3d281 was 5d3d281, checked in by Michael Brooks <mlbrooks@…>, 7 days ago

Remove autogen forward declarations, which are never needed, and cause warnings about static declarations without definitions.

Intended to fix the failing test from previous commit.

Autogen forward declarations are never needed because they do not depend on each other, much less with mutual recursion.

Consequences:

  • tests/.expect/(5 tests).(3 archs).txt: Accept generated code that lacks autogen forward declarations
  • libcfa/src/concurrency/thread.*: Remove unused dependency on destructor from constructor (via thrd_start), by splitting trait is_thread with is_basic_thread
  • Property mode set to 100644
File size: 6.4 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 --
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 : Sun Sep  3 07:34:43 2023
13// Update Count     : 47
14//
15
16#pragma once
17
18#include <assert.h>
19#include "invoke.h"
20
21#include "coroutine.hfa"
22#include "kernel.hfa"
23#include "monitor.hfa"
24#include "exception.hfa"
25#include "bits/random.hfa"
26
27//-----------------------------------------------------------------------------
28// thread trait
29forall( T & )
30trait is_basic_thread {
31        void main(T& this);
32        thread$ * get_thread(T& this);
33};
34forall( T & | is_basic_thread(T) )
35trait is_thread {
36        void ^?{}(T& mutex this);
37};
38
39forall(thread_t &)
40exception ThreadCancelled {
41        thread_t * the_thread;
42        exception_t * the_exception;
43};
44
45forall(T &)
46void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src);
47
48forall(T &)
49const char * msg(ThreadCancelled(T) *);
50
51// Inline getters for threads/coroutines/monitors
52forall( T & | is_basic_thread(T) )
53static inline coroutine$ * get_coroutine(T & this) __attribute__((const)) { return &get_thread(this)->self_cor; }
54
55forall( T & | is_basic_thread(T) )
56static inline monitor$   * get_monitor  (T & this) __attribute__((const)) { return &get_thread(this)->self_mon; }
57
58static inline coroutine$ * get_coroutine(thread$ * this) __attribute__((const)) { return &this->self_cor; }
59static inline monitor$   * get_monitor  (thread$ * this) __attribute__((const)) { return &this->self_mon; }
60
61//-----------------------------------------------------------------------------
62// forward declarations needed for threads
63extern struct cluster * mainCluster;
64
65forall( T & | is_basic_thread(T) )
66void __thrd_start( T & this, void (*)(T &) );
67
68//-----------------------------------------------------------------------------
69// Ctors and dtors
70void ?{}(thread$ & this, const char * const name, struct cluster & cl, void * storage, size_t storageSize );
71void ^?{}(thread$ & this);
72
73static inline void ?{}(thread$ & this)                                                                  { this{ "Anonymous Thread", *mainCluster, 0p, DEFAULT_STACK_SIZE }; }
74static inline void ?{}(thread$ & this, size_t stackSize )                                               { this{ "Anonymous Thread", *mainCluster, 0p, stackSize }; }
75static inline void ?{}(thread$ & this, void * storage, size_t storageSize )                             { this{ "Anonymous Thread", *mainCluster, storage, storageSize }; }
76static inline void ?{}(thread$ & this, struct cluster & cl )                                            { this{ "Anonymous Thread", cl, 0p, DEFAULT_STACK_SIZE }; }
77static inline void ?{}(thread$ & this, struct cluster & cl, size_t stackSize )                          { this{ "Anonymous Thread", cl, 0p, stackSize }; }
78static inline void ?{}(thread$ & this, struct cluster & cl, void * storage, size_t storageSize )        { this{ "Anonymous Thread", cl, storage, storageSize }; }
79static inline void ?{}(thread$ & this, const char * const name)                                         { this{ name, *mainCluster, 0p, DEFAULT_STACK_SIZE }; }
80static inline void ?{}(thread$ & this, const char * const name, struct cluster & cl )                   { this{ name, cl, 0p, DEFAULT_STACK_SIZE }; }
81static inline void ?{}(thread$ & this, const char * const name, struct cluster & cl, size_t stackSize ) { this{ name, cl, 0p, stackSize }; }
82
83struct thread_dtor_guard_t {
84        monitor_dtor_guard_t mg;
85};
86
87forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled(T))
88        | { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); })
89void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) );
90void ^?{}( thread_dtor_guard_t & this );
91
92//-----------------------------------------------------------------------------
93// thread runner
94// Structure that actually start and stop threads
95forall( T & | sized(T) | is_thread(T) )
96struct scoped {
97        T handle;
98};
99
100forall( T & | sized(T) | is_thread(T) | { void ?{}(T&); } )
101void ?{}( scoped(T)& this );
102
103forall( T &, P... | sized(T) | is_thread(T) | { void ?{}(T&, P); } )
104void ?{}( scoped(T)& this, P params );
105
106forall( T & | sized(T) | is_thread(T) )
107void ^?{}( scoped(T)& this );
108
109//-----------------------------------------------------------------------------
110// Scheduler API
111
112//----------
113// Park thread: block until corresponding call to unpark, won't block if unpark is already called
114void park( void );
115
116//----------
117// Unpark a thread, if the thread is already blocked, schedule it
118//                  if the thread is not yet block, signal that it should rerun immediately
119void unpark( thread$ * this );
120
121forall( T & | is_thread(T) )
122static inline void unpark( T & this ) { if(!&this) return; unpark( get_thread( this ) );}
123
124//----------
125// Yield: force thread to block and be rescheduled
126bool force_yield( enum __Preemption_Reason );
127
128//----------
129// sleep: force thread to block and be rescheduled after Duration duration
130void sleep( Duration duration );
131
132//----------
133// join
134forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled(T))
135        | { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); })
136T & join( T & this );
137
138//----------
139// misc
140bool migrate( thread$ * thrd, struct cluster & cl );
141
142forall( T & | is_thread(T) )
143static inline bool migrate( T & mutex thrd, struct cluster & cl ) { return migrate( &(thread&)thrd, cl ); }
144
145
146//----------
147// prng
148void set_seed( size_t seed );
149size_t get_seed( void ) __attribute__(( warn_unused_result ));
150static inline {
151        size_t prng( thread$ & th ) __attribute__(( warn_unused_result )) { return PRNG_NAME( th.random_state ); } // [0,UINT_MAX]
152        size_t prng( thread$ & th, size_t u ) __attribute__(( warn_unused_result )) { return prng( th ) % u; } // [0,u)
153        size_t prng( thread$ & th, size_t l, size_t u ) __attribute__(( warn_unused_result )) { return prng( th, u - l + 1 ) + l; } // [l,u]
154        forall( T & | is_thread(T) ) {
155                size_t prng( T & th ) __attribute__(( warn_unused_result )) { return prng( (thread &)th ); } // [0,UINT_MAX]
156                size_t prng( T & th, size_t u ) __attribute__(( warn_unused_result )) { return prng( th ) % u; } // [0,u)
157                size_t prng( T & th, size_t l, size_t u ) __attribute__(( warn_unused_result )) { return prng( th, u - l + 1 ) + l; } // [l,u]
158        } // distribution
159} // distribution
160
161// Local Variables: //
162// mode: c //
163// tab-width: 4 //
164// End: //
Note: See TracBrowser for help on using the repository browser.