Changeset 23 for trunk/kernel/syscalls/sys_thread_exit.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_thread_exit.c
r16 r23 1 1 /* 2 * kern/sys_thread_exit.c - terminates the execution of current thread2 * sys_thread_exit.c - terminates the execution of current thread 3 3 * 4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017) 6 6 * 7 * This file is part of ALMOS-kernel.7 * Copyright (c) UPMC Sorbonne Universites 8 8 * 9 * ALMOS-kernel is free software; you can redistribute it and/or modify it 9 * This file is part of ALMOS-MKH. 10 * 11 * ALMOS-MKH is free software; you can redistribute it and/or modify it 10 12 * under the terms of the GNU General Public License as published by 11 13 * the Free Software Foundation; version 2.0 of the License. 12 14 * 13 * ALMOS- kernelis distributed in the hope that it will be useful, but15 * ALMOS-MKH is distributed in the hope that it will be useful, but 14 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 17 19 * 18 20 * You should have received a copy of the GNU General Public License 19 * along with ALMOS- kernel; if not, write to the Free Software Foundation,21 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 20 22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 23 */ 22 24 23 #include <list.h> 25 #include <hal_types.h> 26 #include <hal_irqmask.h> 24 27 #include <thread.h> 28 #include <core.h> 25 29 #include <scheduler.h> 26 #include <wait_queue.h> 27 #include <cluster.h> 28 #include <dqdt.h> 29 #include <process.h> 30 #include <printk.h> 30 31 31 /////////////////////////////////////// 32 int sys_thread_exit ( void * exit_val ) 32 33 //////////////////////////////////////// 34 int sys_thread_exit( void * exit_value ) 33 35 { 34 36 thread_t * this = CURRENT_THREAD; 35 37 core_t * core = this->core; 36 bool_t isEmpty;37 bool_t isReleased;38 38 uint32_t irq_state; 39 39 40 // update DQDT TODO must be done by thread destroy 41 if(this->process->pid != 1) dqdt_local_update_threads( -1 );40 // register the exit_value in thread descriptor 41 this->exit_value = exit_value; 42 42 43 spinlock_lock( &this->lock ); 43 // we enter the join loop to wait the join 44 // only if thread is joinable 45 if( (this->flags & THREAD_FLAG_DETACHED) == 0 ) 46 { 47 while( 1 ) 48 { 49 // take the lock protecting the flags 50 remote_spinlock_lock( XPTR( local_cxy, &this->flags_lock ) ); 44 51 45 if(!(thread_isJoinable(this))) 46 { 47 goto exit_dead; 52 // check the JOIN flag 53 if( this->flags & THREAD_FLAG_JOIN ) // parent made a join 54 { 55 // unblock the parent thread 56 thread_unblock( this->parent , THREAD_BLOCKED_JOIN ); 57 58 // release the lock protecting the flags 59 remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) ); 60 61 // exit while 62 break; 63 } 64 else // no join done by parent thread 65 { 66 // set the EXIT flag 67 this->flags |= THREAD_FLAG_EXIT; 68 69 // block this thread 70 thread_block( this , THREAD_BLOCKED_EXIT ); 71 72 // release the lock protecting the flags 73 remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) ); 74 75 // deschedule 76 sched_yield(); 77 } 78 } 48 79 } 49 50 // Check if there's a thread waiting the end of calling thread51 isEmpty = wait_queue_isEmpty(&this->info.wait_queue);52 53 if(isEmpty)54 {55 this->info.exit_value = exit_val;56 wait_on(&this->info.wait_queue, WAIT_ANY);57 spinlock_unlock_nosched(&this->lock);58 sched_sleep(this);59 }60 else61 {62 this->info.join->info.exit_value = exit_val;63 wakeup_one(&this->info.wait_queue, WAIT_ANY);64 spinlock_unlock_nosched(&this->lock);65 }66 67 exit_dead:68 69 isReleased = false;70 80 71 81 // Release FPU if required 72 82 hal_disable_irq( &irq_state ); 73 if(core->fpu_owner == this) 74 { 75 core->fpu_owner = NULL; 76 isReleased = true; 77 } 83 if( core->fpu_owner == this ) core->fpu_owner = NULL; 78 84 hal_restore_irq( irq_state ); 79 85 80 if(isReleased) 81 { 82 thread_dmsg(1, "INFO: Thread %x has released FPU on CPU %d\n", 83 this, 84 current_cpu->gid); 85 } 86 // suicide 87 thread_kill( this ); 88 return 0; 86 89 87 sched_exit(this); 88 89 PANIC ("Thread %x, CPU %d must never return", this, current_cpu->gid); 90 return -1; /* Fake return ! */ 91 } 90 } // end sys_thread_exit()
Note: See TracChangeset
for help on using the changeset viewer.