Ignore:
Timestamp:
Jun 18, 2017, 10:06:41 PM (5 years ago)
Author:
alain
Message:

Introduce syscalls.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/sys_thread_exit.c

    r16 r23  
    11/*
    2  * kern/sys_thread_exit.c - terminates the execution of current thread
     2 * sys_thread_exit.c - terminates the execution of current thread
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *               Alain Greiner (2016,2017)
    66 *
    7  * This file is part of ALMOS-kernel.
     7 * Copyright (c) UPMC Sorbonne Universites
    88 *
    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
    1012 * under the terms of the GNU General Public License as published by
    1113 * the Free Software Foundation; version 2.0 of the License.
    1214 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1416 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1517 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1719 *
    1820 * 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,
    2022 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2123 */
    2224
    23 #include <list.h>
     25#include <hal_types.h>
     26#include <hal_irqmask.h>
    2427#include <thread.h>
     28#include <core.h>
    2529#include <scheduler.h>
    26 #include <wait_queue.h>
    27 #include <cluster.h>
    28 #include <dqdt.h>
    29 #include <process.h>
     30#include <printk.h>
    3031
    31 ///////////////////////////////////////
    32 int sys_thread_exit ( void * exit_val )
     32
     33////////////////////////////////////////
     34int sys_thread_exit( void * exit_value )
    3335{
    3436        thread_t  * this = CURRENT_THREAD;
    3537    core_t    * core = this->core;
    36         bool_t      isEmpty;
    37         bool_t      isReleased;
    3838    uint32_t    irq_state;
    3939
    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;
    4242
    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 ) );
    4451
    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        }
    4879        }
    49 
    50         // Check if there's a thread waiting the end of calling thread
    51         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         else
    61         {
    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;
    7080
    7181        // Release FPU if required
    7282        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;
    7884        hal_restore_irq( irq_state );
    7985
    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;       
    8689
    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.