mirror of
				https://gitlab.com/sortix/sortix.git
				synced 2023-02-13 20:55:38 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			137 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*******************************************************************************
 | 
						|
 | 
						|
    Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
 | 
						|
 | 
						|
    This file is part of Sortix.
 | 
						|
 | 
						|
    Sortix is free software: you can redistribute it and/or modify it under the
 | 
						|
    terms of the GNU General Public License as published by the Free Software
 | 
						|
    Foundation, either version 3 of the License, or (at your option) any later
 | 
						|
    version.
 | 
						|
 | 
						|
    Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
						|
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
						|
    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
						|
    details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU General Public License along with
 | 
						|
    Sortix. If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
    signal.cpp
 | 
						|
    Classes and functions making it easier to handle Unix signals.
 | 
						|
 | 
						|
*******************************************************************************/
 | 
						|
 | 
						|
#include <assert.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include <sortix/signal.h>
 | 
						|
 | 
						|
#include <sortix/kernel/interrupt.h>
 | 
						|
#include <sortix/kernel/kernel.h>
 | 
						|
#include <sortix/kernel/panic.h>
 | 
						|
#include <sortix/kernel/signal.h>
 | 
						|
#include <sortix/kernel/thread.h>
 | 
						|
 | 
						|
namespace Sortix {
 | 
						|
 | 
						|
// A per-cpu value whether a signal is pending in the running task.
 | 
						|
extern "C" { volatile unsigned long asm_signal_is_pending = 0; }
 | 
						|
 | 
						|
namespace Signal {
 | 
						|
 | 
						|
const int PRIORITIES[SIG__NUM_DECLARED] =
 | 
						|
{
 | 
						|
	SIG_PRIO_NORMAL, // unused
 | 
						|
	SIG_PRIO_NORMAL, // SIGHUP
 | 
						|
	SIG_PRIO_NORMAL, // SIGINT
 | 
						|
	SIG_PRIO_NORMAL, // SIGQUIT
 | 
						|
	SIG_PRIO_CORE, // SIGILL
 | 
						|
	SIG_PRIO_CORE, // SIGTRAP
 | 
						|
	SIG_PRIO_CORE, // SIGABRT
 | 
						|
	SIG_PRIO_CORE, // SIGEMT
 | 
						|
	SIG_PRIO_CORE, // SIGFPE
 | 
						|
	SIG_PRIO_KILL, // SIGKILL
 | 
						|
	SIG_PRIO_CORE, // SIGBUS
 | 
						|
	SIG_PRIO_CORE, // SIGSEGV
 | 
						|
	SIG_PRIO_CORE, // SIGSYS
 | 
						|
	SIG_PRIO_NORMAL, // SIGPIPE
 | 
						|
	SIG_PRIO_NORMAL, // SIGALRM
 | 
						|
	SIG_PRIO_NORMAL, // SIGTERM
 | 
						|
	SIG_PRIO_NORMAL, // SIGUSR1
 | 
						|
	SIG_PRIO_NORMAL, // SIGUSR2
 | 
						|
	SIG_PRIO_NORMAL, // SIGCHLD
 | 
						|
	SIG_PRIO_HIGH, // SIGPWR
 | 
						|
	SIG_PRIO_NORMAL, // SIGWINCH
 | 
						|
	SIG_PRIO_NORMAL, // SIGURG
 | 
						|
	SIG_PRIO_NORMAL, // obsolete
 | 
						|
	SIG_PRIO_STOP, // SIGSTOP
 | 
						|
	SIG_PRIO_STOP, // SIGTSTP
 | 
						|
	SIG_PRIO_STOP, // SIGCONT
 | 
						|
	SIG_PRIO_STOP, // SIGTTIN
 | 
						|
	SIG_PRIO_STOP, // SIGTTOU
 | 
						|
	SIG_PRIO_NORMAL, // SIGVTALRM
 | 
						|
	SIG_PRIO_NORMAL, // obsolete
 | 
						|
	SIG_PRIO_CORE, // SIGXCPU
 | 
						|
	SIG_PRIO_CORE, // SIGXFSZ
 | 
						|
	SIG_PRIO_NORMAL, // SIGCORE
 | 
						|
	SIG_PRIO_NORMAL, // SIGLWP
 | 
						|
	SIG_PRIO_NORMAL, // SIGAIO
 | 
						|
};
 | 
						|
 | 
						|
int Priority(int signum)
 | 
						|
{
 | 
						|
	assert(0 <= signum && signum < SIG_MAX_NUM);
 | 
						|
	if ( !signum )
 | 
						|
		return -1;
 | 
						|
	if ( SIG__NUM_DECLARED <= signum )
 | 
						|
		return SIG_PRIO_NORMAL;
 | 
						|
	return PRIORITIES[signum];
 | 
						|
}
 | 
						|
 | 
						|
Queue::Queue()
 | 
						|
{
 | 
						|
	for ( int i = 1; i < SIG_MAX_NUM; i++ )
 | 
						|
		pending[i] = false;
 | 
						|
}
 | 
						|
 | 
						|
void Queue::Push(int signum)
 | 
						|
{
 | 
						|
	assert(0 < signum && signum < SIG_MAX_NUM);
 | 
						|
	pending[signum] = true;
 | 
						|
}
 | 
						|
 | 
						|
int Queue::Pop(int cursig)
 | 
						|
{
 | 
						|
	int best = 0;
 | 
						|
	int bestprio = Priority(cursig);
 | 
						|
	for ( int i = 1; i < SIG_MAX_NUM; i++ )
 | 
						|
		if ( pending[i] && bestprio < Priority(i) )
 | 
						|
		{
 | 
						|
			best = i;
 | 
						|
			bestprio = Priority(i);
 | 
						|
		}
 | 
						|
	pending[best] = false;
 | 
						|
	return best;
 | 
						|
}
 | 
						|
 | 
						|
void Dispatch(CPU::InterruptRegisters* regs, void* /*user*/)
 | 
						|
{
 | 
						|
	return CurrentThread()->HandleSignal(regs);
 | 
						|
}
 | 
						|
 | 
						|
void Return(CPU::InterruptRegisters* regs, void* /*user*/)
 | 
						|
{
 | 
						|
	return CurrentThread()->HandleSigreturn(regs);
 | 
						|
}
 | 
						|
 | 
						|
void Init()
 | 
						|
{
 | 
						|
	Interrupt::RegisterRawHandler(130, isr130, true);
 | 
						|
	Interrupt::RegisterHandler(130, Dispatch, NULL);
 | 
						|
	Interrupt::RegisterRawHandler(131, isr131, true);
 | 
						|
	Interrupt::RegisterHandler(131, Return, NULL);
 | 
						|
}
 | 
						|
 | 
						|
} // namespace Signal
 | 
						|
} // namespace Sortix
 |