source: soft/giet_vm/giet_kernel/ctx_handler.c @ 709

Last change on this file since 709 was 709, checked in by alain, 9 years ago

Major release: Change the task model to implement the POSIX threads API.

  • The shell "exec" and "kill" commands can be used to activate/de-activate the applications.
  • The "pause", "resume", and "context" commands can be used to stop, restart, a single thtead or to display the thread context.

This version has been tested on the following multi-threaded applications,
that have been modified to use the POSIX threads:

  • classif
  • convol
  • transpose
  • gameoflife
  • raycast
  • Property svn:executable set to *
File size: 6.9 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
2// File     : ctx_handler.c
3// Date     : 01/04/2012
4// Authors  : alain greiner & joel porquet
5// Copyright (c) UPMC-LIP6
6//////////////////////////////////////////////////////////////////////////////////
7
8#include <ctx_handler.h>
9#include <sys_handler.h>
10#include <giet_config.h>
11#include <fat32.h>
12#include <hard_config.h>
13#include <utils.h>
14#include <tty0.h>
15#include <xcu_driver.h>
16#include <bdv_driver.h>
17
18/////////////////////////////////////////////////////////////////////////////////
19//     Extern variables and functions
20/////////////////////////////////////////////////////////////////////////////////
21
22// defined in giet_kernel/switch.s file
23extern void _thread_switch( thread_context_t* , thread_context_t* );
24
25// allocated in boot.c or kernel_init.c files
26extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
27
28// allocated in kernel_init.c file
29extern fat_desc_t  _fat;
30
31//////////////////////////////////////////////////////////////////
32// This function is called by the _ctx_switch() function.
33// It desactivates a thread that received a KILL signal.
34// We must release all ressources allocated to the thread
35// before the actual desactivation, that uses NORUN_MASK_THREAD.
36//////////////////////////////////////////////////////////////////
37static void _ctx_kill_thread( unsigned int x,
38                              unsigned int y,
39                              unsigned int p,
40                              unsigned int ltid )
41{
42    // get scheduler address
43    static_scheduler_t* psched = _schedulers[x][y][p];
44
45    // pretend the thread to kill is the currently scheduled thread
46    // (required by the _sys_***_release() calls)
47    unsigned int cur_thread = psched->current;
48    psched->current = ltid;
49
50    // release BDV lock if taken and reset BDV peripheral
51    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_BDV ) 
52    {
53        _bdv_set_register( BLOCK_DEVICE_STATUS , 0 );
54        _spin_lock_release( &_bdv_lock );
55    }
56
57    // release FAT lock if taken
58    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FAT ) 
59    {
60        _spin_lock_release( &_fat.fat_lock );
61    }
62
63    // release private TTY terminal if required
64    if ( psched->context[ltid].slot[CTX_TTY_ID] < NB_TTY_CHANNELS ) 
65        _sys_tty_release(); 
66
67    // release private TIM channel if required
68
69    if ( psched->context[ltid].slot[CTX_TIM_ID] < NB_TIM_CHANNELS )
70    {
71        _sys_tim_release();
72    }
73
74    // release private NIC_RX and CMA_RX channels if required
75    if ( psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS )
76    {
77        _sys_nic_release( 1 );
78    }
79
80    // release private NIC_TX and CMA_TX channels if required
81    if ( psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS )
82    {
83        _sys_nic_release( 0 );
84    }
85
86    // release private FBF_CMA channel if required
87    if ( psched->context[ltid].slot[CTX_CMA_FB_ID] < NB_CMA_CHANNELS )
88    {
89        _sys_fbf_cma_release();
90    }
91
92    // restore scheduled thread index
93    psched->current = cur_thread;
94
95    // set NORUN_MASK_THREAD bit to desactivate the target thread
96    psched->context[ltid].slot[CTX_NORUN_ID] = NORUN_MASK_THREAD;
97
98} // end _ctx_kill_thread()
99
100
101//////////////////
102void _ctx_switch() 
103{
104    unsigned int gpid       = _get_procid();
105    unsigned int cluster_xy = gpid >> P_WIDTH;
106    unsigned int x          = cluster_xy >> Y_WIDTH;
107    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
108    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
109
110    unsigned int ltid;     // index for loops on threads in scheduler
111
112    // get calling thread scheduler address
113    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
114
115    // get number of threads allocated to scheduler
116    unsigned int threads = psched->threads;
117
118    // get current thread ltid
119    unsigned int curr_thread_id = psched->current;
120
121    // first loop on threads: handle all pending KILL signals
122    for ( ltid = 0 ; ltid < threads ; ltid++ )
123    {
124        if ( psched->context[ltid].slot[CTX_SIGS_ID] & SIGS_MASK_KILL )
125        {
126            // acknowledge KILL signal
127            _atomic_and( &psched->context[ltid].slot[CTX_SIGS_ID], ~SIGS_MASK_KILL );
128
129            // desactivate the killed thread
130            _ctx_kill_thread( x , y , p , ltid );
131        }
132    }
133
134    // second loop: select next thread using a round-robin policy
135    unsigned int next_thread_id;
136    unsigned int found = 0;
137    for ( ltid = curr_thread_id + 1 ; ltid < (curr_thread_id + 1 + threads) ; ltid++ ) 
138    {
139        next_thread_id = ltid % threads;
140
141        // test if the thread is runable
142        if ( psched->context[next_thread_id].slot[CTX_NORUN_ID] == 0 )
143        {
144            found = 1;
145            break;
146        }
147    }
148
149    // launch idle_thread if no runable thread
150    if ( found == 0 ) next_thread_id = IDLE_THREAD_INDEX;
151
152    if ( curr_thread_id != next_thread_id )  // actual thread switch required
153    {
154
155#if GIET_DEBUG_SWITCH
156unsigned int x = cluster_xy >> Y_WIDTH;
157unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
158if ( (_get_proctime() > GIET_DEBUG_SWITCH) && (x == 0) && (y == 0) && (p == 0) )
159_printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
160        curr_thread_id, next_thread_id, x, y , p, _get_proctime() );
161#endif
162
163        thread_context_t* curr_ctx_vaddr = &(psched->context[curr_thread_id]);
164        thread_context_t* next_ctx_vaddr = &(psched->context[next_thread_id]);
165
166        // reset TICK timer counter.
167        _xcu_timer_reset_cpt( cluster_xy, p );
168
169        // set current thread index
170        psched->current = next_thread_id;
171
172        // makes context switch
173        _thread_switch( curr_ctx_vaddr , next_ctx_vaddr );
174    }
175} //end _ctx_switch()
176
177
178///////////////////
179void _idle_thread() 
180{
181    unsigned int gpid       = _get_procid();
182    unsigned int cluster_xy = gpid >> P_WIDTH;
183    unsigned int x          = cluster_xy >> Y_WIDTH;
184    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
185    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
186
187    while(1)
188    {
189        // initialize counter
190        unsigned int count = GIET_IDLE_THREAD_PERIOD;
191
192        // decounting loop
193        asm volatile(
194                "move   $3,   %0              \n"
195                "_idle_thread_loop:             \n"
196                "addi   $3,   $3,   -1        \n"
197                "bnez   $3,   _idle_thread_loop \n"
198                "nop                          \n"
199                :
200                : "r"(count)
201                : "$3" ); 
202
203        // warning message
204        _printf("\n[GIET WARNING] Processor[%d,%d,%d] still idle at cycle %d",
205                x , y , p , _get_proctime() );
206    }
207} // end ctx_idle()
208
209
210////////////////
211void _ctx_eret() 
212{
213    asm volatile("eret");
214}
215
216
217// Local Variables:
218// tab-width: 4
219// c-basic-offset: 4
220// c-file-offsets:((innamespace . 0)(inline-open . 0))
221// indent-tabs-mode: nil
222// End:
223// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
224
Note: See TracBrowser for help on using the repository browser.