source: trunk/kernel/syscalls/sys_kill.c @ 657

Last change on this file since 657 was 624, checked in by alain, 6 years ago

Fix several bugs to use the instruction MMU in kernel mode
in replacement of the instruction address extension register,
and remove the "kentry" segment.

This version is running on the tsar_generic_iob" platform.

One interesting bug: the cp0_ebase defining the kernel entry point
(for interrupts, exceptions and syscalls) must be initialized
early in kernel_init(), because the VFS initialisation done by
kernel_ini() uses RPCs, and RPCs uses Inter-Processor-Interrup.

File size: 7.7 KB
RevLine 
[23]1/*
[416]2 * sys_kill.c - Kernel function implementing the "kill" system call.
[23]3 *
[440]4 * Author    Alain Greiner (2016,2017,2018)
[23]5 *
6 * Copyright (c)  UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <kernel_config.h>
[457]25#include <hal_kernel_types.h>
[409]26#include <hal_irqmask.h>
[23]27#include <errno.h>
28#include <thread.h>
29#include <printk.h>
30#include <process.h>
[416]31#include <shared_syscalls.h>
[23]32#include <cluster.h>
33#include <rpc.h>
34
[506]35#include <syscalls.h>
36
[584]37
38#if DEBUG_SYS_KILL
39////////////////////////////////////////////
40static char* sig_type_str( uint32_t sig_id )
41{
42    switch( sig_id )
43    {
44        case SIGKILL: return "SIGKILL";
45        case SIGSTOP: return "SIGSTOP";
46        case SIGCONT: return "SIGCONT";
47        default:      return "undefined";
48    }
49}
50#endif
51
52
[23]53///////////////////////////
54int sys_kill( pid_t    pid,
55              uint32_t sig_id )
56{
[446]57    xptr_t      owner_xp;          // extended pointer on process in owner cluster
58    cxy_t       owner_cxy;         // process owner cluster
59    process_t * owner_ptr;         // local pointer on process in owner cluster
60    xptr_t      parent_xp;         // extended pointer on parent process
61    cxy_t       parent_cxy;        // parent process cluster
62    process_t * parent_ptr;        // local pointer on parent process
63    thread_t  * parent_main_ptr;   // local pointer on parent main thread
64    xptr_t      parent_main_xp;    // extended pointer on parent main thread
[409]65
[416]66    thread_t  * this    = CURRENT_THREAD;
[435]67    process_t * process = this->process;
[416]68
[584]69#if (DEBUG_SYS_KILL || CONFIG_INSTRUMENTATION_SYSCALLS)
70uint64_t     tm_start = hal_get_cycles();
71#endif
72
[438]73#if DEBUG_SYS_KILL
[409]74tm_start = hal_get_cycles();
[438]75if( DEBUG_SYS_KILL < tm_start )
[624]76printk("\n[%s] thread[%x,%x] enter : %s to process %x / cycle %d\n",
77__FUNCTION__, this->process->pid, this->trdid,
78sig_type_str(sig_id), pid, (uint32_t)tm_start );
[409]79#endif
80
[436]81    // get pointers on process descriptor in owner cluster
82    owner_xp  = cluster_get_owner_process_from_pid( pid );
83    owner_cxy = GET_CXY( owner_xp );
84    owner_ptr = GET_PTR( owner_xp );
85   
[446]86#if (DEBUG_SYS_KILL & 1)
87if( DEBUG_SYS_KILL < tm_start )
[624]88printk("\n[%s] thread[%x,%x] get target process descriptor %x in owner cluster %x\n",
[584]89__FUNCTION__ , this->process->pid, this->trdid, owner_ptr, owner_cxy );
[446]90#endif
91
[436]92    // check process found
93    if( owner_xp == XPTR_NULL)
[435]94    {
95
[438]96#if DEBUG_SYSCALLS_ERROR
[436]97printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__, pid );
[435]98#endif
99        this->errno = EINVAL;
100        return -1;
101    }
102
[446]103    // get parent process descriptor pointers
[566]104    parent_xp  = (xptr_t)hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
[446]105    parent_cxy = GET_CXY( parent_xp );
106    parent_ptr = GET_PTR( parent_xp );
107
108#if (DEBUG_SYS_KILL & 1)
109if( DEBUG_SYS_KILL < tm_start )
[624]110printk("\n[%s] thread[%x,%x] get parent process descriptor %x in cluster %x\n",
[584]111__FUNCTION__ , this->process->pid, this->trdid, parent_ptr, parent_cxy );
[446]112#endif
113
114    // get pointers on the parent process main thread
115    parent_main_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->th_tbl[0] ) ); 
116    parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
117
[435]118    // analyse signal type / supported values are : 0, SIGSTOP, SIGCONT, SIGKILL
[433]119    switch( sig_id )
[23]120    {
[436]121        case 0 :          // does nothing
[433]122        {
123            break;
124        }
[436]125        case SIGSTOP:     // block all target process threads
[433]126        {
[584]127            // block all threads in all clusters
[435]128            process_sigaction( pid , BLOCK_ALL_THREADS );
[433]129
[624]130#if (DEBUG_SYS_KILL & 1)
131if( DEBUG_SYS_KILL < tm_start )
132printk("\n[%s] thread[%x,%x] blocked all threads of process %x\n",
133__FUNCTION__ , this->process->pid, this->trdid, pid );
134#endif
[435]135            // atomically update owner process termination state
[433]136            hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
[435]137                                  PROCESS_TERM_STOP );
[446]138
[584]139            // unblock the parent process main thread
[446]140            thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
141
[594]142            // calling thread deschedules when it is itself a target thread
[624]143            if( this->process->pid == pid )
144            {
[594]145
[624]146#if (DEBUG_SYS_KILL & 1)
147if( DEBUG_SYS_KILL < tm_start )
148printk("\n[%s] thread[%x,%x] is a target thread => deschedule\n",
149__FUNCTION__ , this->process->pid, this->trdid );
150#endif
151                sched_yield("block itself");
152            }
153
[433]154            break;
155        }
[436]156        case SIGCONT:     // unblock all target process threads
[433]157        {
158            // unblock all threads in all clusters
[435]159            process_sigaction( pid , UNBLOCK_ALL_THREADS );
[433]160
[436]161            // atomically update owner process termination state
[433]162            hal_remote_atomic_and( XPTR( owner_cxy , &owner_ptr->term_state ) ,
[435]163                                   ~PROCESS_TERM_STOP );
[584]164
165            // unblock the parent process main thread
166            thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
167
[433]168            break;
169        }
170        case SIGKILL:
171        {
[584]172            // a process cannot kill itself
173            if( (pid == process->pid) ) 
174            {
175
176#if DEBUG_SYSCALLS_ERROR
177printk("\n[ERROR] in %s : process %x cannot kill itself\n", __FUNCTION__, pid );
178#endif
179                this->errno = EINVAL;
180                return -1;
181            }
182
183            // processe INIT cannot be killed
184            if( pid == 1 )
185            {
186
187#if DEBUG_SYSCALLS_ERROR
188printk("\n[ERROR] in %s : process_init cannot be killed\n", __FUNCTION__ );
189#endif
190                        this->errno = EINVAL;
191                return -1;
192            }
193
[436]194            // remove process from TXT list
195            process_txt_detach( owner_xp );
[433]196
[446]197            // mark for delete all threads in all clusters, but the main
[435]198            process_sigaction( pid , DELETE_ALL_THREADS );
199
[446]200            // block main thread
[436]201            xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
202            thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
203
204            // atomically update owner process descriptor term_state to ask
205            // the parent process sys_wait() function to delete this main thread
[435]206            hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
207                                  PROCESS_TERM_KILL );
[446]208
[566]209            // unblock the parent process main thread
[446]210            thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
211
[433]212            break;
213        }
214        default:
215        {
216
[438]217#if DEBUG_SYSCALLS_ERROR
[435]218printk("\n[ERROR] in %s : illegal signal %d / process %x\n", __FUNCTION__, sig_id, pid );
219#endif
[433]220            this->errno = EINVAL;
[584]221            return -1;
[433]222        }
[23]223    }
[433]224   
[124]225    hal_fence();
[23]226
[584]227#if (DEBUG_SYS_KILL || CONFIG_INSTRUMENTATION_SYSCALLS)
228uint64_t     tm_end = hal_get_cycles();
229#endif
230
[438]231#if DEBUG_SYS_KILL
232if( DEBUG_SYS_KILL < tm_end )
[594]233printk("\n[%s] thread[%x,%x] exit / process %x / %s / cost = %d / cycle %d\n",
[584]234__FUNCTION__ , this->process->pid, this->trdid, pid,
235sig_type_str(sig_id), (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
[409]236#endif
[23]237
[584]238#if CONFIG_INSTRUMENTATION_SYSCALLS
239hal_atomic_add( &syscalls_cumul_cost[SYS_KILL] , tm_end - tm_start );
240hal_atomic_add( &syscalls_occurences[SYS_KILL] , 1 );
241#endif
[433]242
[584]243        return 0;
244
[23]245}  // end sys_kill()
246
Note: See TracBrowser for help on using the repository browser.