Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Miosix Kernel
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Avionics
Software Development
Miosix Kernel
Commits
ad9215da
Commit
ad9215da
authored
13 years ago
by
Terraneo Federico
Browse files
Options
Downloads
Patches
Plain Diff
Started implementing waitpid
parent
ff09208c
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
main.cpp
+25
-6
25 additions, 6 deletions
main.cpp
miosix/kernel/process.cpp
+108
-8
108 additions, 8 deletions
miosix/kernel/process.cpp
miosix/kernel/process.h
+26
-23
26 additions, 23 deletions
miosix/kernel/process.h
with
159 additions
and
37 deletions
main.cpp
+
25
−
6
View file @
ad9215da
#include
<cstdio>
#include
<sys/wait.h>
#include
<signal.h>
#include
"miosix.h"
#include
"kernel/process.h"
#include
"app_template/prog3.h"
...
...
@@ -7,12 +9,8 @@
using
namespace
std
;
using
namespace
miosix
;
int
main
(
)
void
ledThread
(
void
*
)
{
getchar
();
ElfProgram
prog
(
reinterpret_cast
<
const
unsigned
int
*>
(
main_elf
),
main_elf_len
);
Process
::
create
(
prog
);
for
(;;)
{
ledOn
();
...
...
@@ -21,3 +19,24 @@ int main()
Thread
::
sleep
(
200
);
}
}
int
main
()
{
Thread
::
create
(
ledThread
,
STACK_MIN
);
ElfProgram
prog
(
reinterpret_cast
<
const
unsigned
int
*>
(
main_elf
),
main_elf_len
);
for
(;;)
{
getchar
();
Process
::
create
(
prog
);
int
ec
;
pid_t
pid
=
Process
::
wait
(
&
ec
);
iprintf
(
"Process %d terminated
\n
"
,
pid
);
if
(
WIFEXITED
(
ec
))
{
iprintf
(
"Exit code is %d
\n
"
,
WEXITSTATUS
(
ec
));
}
else
if
(
WIFSIGNALED
(
ec
))
{
if
(
WTERMSIG
(
ec
)
==
SIGSEGV
)
iprintf
(
"Process segfaulted
\n
"
);
}
}
}
This diff is collapsed.
Click to expand it.
miosix/kernel/process.cpp
+
108
−
8
View file @
ad9215da
...
...
@@ -29,6 +29,8 @@
#include
<memory>
#include
<cstdio>
#include
<cstring>
#include
<sys/wait.h>
#include
<signal.h>
#include
"sync.h"
#include
"process_pool.h"
#include
"process.h"
...
...
@@ -70,7 +72,7 @@ namespace miosix {
// class Process
//
Process
*
Process
::
create
(
const
ElfProgram
&
program
)
pid_t
Process
::
create
(
const
ElfProgram
&
program
)
{
auto_ptr
<
Process
>
proc
(
new
Process
(
program
));
{
...
...
@@ -95,10 +97,87 @@ Process *Process::create(const ElfProgram& program)
//among the threads of a process
proc
->
threads
.
push_back
(
thr
);
thr
->
wakeup
();
//Actually start the thread, now that everything is set up
return
proc
.
release
();
//Do not delete the pointer
pid_t
result
=
proc
->
pid
;
proc
.
release
();
//Do not delete the pointer
return
result
;
}
Process
::
Process
(
const
ElfProgram
&
program
)
:
program
(
program
)
pid_t
Process
::
getppid
(
pid_t
proc
)
{
Lock
<
Mutex
>
l
(
procMutex
);
map
<
pid_t
,
Process
*>::
iterator
it
=
processes
.
find
(
proc
);
if
(
it
==
processes
.
end
())
return
-
1
;
return
it
->
second
->
ppid
;
}
pid_t
Process
::
waitpid
(
pid_t
pid
,
int
*
exit
,
int
options
)
{
Lock
<
Mutex
>
l
(
procMutex
);
pid_t
result
=-
1
;
if
(
pid
<=
0
)
{
//Wait for a generic child process
Process
*
self
=
Thread
::
getCurrentThread
()
->
proc
;
pid_t
ppid
=
self
==
0
?
0
:
self
->
pid
;
multimap
<
pid_t
,
Process
*>::
iterator
it
=
zombies
.
find
(
ppid
);
if
((
options
&
WNOHANG
)
&&
it
==
zombies
.
end
())
return
0
;
while
(
it
==
zombies
.
end
())
{
genericWaiting
.
wait
(
l
);
it
=
zombies
.
find
(
ppid
);
}
Process
*
joined
=
it
->
second
;
if
(
joined
->
waitCount
!=
0
)
errorHandler
(
UNEXPECTED
);
result
=
joined
->
pid
;
if
(
exit
!=
0
)
*
exit
=
joined
->
exitCode
;
zombies
.
erase
(
it
);
processes
.
erase
(
result
);
delete
joined
;
}
else
{
//Wait on a specific process
map
<
pid_t
,
Process
*>::
iterator
it
=
processes
.
find
(
pid
);
if
(
it
!=
processes
.
end
())
{
Process
*
joined
=
it
->
second
;
if
(
joined
->
exitCode
==-
1
)
{
//Process hasn't terminated yet
if
(
options
&
WNOHANG
)
return
0
;
joined
->
waitCount
++
;
joined
->
waiting
.
wait
(
l
);
joined
->
waitCount
--
;
if
(
joined
->
waitCount
<
0
||
joined
->
exitCode
==-
1
)
errorHandler
(
UNEXPECTED
);
}
result
=
joined
->
pid
;
if
(
exit
!=
0
)
*
exit
=
joined
->
exitCode
;
if
(
joined
->
waitCount
==
0
)
{
typedef
typename
multimap
<
pid_t
,
Process
*>::
iterator
iterator
;
pair
<
iterator
,
iterator
>
p
=
zombies
.
equal_range
(
joined
->
ppid
);
for
(
iterator
it
=
p
.
first
;
it
!=
p
.
second
;
++
it
)
{
if
(
it
->
second
!=
joined
)
continue
;
zombies
.
erase
(
it
);
break
;
}
processes
.
erase
(
result
);
delete
joined
;
}
}
}
return
result
;
}
Process
::~
Process
()
{
#ifdef __CODE_IN_XRAM
ProcessPool
::
instance
().
deallocate
(
loadedProgram
);
#endif //__CODE_IN_XRAM
}
Process
::
Process
(
const
ElfProgram
&
program
)
:
program
(
program
),
waitCount
(
0
),
exitCode
(
-
1
)
{
//This is required so that bad_alloc can never be thrown when the first
//thread of the process will be stored in this vector
...
...
@@ -112,8 +191,18 @@ Process::Process(const ElfProgram& program) : program(program)
if
(
elfSize
<
ProcessPool
::
blockSize
)
roundedSize
=
ProcessPool
::
blockSize
;
else
if
(
elfSize
&
(
elfSize
-
1
))
roundedSize
=
1
<<
ffs
(
elfSize
);
#ifndef __CODE_IN_XRAM
mpu
=
miosix_private
::
MPUConfiguration
(
program
.
getElfBase
(),
roundedSize
,
//FIXME -- begin
//Till a flash file system that ensures proper alignment of the programs
//loaded in flash is implemented, make the whole flash visible as a big MPU
//region
extern
unsigned
char
_end
asm
(
"_end"
);
unsigned
int
flashEnd
=
reinterpret_cast
<
unsigned
int
>
(
&
_end
);
if
(
flashEnd
&
(
flashEnd
-
1
))
flashEnd
=
1
<<
ffs
(
flashEnd
);
mpu
=
miosix_private
::
MPUConfiguration
(
0
,
flashEnd
,
image
.
getProcessBasePointer
(),
image
.
getProcessImageSize
());
// mpu=miosix_private::MPUConfiguration(program.getElfBase(),roundedSize,
// image.getProcessBasePointer(),image.getProcessImageSize());
//FIXME -- end
#else //__CODE_IN_XRAM
loadedProgram
=
ProcessPool
::
instance
().
allocate
(
roundedSize
);
memcpy
(
loadedProgram
,
reinterpret_cast
<
char
*>
(
program
.
getElfBase
()),
elfSize
);
...
...
@@ -133,12 +222,14 @@ void *Process::start(void *argv)
#endif //__CODE_IN_XRAM
Thread
::
setupUserspaceContext
(
entry
,
proc
->
image
.
getProcessBasePointer
(),
proc
->
image
.
getProcessImageSize
());
int
returnValue
=
0
;
bool
running
=
true
;
do
{
miosix_private
::
SyscallParameters
sp
=
Thread
::
switchToUserspace
();
if
(
proc
->
fault
.
faultHappened
())
{
running
=
false
;
returnValue
=
SIGSEGV
;
//Segfault
#ifdef WITH_ERRLOG
iprintf
(
"Process %d terminated due to a fault
\n
"
"* Code base address was 0x%x
\n
"
...
...
@@ -157,9 +248,7 @@ void *Process::start(void *argv)
{
case
2
:
running
=
false
;
#ifdef WITH_ERRLOG
iprintf
(
"Exit %d
\n
"
,
sp
.
getFirstParameter
());
//FIXME: remove
#endif //WITH_ERRLOG
returnValue
=
(
sp
.
getFirstParameter
()
&
0xff
)
<<
8
;
break
;
case
3
:
//FIXME: check that the pointer belongs to the process
...
...
@@ -178,6 +267,7 @@ void *Process::start(void *argv)
break
;
default:
running
=
false
;
returnValue
=
SIGSYS
;
//Bad syscall
#ifdef WITH_ERRLOG
iprintf
(
"Unexpected syscall number %d
\n
"
,
sp
.
getSyscallId
());
#endif //WITH_ERRLOG
...
...
@@ -186,7 +276,15 @@ void *Process::start(void *argv)
}
if
(
Thread
::
testTerminate
())
running
=
false
;
}
while
(
running
);
//TODO: handle process termination
{
Lock
<
Mutex
>
l
(
procMutex
);
proc
->
exitCode
=
returnValue
;
if
(
proc
->
waitCount
>
0
)
proc
->
waiting
.
broadcast
();
else
{
zombies
.
insert
(
make_pair
(
proc
->
ppid
,
proc
));
genericWaiting
.
broadcast
();
}
}
return
0
;
}
...
...
@@ -203,8 +301,10 @@ pid_t Process::getNewPid()
}
map
<
pid_t
,
Process
*>
Process
::
processes
;
multimap
<
pid_t
,
Process
*>
Process
::
zombies
;
pid_t
Process
::
pidCounter
=
1
;
Mutex
Process
::
procMutex
;
ConditionVariable
Process
::
genericWaiting
;
}
//namespace miosix
...
...
This diff is collapsed.
Click to expand it.
miosix/kernel/process.h
+
26
−
23
View file @
ad9215da
...
...
@@ -32,6 +32,7 @@
#include
<map>
#include
<sys/types.h>
#include
"kernel.h"
#include
"sync.h"
#include
"elf_program.h"
#include
"config/miosix_settings.h"
...
...
@@ -48,22 +49,19 @@ public:
/**
* Create a new process
* \param program Program that the process will execute
* \return
a pointer to
the newly created process
* \return
the pid of
the newly created process
* \throws std::exception or a subclass in case of errors, including
* not emough memory to spawn the process
*/
static
Process
*
create
(
const
ElfProgram
&
program
);
/**
* \return the pid of the created process
*/
pid_t
getpid
()
const
{
return
pid
;
}
static
pid_t
create
(
const
ElfProgram
&
program
);
/**
* Given a process, returns the pid of its parent.
* \param proc the pid of a process
* \return the pid of the parent process, or zero if the process was created
* by the kernel directly
* by the kernel directly
, or -1 if proc is not a valid process
*/
pid_t
getppid
(
)
const
{
return
ppid
;
}
static
pid_t
getppid
(
pid_t
proc
);
/**
* Wait for child process termination
...
...
@@ -71,7 +69,7 @@ public:
* is not null
* \return the pid of the terminated process, or -1 in case of errors
*/
pid_t
wait
(
int
*
exit
)
;
static
pid_t
wait
(
int
*
exit
)
{
return
waitpid
(
-
1
,
exit
,
0
);
}
/**
* Wait for a specific child process to terminate
...
...
@@ -83,7 +81,12 @@ public:
* case WNOHANG is specified and the specified process has not terminated,
* 0 is returned
*/
pid_t
waitpid
(
pid_t
pid
,
int
*
exit
,
int
options
);
static
pid_t
waitpid
(
pid_t
pid
,
int
*
exit
,
int
options
);
/**
* Destructor
*/
~
Process
();
private
:
Process
(
const
Process
&
);
...
...
@@ -116,29 +119,29 @@ private:
#endif //__CODE_IN_XRAM
ProcessImage
image
;
///<The RAM image of a process
miosix_private
::
FaultData
fault
;
///< Contains information about faults
std
::
vector
<
Thread
*>
threads
;
///<Threads that belong to the process
miosix_private
::
MPUConfiguration
mpu
;
///<Memory protection data
std
::
vector
<
Thread
*>
threads
;
///<Threads that belong to the process
pid_t
pid
;
///<The pid of this process
pid_t
ppid
;
///<The parent pid of this process
///This union is used to join threads. When the thread to join has not yet
///terminated and no other thread called join it contains (Thread *)NULL,
///when a thread calls join on this thread it contains the thread waiting
///for the join, and when the thread terminated it contains (void *)result
union
{
Thread
*
waitingForJoin
;
///<Thread waiting to join this
int
exitCode
;
///<Process exit code
}
joinData
;
///Maps the pid to the Process instance
///Contains the count of active wait calls which specifically requested
///to wait on this process
int
waitCount
;
///Active wait calls which specifically requested to wait on this process
///wait on this condition variable
ConditionVariable
waiting
;
int
exitCode
;
///< Contains -1 if process is running, or the exit code
///Maps the pid to the Process instance. Includes zombie processes
static
std
::
map
<
pid_t
,
Process
*>
processes
;
///Terminated but not joined processes, the key is the parent's pid
static
std
::
multimap
<
pid_t
,
Process
*>
zombies
;
///Used to assign a new pid to a process
static
pid_t
pidCounter
;
///Uset to guard access to processes and pidCounter
static
Mutex
procMutex
;
///Used to wait on process termination
static
ConditionVariable
w
aiting
;
static
ConditionVariable
genericW
aiting
;
//Needs access to fault,mpu
friend
class
Thread
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment