source: libcfa/src/concurrency/thread.hfa @ 3381ed7

arm-ehjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since 3381ed7 was 3381ed7, checked in by Thierry Delisle <tdelisle@…>, 22 months ago

Added park/unpark primitives thread and removed BlockInternal?.
Converted monitors to use park unpark.
Intrusive Queue now mark next field when thread is inside queue.
Added several asserts to kernel and monitor.
Added a few tests for park and unpark.

  • 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 --
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:18:14 2019
13// Update Count     : 6
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
25//-----------------------------------------------------------------------------
26// thread trait
27trait is_thread(dtype T) {
28      void ^?{}(T& mutex this);
29      void main(T& this);
30      thread_desc* get_thread(T& this);
31};
32
33#define DECL_THREAD(X) thread_desc* get_thread(X& this) { return &this.__thrd; } void main(X& this)
34
35forall( dtype T | is_thread(T) )
36static inline coroutine_desc* get_coroutine(T & this) {
37        return &get_thread(this)->self_cor;
38}
39
40forall( dtype T | is_thread(T) )
41static inline monitor_desc* get_monitor(T & this) {
42        return &get_thread(this)->self_mon;
43}
44
45static inline coroutine_desc* get_coroutine(thread_desc * this) {
46        return &this->self_cor;
47}
48
49static inline monitor_desc* get_monitor(thread_desc * this) {
50        return &this->self_mon;
51}
52
53extern struct cluster * mainCluster;
54
55forall( dtype T | is_thread(T) )
56void __thrd_start( T & this, void (*)(T &) );
57
58//-----------------------------------------------------------------------------
59// Ctors and dtors
60void ?{}(thread_desc & this, const char * const name, struct cluster & cl, void * storage, size_t storageSize );
61void ^?{}(thread_desc & this);
62
63static inline void ?{}(thread_desc & this)                                                                  { this{ "Anonymous Thread", *mainCluster, 0p, 65000 }; }
64static inline void ?{}(thread_desc & this, size_t stackSize )                                               { this{ "Anonymous Thread", *mainCluster, 0p, stackSize }; }
65static inline void ?{}(thread_desc & this, void * storage, size_t storageSize )                             { this{ "Anonymous Thread", *mainCluster, storage, storageSize }; }
66static inline void ?{}(thread_desc & this, struct cluster & cl )                                            { this{ "Anonymous Thread", cl, 0p, 65000 }; }
67static inline void ?{}(thread_desc & this, struct cluster & cl, size_t stackSize )                          { this{ "Anonymous Thread", cl, 0p, stackSize }; }
68static inline void ?{}(thread_desc & this, struct cluster & cl, void * storage, size_t storageSize )        { this{ "Anonymous Thread", cl, storage, storageSize }; }
69static inline void ?{}(thread_desc & this, const char * const name)                                         { this{ name, *mainCluster, 0p, 65000 }; }
70static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl )                   { this{ name, cl, 0p, 65000 }; }
71static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl, size_t stackSize ) { this{ name, cl, 0p, stackSize }; }
72
73//-----------------------------------------------------------------------------
74// thread runner
75// Structure that actually start and stop threads
76forall( dtype T | sized(T) | is_thread(T) )
77struct scoped {
78        T handle;
79};
80
81forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } )
82void ?{}( scoped(T)& this );
83
84forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T&, P); } )
85void ?{}( scoped(T)& this, P params );
86
87forall( dtype T | sized(T) | is_thread(T) )
88void ^?{}( scoped(T)& this );
89
90//-----------------------------------------------------------------------------
91// Thread getters
92static inline struct thread_desc * active_thread () { return TL_GET( this_thread ); }
93
94//-----------------------------------------------------------------------------
95// Scheduler API
96
97//----------
98// Park thread: block until corresponding call to unpark, won't block if unpark is already called
99void park( void );
100
101//----------
102// Unpark a thread, if the thread is already blocked, schedule it
103//                  if the thread is not yet block, signal that it should rerun immediately or reschedule itself
104void unpark( thread_desc * this, bool must_yield );
105
106static inline void unpark( thread_desc * this ) { unpark( this, false ); }
107
108forall( dtype T | is_thread(T) )
109static inline void unpark( T & this ) { if(!&this) return; unpark( get_thread( this ), false );}
110
111forall( dtype T | is_thread(T) )
112static inline void unpark( T & this, bool must_yield ) { if(!&this) return; unpark( get_thread( this ), must_yield );}
113
114//----------
115// Yield: force thread to block and be rescheduled
116static inline void yield() {
117        unpark( active_thread(), true );
118        park();
119}
120
121// Yield: yield N times
122static inline void yield( unsigned times ) {
123        for( times ) {
124                yield();
125        }
126}
127
128// Local Variables: //
129// mode: c //
130// tab-width: 4 //
131// End: //
Note: See TracBrowser for help on using the repository browser.